본문 바로가기
WORK/Sotfware

CodevsionAVR ANSI C Language 요점 정리

by KANG Stroy 2008. 7. 18.
728x90
728x90

l        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

-  자동 소스 생성 기능 내장

 

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

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

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

- 대소문자 구분 있음.

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

 

l        CodeVisionAVR의 데이터 타입

데이터 타입

크기(bit)

범 위

Bit

1

0,1

Char

8

-128 ~ 127

Unsigned char

8

0 ~ 255

Signed char

8

-127 ~ 127

Int

16

-32768 ~ 32767

Short int

16

-32767 ~ 32767

Unsigned int

16

0 ~ 65536

Signed int

16

-32767 ~ 32767

Long int

32

-2147483648 ~ 2147483647

Unsigned long int

32

0 ~ 4294967295

Signed long int

32

-2147483648 ~ 2147483647

Float

32

-0.175e-38 ~ +0.402e38

Double

32

-0.175e-38 ~ +0.402e38

 

l        주석(Comments) 처리

주석 시작           /*

주석 끝              */

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

한 줄 주석 처리: //

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

 

l        전처리(Preprocessor)

-         <![endif]>파일 포함 처리:

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

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

-         <![endif]>macro define:

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

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

-         <![endif]>파라미터를 가질 수 있음:

#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     /* 링크 라이브러리 지정 */

 

n        상수(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차까지 가능

 

n        변수(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하게 할당된다.

 

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

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

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

struct x {

             int a;

             char c;

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

 

l        비트(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에서 지정할 수 있다.

가능한 작게 지정하는 것이 좋음 (전역 변수에서 많이 사용 가능)

 

l        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)

}

 

l        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비트를 사용함.

 

l        인터럽트 사용 하기

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 */

 

l        어셈블리 언어 첨가

#asm 과 #endasm 사용

:

void delay(unsigned char i){

while(i--){

             #asm

                           nop

                           nop

             #endasm

             };

}

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

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

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

 

l        딜레이(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)          /* 인터럽트 인에이블 */

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

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

728x90

'WORK > Sotfware' 카테고리의 다른 글

ponyprog2000 다운로드 방법  (0) 2008.07.22
ShellExecute와 ShellExecuteEx 를 이용해 프로세스 실행하기!  (0) 2008.07.21
AVR8535 PORTC  (0) 2008.07.17
CodevisionAVR #pragma  (2) 2008.07.17
AVR ASM 요약..  (0) 2008.07.17

댓글