//자체 소스에서 만든 딜레이를 쓰면
//에러가 발생되는 걸 보여주는 소스
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>
#define CPU_CLOCK 16000000
#define TICKS_PER_SEC 1000
#define BAUD_RATE 9600
#define BAUD_RATE_L (CPU_CLOCK / (16l * BAUD_RATE)) - 1
#define BAUD_RATE_H ((CPU_CLOCK / (16l * BAUD_RATE)) - 1) >> 8
/*
#define DDR_RF DDRC
#define PORT_RF PORTC
#define PIN_RF PINC
*/
volatile unsigned int tic_time;
unsigned int ad_temp_s=0;
int fnd1[10]={0xBF,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xD8,0x00,0xE7};
int fnd2[10]={0x10,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0xFF,0x18};
// timer0의 Compare Match 함수
SIGNAL(SIG_OUTPUT_COMPARE0)
{
tic_time++;
}
/*
//===============================================================//
//================== Timer setting =======================//
//===============================================================//
void time_init(void)
{
// CTC 모드 설정, clk/64
TCCR0 = (0 << WGM00) | (1 << WGM01) | (1 << CS02) | (0 << CS01) | (0 << CS00);
// 타이머/카운터0 Compare Match 인터럽트 활성화
TIMSK = (1 << OCIE0) | (0 << TOIE0);
// timer 시작값 초기화
TCNT0 = 0;
// TCNT0 레지스터와 비교하게 될 값을 OCR0에 써 준다.
OCR0 = CPU_CLOCK / TICKS_PER_SEC / 64 - 1;
}*/
// ms단위의 delay함수
void delay_ms(unsigned int msec)
{
tic_time = 0;
while (msec > tic_time);
}
//===============================================================//
//================== UART setting =======================//
//===============================================================//
void uart_init(void)
{
// baud rate 설정
UBRR1L = (unsigned char)BAUD_RATE_L;
UBRR1H = (unsigned char)BAUD_RATE_H;
// no parity, 1 stop bit, 8bit 설정
UCSR1C = (0 << UPM1) | (0 << UPM0) | (0 << USBS) | (1 << UCSZ1) | (1 << UCSZ0);
// rx/tx interrupt 설정, 8bit 설정
UCSR1B = (1 << TXEN) | (1 << RXEN) | (0 << UCSZ2);
}
// 1 byte 전송 함수
void uart_send_byte(unsigned char byte)
{
// 전송 버퍼가 빌 때 까지 기다린다.
while (!(UCSR1A & (1 << UDRE1)));
UDR1 = byte;
}
// 문자열 전송 함수
void uart_send_string(unsigned char *str, unsigned char len)
{
int i;
for (i = 0; i < len; i++)
{
if (!(*(str + i)))
{
break;
}
uart_send_byte(*(str + i));
}
}
void sensing(void)
{
// setting ADMUX
ADMUX = 0x41;
// setting ADCSR
ADCSRA = 0x86;
unsigned char buf[20] = {0,};
unsigned int ad_temp = 0;
ADCSRA = 0xD6; // ADC start
while((ADCSR & 0x10) != 0x10); // ADIF = 1 일 때까지 대기
ad_temp = ADC * 0.5 ;
ad_temp_s = ad_temp;
/*
uart_send_string("1 - ", 3);
itoa(ad_temp, buf, 10);
uart_send_string(buf, sizeof(buf));
uart_send_string("\r\n", 2);
*/
}
void port_init(void)
{
// DDR_RF = 0xFF;
DDRF = 0x00; // ADC0 입력 설정
}
void adc_init(void)
{
// setting ADMUX
ADMUX = 0x43;
// setting ADCSR
ADCSRA = 0x86;
}
int main(void)
{
uart_init(); // UART 초기화
port_init(); // PORT 초기화
adc_init(); // ADC 레지스터 설정
sei();
//DDRA = 0xFF;
// uart_send_string("Start\r\n", 7);
int f_num=0;
int s_num=0;
DDRA = 0xff;
DDRC = 0xff;
while(1)
{
sensing();
f_num = ad_temp_s / 10;
PORTC = 0x01;
PORTA = fnd1[f_num];
_delay_ms(500);
PORTC = 0x00;
_delay_ms(500);
/*
s_num = ad_temp_s % 10;
PORTC = 0x02;
PORTA = fnd1[s_num];
_delay_ms(20);
//_delay_ms(1000);
*/
}
return 1;
}
위 소스를 대충 잘 보면 자체 delay 함수가 있는대
그 함수를 끌어다 쓰면 컴파일 과정에서 그 과정을
컴파일러가 생략해버려서 시스템 구동에 문제가 생긴다
/util/delay.h 를 필히 끌어다 쓰도록 하자.
라고 원래 썻는데 모르고 함수로 직접만든 딜레이 부분이 지워졌네요 죄송합니다 -_-;
대충 아래와 같은 소스였는데 필요 없는 같은 동작 반복이라 생각하고 최적화 과정에서 생략 해버리더군요
그래서 winAVR 컴파일러에 포함된 delay.h를 써주면 아무 문제가 없더라구요
delay( int ms)
{
push();
pop();
}
'Embedded system > AVR' 카테고리의 다른 글
소프트웨어로 AVR 메모리 초기화 하기 (0) | 2011.02.11 |
---|---|
winavr 버전에 따른 문제점 20081205 vs 20090313 (0) | 2010.09.02 |
일광절약제(Daylight Saving) (0) | 2010.09.02 |
atmega128의 컴파일러 AVR-GCC의 모든 것 (0) | 2010.03.16 |
AVR studio optimization problem (0) | 2009.11.17 |