8051
AVR
EZLab
PIC
80C196KC
DSP
ARM
VHDL
마이크로마우스
로봇축구
Battle 로봇
로봇대회
휴먼로봇
Embeded Linux
HW/SW 강좌
RTOS
 
 

 CodeVisionAVR C 컴파일러 요점 정리

 ◆ CodeVisionAVR 특징

    - Atmel AVR용 통합 환경 C 컴파일러.

      통합 환경 내에 여러 가지 ISP 기능 포함.

      통합 환경 내에 비동기 통신 터미널 기능 내장.

    - 윈도우 95, 98, NT4.0, 2000 환경에서 동작

    - 생성된 COFF파일은 AVR Studio를 사용하여 소스 레벨 디버깅 가능.

    - 표준 라이브러리 외에 아래의 여러 가지 주변 소자 라이브러리 포함

       -- 문자형 LCD 모듈

       -- Philips I2C 버스

       -- 온도 센서 소자(LM75, DS1820)

       -- Real Time Clock 소자 지원(PCF8563,PCF8583, DS1302, DS1307)

       -- Dallas 1 Wire 프로토콜

       -- Thermometer/Thermostat (ds1621)

       -- SPI

       -- Delay 함수

       -- Power management

    - 자동 소스 생성 기능 내장

◆ 변수 / 함수 / 레벨의 이름(Identifiers) 지정

    - 알파벳 문자(A..Z, a..z)와 숫자(0…9) 그리고 underscore(_)문자 사용 가능.

    - 시작은 알파벳 문자나 underscore로 사용 가능.

    - 대소문자 구분 있음.

    - 최대 32문자까지 사용 가능.

◆ 주석(Comments) 처리

주석 시작           “/*”

주석 끝              “*/”

     예:        /* 이것은 주석 입니다 */

한 줄 주석 처리: “//”

     예:        // 이것도 주석입니다.

◆ 전처리(Preprocessor)

 ㆍ파일 포함 처리:

 #include <file name>       /* 컴파일러 설치 사용 디렉터리에서 참조 */

 #include “file name”        /* 현재 작업 디렉터리에서 참조 */

 

 ㆍmacro define:

 #define ALFA 0xff            /* ALFA 심볼을 0xff로 동일 처리 */

                            /* 소스 문에서 ALFA를 모두 0xff로 컴파일 처리 함 */

 ㆍ파라미터를 가질 수 있음:

 #define SUM(a,b) a+b

  int         i=SUM(2,3);               /* i=2+3;으로 치환 처리 */

 

ㆍ매크로 파라미터에 #을 사용하면 문자열로 치환:

 #define PRINT_MESSAGE(t) printf(#t)

PRINT_MESSAGE(Hello);            /* printf(“Hello”)와 동일 처리 */

 

ㆍ두개의 파라미터가 ## 연산자로 하나로 합해 짐:

#define ALFA(a,b) a ## b

 char      ALFA(x,y)=1;       /* char xy=1; 과 동일  처리 */

 

ㆍ역 슬래시(\)를 사용하여 다음 줄까지 연장:

 #define MESSAGE “This is a very \

 long text…”

 

ㆍdefine 취소: #undef 사용

 #undef  ALFA

 

ㆍ조건부 컴파일 처리 : #ifdef, #ifndef, #else, #endif

 #ifdef macro_name

             [문 1 그룹]

#else                                            /* option */

             [문 2 그룹]

#endif

설명: 만일 macro_name이 define 되어 있으면 [문 1 그룹]을 컴파일 하고, 그렇지 않으면

[문 2그룹]을 컴파일 한다. 또 다른 조건부 컴파일 처리: #if, #elif, #else, #endif

#if expression1

             [문 1 그룹]

#elif expression2

             [문 2 그룹]

#else

             [문 3 그룹]

#endif

설명: 만일 expression1이 true이면 [문 1 그룹]을 컴파일 하고, 그렇지 않고 만일 expression2가 true이면 [문 2 그룹]을 컴파일 하고, 그 외에는 [문 3 그룹]을 컴파일 한다.

 

ㆍ#error 문: 컴파일을 중지하고 에러 메시지를 표시.

예:

#error This is an error!

 

#pragma 문: 컴파일러 특수 지시 문

#pragma warn-                             /* warning 디스어블 */

#pragma warn+                             /* warning 인에이블 */

#pragma opt-                               /* 최적화 안 함 */

#pragma opt+                               /* 최적화 함 */

#pragma savereg-                       /* 레지스터 저장 안 함 */

#pragma savereg+                       /* 레지스터 저장 함 */

#pragma library mylib.lib  /* 링크 라이브러리 지정 */

◆ 상수(Constants)

 2진수 : 0b로 시작(예 0b101001)

 16진수 : 0x로 시작 (예. 0xff)

 8진수 : 0으로 시작 (예. 0777)

 Unsigned integer 상수는 뒤에 U사용: (예, 10000U)

 Long integer 상수는 뒤에 L사용: (예, 99L)

 Unsigned Long integer 상수는 뒤에 UL사용: (예, 99UL)

 Floating point 상수는 뒤에 F사용: (예, 1.234F)

 문자 상수는 1중 따옴표로 처리: (예, ‘a’)

 문자열 상수는 2중 따옴표로 처리:  (예, “Hello world”)

 (함수의 파라미터 안에 2중 따옴표 문자열이 있으면 FLASH 메모리에 놓임.)

 행렬은 최대 8차까지 가능

◆ 변수(Variables)

전역(global) 변수와 지역(local) 변수가 있음.

전역(global) 변수 : 함수 외각에 선언, 프로그램 내의 모든 함수에서 사용 가능.

지역(local) 변수 : 함수 내부에 선언, 해당 함수 내에서만 사용 가능.

초기화하지 않은 전역 변수는 프로그램 초기에 0으로 초기화 됨.

  예:

    /* 전역 변수 선언 */

      char a;

      int b;

      long c = 0x12345678;        /* 초기화 */

      void main(void){

    /* 지역 변수 */

      char d;

      int e;

      long f=22222222; /* 초기화 */

    …

     }

◆ 행렬 변수: 8 차까지 가능, 0부터 시작, 초기화하지 않은 전역 행렬 변수 값은 0으로                   초기화.

  /* 전역 행렬 변수 */

  int global_array1[32];       /* 모든 값이 0으로 초기화 */

  int global_array2[]={1,2,3};

  int global_array3[4]={1,2,3,4};

  char global_array4[]=”This is a string”;

  int multidim_array[2,3]={{1,2,3},{4,5,6}};

  void main(void){

  

  /* 지역 행렬 변수 */

  int local_array[3]={11,22,33};

  …

   }

◆ static 변수: 지역 변수라도 static 선언을 하면 값을 보존할 수 있다.

  예:

     int alfa(void){

     static int n=1;      /* static 변수 선언 */

     return n++;

     }

     void main(void){

     int i;

     i = alfa();             /* return 값 = 1 */

     i = alfa();             /* return 값 = 2 */

      …

     }

◆ extern 선언 : 다른 파일에 선언된 변수는 extern 선언을 해야한다.

    extern int xyz;

  전역 변수는 SRAM의 Global Variables 영역에 저장되고, 지역 변수는 SRAM의 Data Stack 영역에 dynamic하게 할당된다.

◆ 외부 SRAM의 특정 번지에 전역 변수를 지정하는 방법

   연산자 사용하여 전역 변수를 특정 SRAM 위치에 배치할 수 있다.

   int  a  @0x80                   /* 정수 변수 a는 외부 SRAM 0x80에 할당 */

   struct x {

         int a;

         char c;

            } alfa @0x90        /* 0x90 번지에 구조체 alfa 할당 */

◆ 비트(bit) 변수

 비트 변수는 레지스터 R2에서 R15까지 사용 가능: 최대 112 비트.

   예:

      bit alfa=1;            /* bit0 of R2 */

      bit beta;              /* bit1 of R2 */

      void main(void){

      if(alfa) beta != beta;

      …

      }

비트 변수 크기 지정은 Project|Configure|C Compiler|Compilation|Bit Variable Size에서 지정할 수 있다. 가능한 작게 지정하는 것이 좋음 (전역 변수에서 많이 사용 가능)

◆ I/O 레지스터의 비트 단위 액세스

  I/O 레지스터를 비트 단위로 액세스 할 수 있다.

   예:

     DDRA.0 = 1;         /* Port A의 비트 0을 출력 포트로 함 */

     DDRA.1 = 0;         /* Port A의 비트 1을 입력 포트로 함 */

     PORTA.0 = 1;      /* Port A의 비트 0에 1 출력 */

     If(PINA.1){           /* Port A의 비트 1를 판별하여 처리 */

   /* 코드 추가 */

     }

   프로그램의 판독을 좋게 하려면 #define을 사용하여 의미 부여 사용.

  #define alarm_input PINA.2

   void main(void){

   if(alarm_input)

   …

    }

◆ EEPROM 액세스

 AVR 내부의 EEPROM 사용은 전역 변수 앞에 eeprom 키워드를 사용하여 가능하다.

   예:

   eeprom int alfa=1;          /* Chip 프로그램 시에 EEPEOM에 1값 저장 */

   eeprom char beta;

   eeprom long array1[5];

   eeprom char string[]=”Hello”;   /* Chip 프로그램 시에 EEPEOM에 문자열 저장 */

 

 void main(void){

   int i;

   int eeprom *ptr_to_eeprom;          / EEPROM 포인터 */

    …

   alfa = 0x55;                       /* EEPROM에 0x55 값 직접 쓰기 */

   ptr_to_eeprom=&alfa;

   ptr_to_eeprom=0x55;       / 포인터 사용하여 간접적으로 쓰기 */

   i=alfa;                               /* EEPROM에서 직접적으로 값 읽기 */

   i=*ptr_to_eeprom;            /* EEPROM에서 간접적으로 값 읽기 */

  }

   EEPROM의 포인터는 항상 16비트를 사용함.

◆ 인터럽트 사용 하기

 ㆍinterrupt 키워드를 사용.

    예: 여기서 벡터 번호는 AT90S8515에 대한 것 임.

      interrupt [2] void external int0(void){           /* 외부 인터럽트 */

   /* 여기에 처리 코드를 넣는다 */

      }

      interrupt [8] void timer0 overflow(void){    /* 타이머0 Overflow 인터럽트 */

   /* 여기에 처리 코드를 넣는다 */

      }

 인터럽트 벡터 번호는 1부터 시작.

 인터럽트 처리 시작 부분에서 자동적으로 레지스터를 스택에 저장하고 인터럽트 종료 시 다시 스택에서 레지스터로 회복해 놓는다. 자동적으로 저장하는 레지스터는 R0, R1, R22 ~ R31, SREG이다. 만일 레지스터를 대피하는 인터럽트 처리 시간을 조금이라도 단축하고자 하는 경우 #pragma savereg 지시자를  사용한다.

 예:

   #pragma savereg-           /* 레지스터 저장 기능 OFF */

    interrupt [1] void my_irq(void){

  /* 사용하는 레지스터 만 저장 예: R30, R31, SREG 만 사용하는 경우 */

  #asm

          push r30

          push r31

          in r30, SREG

          push      r30

#endasm

   /* 여기에 C 코드를 놓음 */

   /* 레지스터 SREG, R31, R30 회복 */

 #asm

          pop       r30

          out         SREG,r30

          pop       r31

          pop       r30

 #endasm

  }

 #pragma savereg+           /* 레지스터 저장 기능 ON */

◆ 어셈블리 언어 첨가

 #asm 과 #endasm 사용

  예:

       void delay(unsigned char i){

    while(i--){

       #asm

              nop

              nop

       #endasm

          }

       }

 다음과 같이 한 줄로 표현 할 수도 있다.

   #asm(“sei”)        /* 인터럽트 인에이블 */

 어셈블리 루틴에서 R0, R1, R22 ~ R31은 자유롭게 사용할 수 있다. 단 인터럽트 루틴 안에서 사용 시에는 스택에 저장 및 회복을 해야 한다.

◆ 딜레이(delay) 함수 사용

 CodeVisionAVR에서는 일정 시간 동안 지연하는 2개의 딜레이 함수를 제공한다.

   void       delay_us(unsigned int n);          /* micro(u) sec 단위 지연 함수 */

   void       delay_ms(unsigned int n);         /* milli(m) sec 단위 지연 함수 */

예:

   delay_us(100);    /* 100 usec 지연 */

   delay_ms(123);   /* 123 msec 지연 */

 딜레이 함수를 사용하기 전에 delay.h 헤더 파일을 포함해야 되고, 정확한 시간을 위해서는 Project|Configure|C Compiler 메뉴의 AVR chip 클럭 주파수가 정확히 설정되어야 한다.

 지연 동안 인터럽트가 처리될 수 있고 인터럽트가 처리되면 지연 시간이 늘어 날 수 있다.좀더 정확한 시간을 원하면 지연 시간동안 인터럽트를 금지할 필요가 있다.

     예:

         …

        #asm (“cli”)        /* 인터럽트 디스어블 */

          delay_us(100);    /* 100 usec 지연 */

        #asm(“sei”)        /* 인터럽트 인에이블 */

         …

◆ 표준 함수 및 응용 함수 사용

 CodeVionAVR C 컴파일러에서는 거의 모든 ANSI 표준 함수를 제공하고 있으며, 기타 LCD, 온도 센서, 시계 소자 등 여러 가지 라이브러리 함수를 제공하고 있는데 이에 대한 자세한 내용은 “CodeVisionAVR User Manual”을 참조 바람.

상호 : (주) 로보블럭 사업자등록번호:214-86-56219 통신판매업신고19-2544 대표: 신대섭 전화:(02)2679-8556 Fax :(02)2679-8557
본사 : 경기도 부천시 원미구 약대동 부천 테크노파크 401동 502호     서울사무소 : 서울시 영등포구 문래동 4가 8-1 4층
Copyright(C) 2004, (주) 로보블럭 시스템즈 All Rights Reserved E-Mail : WebMaster