Presentation is loading. Please wait.

Presentation is loading. Please wait.

3 8051을 위한 C 언어 프로그래밍.

Similar presentations


Presentation on theme: "3 8051을 위한 C 언어 프로그래밍."— Presentation transcript:

1 3 8051을 위한 C 언어 프로그래밍

2 프로그래밍 언어의 종류를 알고 특성을 이해한다.
8051에서 C 언어를 사용하는 방법을 익힌다. 실습에 필요한 주요 프로그래밍 기법을 익힌다. 01. 프로그래밍 언어 을 위한 C 언어 03. 유용한 프로그래밍 기법

3 01. 프로그래밍 언어 1.1 기계어 What is the program language? 프로그래밍 언어의 종류
Program : CPU가 순서적으로 처리해야 할 일을 만드는 것. 명령어(Instruction) : CPU가 처리해야 할 일. Machine Language CPU가 이해할 수 있는 언어. Mnemonic Code 사람이 이해하기 쉽도록 기호 또는 문자를 압축해서 만든 코드. 프로그래밍 언어의 종류 고급 언어 (High level language) : FORTRAN, PASCAL, COBOL, C 언어 등 저급 언어 (Low level language) : 어셈블리어 기계어 (Machine language) : 기계 고유의 언어

4 01. 프로그래밍 언어 프로그래밍 언어의 변환 과정 소스 프로그램(Source Program) : 어셈블리어나 고급 언어로 작성한 원본 프로그램이며, 원시 프로그램이라고도 함 목적 프로그램(Object Program) : 변환된 기계어 프로그램 소스 프로그램 번역기 목적 프로그램

5 01. 프로그래밍 언어 1.2 어셈블리어 어셈블리어 니모닉 코드(mnemonic code) 어셈블리어로 프로그래밍을 하는 경우
기계어의 비트 형식이 나타내는 의미를 심벌(symbol)로 표현한 것으로 프로그램을 이해하거나 작성하기가 쉽다. MOV A, #03H 어셈블리어로 프로그래밍을 하는 경우 컴퓨터 하드웨어의 구성 요소를 직접 액세스할 때 컴파일러를 설계하거나 시스템 프로그램을 작성할 때 빠른 수행이 필요한 프로그램을 작성할 때 기억장소를 적게 차지하거나 입출력 장치를 효율적으로 사용할 때 8051 어셈블리어 예

6 02. 8051을 위한 C 언어 2.1 8051용 C 언어와 컴파일러 C 언어 vs. 어셈블리어
잘못된 편견 - 마이크로컨트롤러 시스템을 구현하기 위해서 C 언어가 어셈블리어보다 쉽다 - 앞으로는 어셈블리어는 없어지고 C 언어만이 존재한다 어셈블리어는 수행속도와 메모리 측면에서 유리하지만 마이크로컨트롤러마다 다 르다는 단점이 있다. C 언어는 보다 쉽고 간편하게 프로그램을 작성할 수 있지만 정확한 시간산출이 어렵고 메모리 측면에서는 불리하다는 단점이 있다. 8051을 위한 상용 컴파일러 : Keil, IAR, Raisonance社에서 만든 컴파일러 - 상용 버전은 고가이지만 사용에 제한이 있는 데모 버전을 무료로 배포 상용 컴파일러는 표준 ANSI C언어를 동일하게 구현하고 있으나, 8051 하드웨어 환경 제어를 위해 확장된 사항들은 숙지해야 함

7 02. 8051을 위한 C 언어 2.2 상수의 표현 정수 상수 실수 상수 예 53.18765
고정 소수점 방식 : 소수점을 찍어 정수부와 실수부로 나누어 표시 부동 소수점 방식 : 가수부(mantissa)와 지수부(exponent)로 나누어 표시 진수 설명 8진수 0으로 시작되는 숫자 012 10진수 +, -, 0 이외의 숫자로 시작되는 숫자 123, -10 16진수 0x, 0X로 시작되는 숫자 0x1c, 0X1c .345 // 소수점 앞의 0을 생략하여 표현 -25. // 소수점 뒤의 0을 생략하여 표현 5318e5 // 5318x105을 표현 .145e2 // 0.145x102을 표현 -2.4e-4 // -2.4x10-4을 표현

8 02. 8051을 위한 C 언어 문자 상수 문자열 상수 #define 예
하나의 문자로 이루어진 상수이며, 작은 따옴표(‘’)사이에 하나의 문자로 표현 문자상수들은 아스키(ASCII)값들을 가진다. 문자열 상수 큰 따옴표(“ ”)사이에 문자열을 넣어서 사용한다. #define 어떤 특정한 값을 미리 정해주는 역할을 한다. ‘A’의 경우 10진수 65, 16진수 0x41 값을 갖는다. “Hi C”는 4개의 문자와 문자열의 끝을 알려주는 0(null 문자)을 포함하므로 실제 크기는 5바이트이다. #define pi // pi=3.14를 의미한다. #define count 100 // count=100을 의미한다.

9 02. 8051을 위한 C 언어 2.3 연산자 산술연산 증가/감소연산 사용 예 설명 사용 예 설명 a+b a와 b를 더함
a++, (++a) a=a+1 또는 a+=1, a를 1 증가 a--, (--a) a=a-1 또는 a-=1, a를 1 감소

10 02. 8051을 위한 C 언어 대입연산 관계연산 사용 예 설명 사용 예 설명 a*=b
a=a*b, a와 b를 곱해서 a에 대입 a /= b a=a/b, a를 b로 나누어서 몫을 a에 대입 a %= b a=a%b, a를 b로 나누어서 나머지를 a에 대입 a += b a=a+b, a와 b를 더해서 a에 대입 a -= b a=a-b, a에서 b를 빼서 a에 대입 사용 예 설명 a > b a가 b보다 크면 참 a >= b a가 b 이상이면 참 a < b a가 b보다 작으면 참 a <= b a가 b 이하이면 참 a == b a와 b가 같으면 참 a != b a와 b가 같지 않으면 참

11 02. 8051을 위한 C 언어 논리연산 비트연산 사용 예 설명 사용 예 설명 !(a식)
(a식) && (b식) (a식)과 (b식)이 모두 참(논리1)이면 참이다. (a식) || (b식) (a식) 또는 (b식)이 참(논리1)이면 참이다. 사용 예 설명 ~a a=~a (a를 비트 단위로 반전) a <<= 2 a=a<<2 (a의 각 비트를 왼쪽으로 2회 시프트) a >>= 2 a=a>>2 (a의 각 비트를 오른쪽으로 2회 시프트) a &= b a=a&b (a와 b를 각 비트 단위로 AND) a ^= b a=a^b (a와 b를 각 비트 단위로 XOR) a |= b a=a|b (a와 b를 각 비트 단위로 OR)

12 02. 8051을 위한 C 언어 2.4 데이터 형 데이터 형 내용 기억범위 크기 bit 비트 0 또는 1 1비트
char(signed char) 부호 있는 정수 -128 ~ +127 1바이트 unsigned char 부호 없는 정수 0 ~ 255 enum -32,768 ~ +32,767 2바이트 int(signed int) unsigned int 0 ~ 65,535 short(signed short) 부호 있는 단정도 정수 unsigned short 부호 없는 단정도 정수 long(signed long) 부호 있는 배정도 정수 -2,147,483,648 ~ +2,147,483,647 4바이트 unsigned long 부호 없는 배정도 정수 0 ~ 4,294,697,295 float 실수  E-38 ~  E+38 sfr 8비트 SFR 어드레스 0x00 ~ 0xff sbit SFR 비트번호

13 02. 8051을 위한 C 언어 bit 형 sbit 형 예 bit day = 0, night = 1; 예
비트 단위의 독립적인 변수를 정의하는 것 sbit 형 bdata로 선언된 독립적인 변수 내부에서 몇 번째 비트를 액세스하기 위한 비트지정 방법 8051 내부 RAM 중에 비트 단위로 처리 가능한 영역(0x20~0x2f)과 특수기능 레지스터 영역(0x80~0xff)에서 비트 지정이 가능한 영역에 변수를 지정할 때 사용 bit day = 0, night = 1; sbit LED_L =P1^0; // P1.0을 LED_L로 지정 sbit LED_C =P1^1; // P1.1을 LED_C로 지정 sbit LED_R =P1^2; // P1.2를 LED_R로 지정 bit 형 또는 sbit 형은 논리 연산(AND, OR, NOT, XOR), 상태 표시, 8051에서 비트별로 입출력 포트 제어를 위해 사용한다.

14 02. 8051을 위한 C 언어 sfr 형 sfr16 형 예 sfr P0=0x80; 예
특수기능 레지스터를 선언하는데 사용 SFR 영역의 특수기능 레지스터 이름들은 헤더파일(8051용으로는 reg51.h, 8052용으로는 reg52.h)에 있기 때문에 따로 지정할 필요는 없음 sfr16 형 8052 계열의 16비트 데이터 값을 직접 지정하는데 사용 sfr P0=0x80; sfr16 T2=0xcc; // T2L=0xcc, T2H=0xcd

15 02. 8051을 위한 C 언어 2.5 메모리 형과 메모리 모델 메모리 형 프로그램 메모리 영역(ROM)의 상수 데이터
데이터 메모리 영역(RAM)의 상수 데이터 메모리 형 포인터 값 설명 idata 1 간접 액세스할 수 있는 내부 데이터 메모리(256바이트) xdata 2 외부 데이터메모리(64K바이트) pdata 3 페이지화 된 외부 데이터 메모리(256바이트) data 4 직접 액세스할 수 있는 내부 데이터 메모리(128바이트) code 5 프로그램 메모리(64K바이트) code unsigned char sensor=0x05; code unsigned char table[7]={0x40,0x79,0x24,0x30,0x19,0x12,0x02}; unsigned char index=0x7f; unsigned int constant=0x7f00;

16 02. 8051을 위한 C 언어 메모리 모델 프로그램 메모리와 데이터 메모리가 어떠한 형태로 사용되는가를 의미
실행속도가 빠르고 효율적인 코드를 생성하기 위해 가장 작은 모델인 small을 사용 메모리 모델 설 명 small 모든 변수는 내부 데이터 메모리128byte(0x00~0x7f)를 사용 하며, 기본적인 메모리 형은 data compact 모든 변수는 외부 데이터 메모리 256byte(0x00~0xff)를 사용 하며, 기본적인 메모리 형은 pdata large 모든 변수는 외부 데이터 메모리64Kbyte(0x0000~0xffff)를 사 용하며, 기본적인 메모리 형은 xdata

17 02. 8051을 위한 C 언어 2.6 제어 구조와 루프(loop)문 if 문과 if~else 문 사용법 의미 if 문
사용법 의미 if 문 if (조건식) { statement(s) 1; } statement(s) 2; 조건식이 참이면, statement(s) 1을 실행하 고, 거짓이면 if 다음에 있는 statement(s) 2를 실행한다. If~else 문 else { 조건식이 참이면 statement(s) 1을 실행하 고, 거짓이면 statement(s) 2를 실행한다.

18 02. 8051을 위한 C 언어 P03_01.c #include <reg51.h> void main(void) {
unsigned char a=2, b=0; // 변수 선언과 변수 초기화 if (a) P1=0x04; // a≠0이므로 조건식은 참이 되고 포트 1에 0x04 출력 if (a<b) { // 조건식이 거짓임으로 else 다음 { } 부분 실행 P1=0x00; // 포트 1에 0x00 출력 P2=0x00; // 포트 2에 0x00 출력 } else { P1=0xb3; // 포트 1에 0xb3 출력 P2=0xe5; // 포트 2에 0xe5 출력

19 02. 8051을 위한 C 언어 while 문과 do~while 문 사용법 의 미 while 문 while (조건식) {
    사용법 의  미 while 문 while (조건식) { statement(s); } 조건식이 참일 동안 { } 사이의 문장들인 statement(s)을 반복하며 실행한다. 조건식이 거짓이 되면 { } 부분을 더 이상 실행하지 않고 빠져 나온다. do~while 문 do { } while (조건식) ; 조건식에 관계 없이 일단 { } 사이의 문장들인 statement(s)을 한번 실행한 후에 조건식을 검 사한다. 그리고 조건식이 참일 동안 { } 사이의 문장들을 반복해서 실행한다. 조건식이 거짓 이 되면 { } 부분을 더 이상 실행하지 않고 빠 져 나온다.

20 02. 8051을 위한 C 언어 P03_02.c #include <reg51.h> void main(void) {
unsigned char a=2, b=0; // 변수 선언과 초기화 while(b) P1=0xd2; // b=0이므로 P1=0xd2;를 실행하지 않음 do { P1=0x2e; // 포트 1에 0x2e 출력 P2=0x3c; // 포트 2에 0x3c 출력 } while(b);    // b=0이므로 조건식은 거짓이지만 일단 한번은 실행 while(a-- > 0) { // a를 1씩 감소하면서 {} 안의 명령문 실행 // a=0이 되면 while 문을 빠져 나옴 P1=0x7f; // 포트 1에 0x7f 출력 P2=0xa3; // 포트 2에 0xa3 출력 }

21 02. 8051을 위한 C 언어 for 문 P03_03.c #include <reg51.h>
사용법 for (초기식; 조건식; 증감식) { statement(s); } P03_03.c #include <reg51.h> void main(void) { unsigned char i, sum=0 ; // 변수 선언과 초기화 for (i=1; i<11; i++) { // i=1에서부터 10까지 {} 안의 명령문 실행 // i는 순환할 때마다 1씩 증가 sum=sum+i; // 1~10까지 숫자를 더함 P1=sum; // 포트1에 현재의 sum 값 출력 }

22 02. 8051을 위한 C 언어 switch 문 switch (수식) { case 값 1 : statement 1;
사용법 switch (수식) { case 값 1 : statement 1; break; case 값 2 : statement 2; break;   case 값 3 : statement 3;           … default : statement N; }

23 02. 8051을 위한 C 언어 P03_04.c #include <reg51.h> void main(void) {
unsigned char num=2 ; // 변수 선언과 초기화 switch(num+1) { // ( )안의 값은 3이 되어 case 3:으로 // 점프하여 명령문 실행 case 1: P1=0x01; // 포트 1에 0x01 출력 break; case 2: P1=0x02; // 포트 1에 0x02 출력 case 3: P1=0x03; // 포트 1에 0x03 출력 default : P1=0xff; // 포트 1에 0xff 출력 }

24 을 위한 C 언어 break 문 while 문, do~while문, for문 안에서 루프를 탈출하기 위해서 사용되고 또한 switch 문에서 블록을 빠져 나올 때도 사용 P03_05.c #include <reg51.h> void main(void) { unsigned char num=0; // 변수 선언과 초기화 while(num++ < 100) { // num이 0~99까지 루프를 100번 반복 P1=num; // 포트1에 num 값을 출력 if (num==50) break; // num이 50이면 while 루프를 빠져 나감 }

25 을 위한 C 언어 continue 문 while, do~while, for 루프를 돌다가 continue 문을 만나게 되면 루프의 중간이더라도 다음 문장들은 실행시키지 않고 루프의 처음으로 돌아가 조건식과 비교하교 루프를 순환 continue 문은 루프의 중간에 어떤 조건하에서 나머지 문장들을 실행할 필요가 없을 경우에 사용 P03_06.c #include <reg51.h> void main(void) { unsigned char num=0; // 변수 선언과 초기화 while (num++ < 100) { // num이 0~99까지 루프를 100번 반복 if ( num % 2 ) continue; // num이 홀수면 뒷 부분을 실행하지 않음 P1=num; // num이 짝수일 때만 포트1에 num 값 출력 }

26 을 위한 C 언어 goto 문 프로그램 수행 도중 goto 문을 만나면 goto 문 다음에 나오는 레이블(label)로 점프하여 그곳에서부터 프로그램을 수행 P03_07.c #include <reg51.h> void main(void) { unsigned char num=0; // 변수 선언과 초기화 while (num++ < 100) { // num이 0~99까지 루프를 100번 반복 if (num==50) goto label_1; // num이 50이면 label_1로 점프 P1=num; // 포트 1에 num 값을 출력 } label_1: P1=100; // 포트 1에 100 출력

27 02. 8051을 위한 C 언어 2.7 포인터의 사용 일반 포인터 (generic pointer) 예 char *strptr;
포인터는 주소(address)에 대한 기호화된 표현 8051용 C언어에서는 일반 포인터와 메모리 지정 포인터(memory specific pointer)의 2가지를 지원 일반 포인터 (generic pointer) ANSI C에서 사용하는 것과 같은 기본적인 포인터로서 항상 3바이트를 사용하여 변수를 가리킨다. 첫 번째 바이트는 메모리 형을 지정하는 것이고, 나머지는 메모리 어드레스를 나타내는 2바이트의 총 3바이트 크기다. 일반 포인터는 메모리 영역의 어느 위치에서라도 변수를 액세스할 수 있는 장점이 있지만 처리 속도가 늦은 단점이 있다. char *strptr; int *numptr; long *varptr;

28 을 위한 C 언어 메모리 지정 포인터 메모리 지정 포인터는 포인터 선언에 메모리 형을 함께 지정함으로써 항상 지정된 메모리 영역을 참조하도록 하는 것 메모리 지정 포인터는 1바이트(idata, data, bdata, pdata 포인터) 또는 2바이트(code, xdata 포인터)를 사용해서 저장 일반 포인터에 비해 메모리 효율적이며 처리속도가 빠르다. char code *strptr; // code 영역에 char로 strptr 포인터를 선언 int idata *numptr; // idata 영역에 int로 numptr 포인터를 선언 long xdata *varptr; // xdata 영역에 long으로 varptr 포인터를 선언 char code *xdata strptr; int idata *idata numptr; long xdata *idata varptr;

29 02. 8051을 위한 C 언어 일반 포인터와 메모리 지정 포인터의 비교 설명 idata 포인터 xdata 포인터 일반 포인터
예제 프로그램 char idata *ip; char val; val=*ip; char xdata *xp; val=*xp; char idata *p; val=*p; 생성된 8051 프로그램 코드 MOV R0,ip MOV MOV DPL,xp+1 MOV DPH,xp MOVX MOV val,A MOV R1,p+2 MOV R2,p+1 MOV R3,p CALL CLDPTR 포인터 크기 코드 크기 실행 사이클 1바이트 데이터 4바이트 코드 4사이클 2바이트 데이터 9바이트 코드 7사이클 3바이트 데이터 11바이트 코드 13사이클

30 02. 8051을 위한 C 언어 = 배열과 포인터 포인터 선언 및 포인터 변수에 값을 저장하는 방법
unsigned char *ptr; // 메모리 주소를 의미 ptr = &valiable; // &는 메모리의 주소를 의미하는 포인터 연산자 // 포인터 변수 ptr에는 variable 변수가 저장되어 있는 // 메모리 주소가 들어간다 *ptr = 0x7f; // variable에 0x7f가 들어간다. unsigned char *ptr; ptr = &valiable; *ptr = 0x7f; = variable = 0x7f;

31 02. 8051을 위한 C 언어 a==&a[0]; // 배열 이름 a는 배열의 첫 번째 요소가 있는 주소(=200)
포인터는 주소를 참조하는 변수 배열의 이름은 배열의 첫 번째 요소가 있는 주소이다. (배열이름+1)은 두 번째 요소가 있는 주소를, (배열이름+2)는 세 번째 요소가 있는 곳의 주소를 나타낸다. char a[5]={11,22,33,44,55}; char *ptr; ptr=a; // ptr=&a가 아님 포인터 ptr ptr+1 ptr+2 ptr+3 ptr+4 주소 200 201 202 203 204 11 22 33 44 55 배열 요소 a[0] a[1] a[2] a[3] a[4] a==&a[0]; // 배열 이름 a는 배열의 첫 번째 요소가 있는 주소(=200) *a==a[0]; // *a는 배열의 첫 번째 요소의 값, a[0]=11 *(a+1)==a[1]; // *(a+1)는 배열의 두 번째 요소의 값, a[1]=22 *(a+2)==a[2]; // *(a+2)는 배열의 세 번째 요소의 값, a[2]=33 *(a+3)==a[3]; // *(a+3)은 배열의 네 번째 요소의 값, a[3]=44 *(a+4)==a[4]; // *(a+4)는 배열의 다섯 번째 요소의 값, a[4]=55

32 02. 8051을 위한 C 언어 문자가 단순 배열과 포인터로 선언된 경우 예
첫 번째 문장과 같이 선언된 배열을 포인터로 처리하면 다음 두 가지가 가능하다. char array = "HELLO!"; // “HELLO!”라는 ASCII 문자를 // 바이트 단위로 array 배열에 저장 char *ptr = "HELLO!"; // *ptr은 “HELLO!”라는 연속된 바이트의 // 첫 번째 문자의 어드레스를 가리킨다. char *ptr = array; // 배열은 포인터로 처리된다. char *ptr = &array[0]; // 배열의 첫 번째 요소의 어드레스를 // 포인터에 넣는다.

33 을 위한 C 언어 2.8 함수 함수 형식 return_type : 함수의 리턴 값으로 데이터 형을 지정하지 않으면 int 형으로 간주 function_name : 함수 이름 arg_list는 : 함수 인수 small, compact, large : 함수를 위한 메모리 모델 reentrant : 재진입 함수임을 나타냄 interrupt n : 인터럽트 서비스 루틴 함수임을 나타냄 using n : 사용할 레지스터 뱅크를 지정 [return_type]  function_name([arg_list]) {small | compact | large} [reentrant][interrupt n][using n]

34 02. 8051을 위한 C 언어 8051 C 함수에서 레지스터를 사용한 인수 전달 8051 C 함수에서 리턴 값의 전달
인수 순서 char 또는 1바이트 포인터 int 또는 2바이트 포인터 long 또는 float 일반 포인터 1 R7 R6, R7 R4 ~ R7 R1 ~ R3 2 R5 R4, R5 3 R3 R2, R3 리턴 값의 형 레지스터 비고 bit CY char, unsigned char, 1바이트 포인터 R7 int, unsigned int, 2바이트 포인터 R6, R7 R6이 MSB, R7이 LSB long, unsigned long R4 ~ R7 R4가 MSB, R7이 LSB float 32비트 IEEE format 일반 포인터 R1 ~ R3 R3에 메모리 형, R2가 MSB, R1이 LSB

35 02. 8051을 위한 C 언어 2.9 인터럽트 처리루틴 인터럽트 종류와 시작 어드레스
인터럽트 처리 루틴도 함수의 일종이므로 8051 C에서 interrupt n 키워드를 추 가해 선언하는 것 외에는 일반 함수와 차이가 없다. 인터럽트 종류와 시작 어드레스 벡터 어드레스 8051 C에서 사용하는 벡터 번호 인터럽트 원인 0x0003 외부 인터럽트 0 0x000B 1 타이머/카운터 0 0x0013 2 외 인터럽트 1 0x001B 3 타이머/카운터 1 0x0023 4 시리얼 포트 인터럽트

36 을 위한 C 언어 인터럽트 처리 루틴 선언 형식 extint0 : 인터럽트 처리함수 이름이며 사용자가 임의로 명명한다. interrupt : 인터럽트 처리루틴이라는 키워드이며 반드시 있어야 한다. 0 : 인터럽트 벡터번호 using 1 : 인터럽트 처리루틴에서 사용할 레지스터 뱅크이며 생략해도 된다. void extint0(void) interrupt 0 using 1 { // 인터럽트 처리 } 인터럽트 처리 루틴을 만들 때 주의 사항 인수를 전달할 수 없으므로 인수를 반환할 수 없다. 8051 C 라이브러리에서 제공하는 함수를 사용할 수 없다. 인터럽트 처리 루틴에서 사용하는 레지스터는 인터럽트 처리 루틴으로 들어가기 전에 자동 저장된다. 인터럽트 함수를 직접 호출(call)할 수 없다.

37 을 위한 C 언어 2.10 헤더 파일 C 언어 프로그램에서 8051만의 하드웨어를 제어하기 위해서는 8051 헤더파일을 include 문으로 포함시킴으로써 가능하다. /* REG51.H Header file for 8051. */ /* BYTE Register */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0; sfr B = 0xF0; sfr SP = 0x81; sfr DPL = 0x82; sfr DPH = 0x83; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TL0 = 0x8A; sfr TL1 = 0x8B; sfr TH0 = 0x8C; sfr TH1 = 0x8D; sfr IE = 0xA8; sfr IP = 0xB8; sfr SCON = 0x98; sfr SBUF = 0x99; /* BIT Register */ /* PSW */ sbit CY = 0xD7; sbit AC = 0xD6; sbit F0 = 0xD5; sbit RS1 = 0xD4; sbit RS0 = 0xD3; sbit OV = 0xD2; sbit P = 0xD0;

38 을 위한 C 언어 /* TCON */ sbit TF1 = 0x8F; sbit TR1 = 0x8E; sbit TF0 = 0x8D; sbit TR0 = 0x8C; sbit IE1 = 0x8B; sbit IT1 = 0x8A; sbit IE0 = 0x89; sbit IT0 = 0x88; /* IE */ sbit EA = 0xAF; sbit ES = 0xAC; sbit ET1 = 0xAB; sbit EX1 = 0xAA; sbit ET0 = 0xA9; sbit EX0 = 0xA8; /* IP */ sbit PS = 0xBC; sbit PT1 = 0xBB; sbit PX1 = 0xBA; sbit PT0 = 0xB9; sbit PX0 = 0xB8; /* P3 */ sbit RD = 0xB7; sbit WR = 0xB6; sbit T1 = 0xB5; sbit T0 = 0xB4; sbit INT1 = 0xB3; sbit INT0 = 0xB2; sbit TXD = 0xB1; sbit RXD = 0xB0; /* SCON */ sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98;

39 03. 유용한 프로그래밍 기법 3.1 시간 지연 루틴 소프트웨어 타이머 소프트웨어로 일정시간 지연하는 것
사용 형식 void delay(unsigned int i) { while(i--); } delay(0x2000); // R6=20H, R7=00H delay(0x2000) 명령을 실행하면 delay 함수로 점프하여 i 값을 하나씩 감소시켜 8,192 (2000H)번 반복한다. 이때 i 값이 0이 되어 delay 함수로부터 리턴하기까지의 시간이 지연 시간이다.

40 03. 유용한 프로그래밍 기법 C 컴파일러에 의한 지연 루틴 계산 명령어 수행 횟수 사이클 수 사이클 총 수 MOV i,R6
MOV i+01H,R7 ?C0001: MOV A,i+01H DEC i+01H MOV R6,i JNZ ?C0104 DEC i ?C0104: MOV R7,A MOV A,R7 ORL A,R6 JNZ ?C0001 RET 1 256×R6+R7+1 R6+1 2 2(256×R6+R7+1) 33 합계 2817×R6+11×R7+18 시간지연 : 2817R6+11R7+18 머신 사이클

41 03. 유용한 프로그래밍 기법 (예) 0.5초의 지연이 필요한 경우 지연 정수 산출
12MHz 수정 발진기를 사용한 경우 1 머신 사이클은 1s delay(0x2000) 함수를 수행하는 데에는 90162s(=281732+110+18)가 소요 (예) 0.5초의 지연이 필요한 경우 지연 정수 산출 R7과 R6의 조합에 따라 여러 가지 경우의 수가 존재하지만 먼저 R7=00H으로 놓고 R6 값을 계산하면, 2817R6+18=500000에서 R6=177=B1H이므로 “delay(0xb100);” 으로 하여 delay 함수를 호출하면 된다.

42 03. 유용한 프로그래밍 기법 짧은 지연시간을 얻기 위한 방법 void delay(unsigned char i) {
while(i--); } delay(0x20); // R7=20H

43 03. 유용한 프로그래밍 기법 C 컴파일러에 의한 지연 루틴 계산 시간지연 : 6R7+10 머신 사이클
delay(0x20) 함수를 수행하는 데에는 202s(=632+10)가 소요된다. 명령어 수행 횟수 사이클 수 사이클 총 수 MOV i,R7 ?C0001: MOV R7,i DEC i MOV A,R7 JNZ ?C0001 RET 1 R7+1 2 2×(R7+1) 합계 6×R7+10 시간지연 : 6R7+10 머신 사이클 (예) 500s의 지연이 필요한 경우 지연 정수 산출 6×R7+10을 얻고자 하는 지연 시간과 같다고 놓으면 6×R7+10=500에서 R7=82=52H므로 delay(0x52);로 하여 delay 함수를 호출하면 된다.

44 03. 유용한 프로그래밍 기법 3.2 무한 루프 사용 마이크로컨트롤러 시스템을 동작시키기 위한 사용자 프로그램은 무한 루프 구조로 작성하는 것이 일반적이다. 그 이유는 마이크로컨트롤러 시스템에서 는 대부분 운영체제를 사용하지 않으므로 프로그램 실행이 종료되면 되돌아 갈 곳이 없기 때문이다. 방법 1 프로그램의 주요부를 1회만 실행하고, 의미 없는 하나의 명령을 반복하여 실행함으로써 무한 루프에 빠지는 방법이다. P03_08.c #include <reg51.h> void main(void) { P1=0x55; // P1포트에 데이터 출력 P2=0xaa; // P2포트에 데이터 출력 while(1); }

45 03. 유용한 프로그래밍 기법 방법 2 프로그램의 주요부분을 무한히 반복하면서 무한 루프에 빠지도록 작성하는 방법이다. P03_09.c #include <reg51.h> sbit sw=P3^0; unsigned char led; void delay(unsigned int i) { while(i--); } void main(void) led=0xfe; do { P1=led; // 포트 1에 출력 led=(led<<1) | 0x01; // LED 상태 변경 if (led == 0xff) led=0xfe; delay(0xb100); // 약 0.5초 지연 } while(1);

46 03. 유용한 프로그래밍 기법 3.3 룩업 테이블 (Look-up table) 7-세그먼트 공통 캐소드 공통 애노드
룩업 테이블은 여러 경우에 사용되며, 예를 들어 BCD값을 7-세그먼트에 디 스플레이하는 경우에 사용 BCD 값 2진수 표시 16진수 표시 a b c d e f g dp 1 03H 9FH 2 25H 3 0DH 4 99H 5 49H 6 41H 7 1FH 8 01H 9 09H 7-세그먼트 공통 애노드 공통 캐소드

47 03. 유용한 프로그래밍 기법 P03_10.c #include <reg51.h> void main(void) {
unsigned char offset, segment; unsigned char table[10]={0x03,0x9f,0x25,0x0d,0x99, x49,0x41,0x1f,0x01,0x09}; offset=0x02; segment=table[offset]; }

48 03. 유용한 프로그래밍 기법 3.4 스위치 입력 바운싱(bouncing), 채터링(chattering) 현상 : 스위치를 누르거나 뗄 때 접 점 부분에서의 기계적 진동에 의해 출력 파형이 일정하지 않은 현상 이 현상 때문에 마이크로컨트롤러는 스위치가 여러 번 눌린 것으로 잘못 인식할 수 있으며, 이러한 진동은 최대 20ms 정도 지속 디바운싱(debouncing) : 마이크로컨트롤러가 올바른 스위치 입력 동작을 수행하기 위해 스위치 접점에서의 진동을 제거하는 것 기본적인 스위치 입력회로 스위치에서의 바운싱 현상

49 03. 유용한 프로그래밍 기법 디바운싱 방법(하드웨어) 디바운싱 방법(소프트웨어)
스위치가 눌리지 않으면 P1.0에는 Low가, 눌리면 High가 검출 스위치 개수가 많으면 회로 기판의 크기가 커지고 경제적인 부담 때문에 적용하기 어렵다. 디바운싱 방법(소프트웨어) 첫 번째 방법 : 1ms 간격으로 스위치 값을 읽어 5회 또는 10회 연속 같은 값이 나오면 스위치가 눌린 것으로 판단하는 것 두 번째 방법 : 시간 지연 루틴을 이용하는 것 슈미트 트리거를 이용한 스위치 입력 회로

50 03. 유용한 프로그래밍 기법 디바운싱(debouncing) 방법(소프트웨어, 두 번째 방법) P03_11.c
#include <reg51.h> sbit sw=P1^0; unsigned char led; void delay(unsigned int i) { while(i--); } void main(void) led=0xfe; // 초기 출력 데이터(P2.0에 연결된 LED만 on) do { P2=led; // 포트 2에 출력 led=(led << 1) | 0x01; // LED 상태 변경 if (led == 0xff) led=0xfe; while(sw!=0); // 스위치가 눌릴 때까지 대기 delay(0x0700); // 약 20ms 지연 while(sw==0); // 스위치가 떨어질 때까지 대기 } while(1);

51


Download ppt "3 8051을 위한 C 언어 프로그래밍."

Similar presentations


Ads by Google