본문 바로가기

Embedded system/AVR

the problem of delay



//자체 소스에서 만든 딜레이를 쓰면
//에러가 발생되는 걸 보여주는 소스

#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();
}