2015-02-15

FND로 ‘1234’ 표시하기 과제 실습 및 궁금증 추가 질문

아래 내용은 http://cafe.naver.com/lazydigital/ 에서 질문한 내용을 정리한 내용입니다.


안녕하세요. 궁금증이 생겨 질문드립니다..

float t_tbl[4] = {6.0, 7.0, 8.0, 9.0, 10.0};
int k = 0;
while (1)
{
t = t_tbl[k];
for(i=1;i<5;i++){
FND_NUMBER = num[i]; // 1~4까지 주소값에 대응하는 값을 PORTC로 출력[1.2.3.4]
FND_PLACE = place[i-1]; // 0~3까지 FND 자릿수를 점등.
_delay_ms(t);
}
s += t; // s는 새로운 delay 가 얼마동안 누적되었는지를 가지고 있음.
if(s >= 1000.0) // 1초 이상이면
{
s = 0;
if(++k >= sizeof(t_tbl)/sizeof(t_tbl[0])) k = 0;
i
}

위에 있는 코드는 2-1. FND로 ‘1234’ 표시하기 과제 실습 및 궁금증 에서 답변 달아주신 코드를 avrstudio 6.1 에 넣어 컴파일을 하였습니다.

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

#define  FND_NUMBER PORTC        
#define  FND_PLACE  PORTG


int main(void)
{
    int i,k=0;         // 2byte (16bits) int형 변수 i초기값 0, a초기값 1
    double t ;
    unsigned long s;   // 양수형 4byte (32bits) 라이브러리 딜레이 함수의 return값의 형이 unsigned long 형.
           

    unsigned char num[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f,0x77,0xff,0x39,0xbf,0x79,0x71};
    unsigned char place[4] ={0x08,0x04,0x02, 0x01};
    //unsigned char HELP[4] = {0x76,0x79,0x38,0x73};
 
     float t_tbl[5] = {6.0, 7.0, 8.0, 9.0, 10.0}; //자료 갯수가 않맞아서 5로 변경하여 적어 넣었습니다.

 DDRC = 0xff;        // PORTC의 입출력 상태를 출력으로 모두 설정.
 DDRG = 0x0f;       // PORTG의 입출력 상태를 하위 4bits만을 출력 설정 상위 4bits는 입력설정.

 while (1)
 {
  t = t_tbl[k];
  for(i=1;i<5;i++){
   FND_NUMBER = num[i]; // 1~4까지 주소값에 대응하는 값을 PORTC로 출력[1.2.3.4]
   FND_PLACE = place[i-1]; // 0~3까지 FND 자릿수를 점등.
   _delay_ms(t);
  }
  s += t; // s는 새로운 delay 가 얼마동안 누적되었는지를 가지고 있음.
  if(s >= 1000.0) // 1초 이상이면
  {
   s = 0;
   if(++k >= sizeof(t_tbl)/sizeof(t_tbl[0])) k = 0;
 
      }
   }
}


---아래는 제가 사용한 /util/delay.h 파일로 일부 코드에 사용된 _delay_ms의 정의된 부분을 발췌하였습니다-----


void
_delay_ms(double __ms)
{
 uint16_t __ticks;
 double __tmp ;
#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
  !defined(__DELAY_BACKWARD_COMPATIBLE__) &&    \
  __STDC_HOSTED__
 uint32_t __ticks_dc;
 extern void __builtin_avr_delay_cycles(unsigned long);
 __tmp = ((F_CPU) / 1e3) * __ms;

 #if defined(__DELAY_ROUND_DOWN__)
  __ticks_dc = (uint32_t)fabs(__tmp);

 #elif defined(__DELAY_ROUND_CLOSEST__)
  __ticks_dc = (uint32_t)(fabs(__tmp)+0.5);

 #else
  //round up by default
  __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
 #endif

 __builtin_avr_delay_cycles(__ticks_dc);

#else
 __tmp = ((F_CPU) / 4e3) * __ms;
 if (__tmp < 1.0)
  __ticks = 1;
 else if (__tmp > 65535)
 {
  // __ticks = requested delay in 1/10 ms
  __ticks = (uint16_t) (__ms * 10.0);
  while(__ticks)
  {
   // wait 1/10 ms
   _delay_loop_2(((F_CPU) / 4e3) / 10);
   __ticks --;
  }
  return;
 }
 else
  __ticks = (uint16_t)__tmp;
 _delay_loop_2(__ticks);
#endif
}



문제는 빌드 실행시 위의 헤더 파일이 열리면서 __builtin_avr_delay_cycles(__ticks_dc); 부분을 가리키며

에러 메세지와 함께 컴파일이 되지 않습니당.

사용한 delay 함수에 입력되는 인자값하고 리턴값의 자료형 때문이라고 추측하고 풀어보려는데 좀 처럼 해결방법이

보이지 않아 이렇게 질문드려봅니다. 일단 어떤문제 때문인지 확실치 않아서 궁금합니다.

에러 메세지는 다음과 같습니다.

Error 2 __builtin_avr_delay_cycles expects a compile time integer constant c:\program files (x86)\atmel\atmel toolchain\avr8 gcc\native\3.4.2.1002\avr8-gnu-toolchain\bin\../lib/gcc/avr/4.7.2/../../../../avr/include/util/delay.h

Warning 1 's' may be used uninitialized in this function [-Wmaybe-uninitialized] C:\Atmel_hjh\test\GccApplication6\GccApplication6\GccApplication6.c


해결책이나 참고 내용에 대해 알려주시면 대단히 감사드리겠습니다.

현재  강좌에서 알려주신 avrstudio 6.1 프로그램만으로 강좌를 수행중에 있습니다. 가능하시다면 avrstudio 6.1

안에서 해결할수있는 방법을 알려주신다면 더더욱 감사드리겠습니다.

자료출처: http://cafe.naver.com/lazydigital/ 작성자: 임베디드홀릭



제가 잠깐 해 봤는데 일단 되는 것 같습니다.

1. winavr 20100110 을 설치
2. avrstuio 6.1 에서
Project -> Advanced ->
파란색
Tools -> Options -> Toolchain -> Flavour Configuration
을 click
3. Add flavour 로 Native 다음에 하나를 추가하고
경로를
C:\Winavr-20100110\avr\bin 을 선택

이후 컴파일

http://winavr.sourceforge.net/download.html
winavr 새 버젼 download



No comments:

Post a Comment

Total Pageviews