533104334ff1f25feb7e9539fd3f811d.ppt
- Количество слайдов: 37
8051 Serial 통신 l Mode 0 : 동기 통신 l Mode 1, 2, 3 : 비동기 통신 dolicom@naver. com http: //blog. naver. com/dolicom
통신 시 동시에 보내는 데이터 비트수 l 패럴럴 통신 (Parallel) ¡ 두 지점 간 데이터 시 데이터 연결 수가 많다. l 8비트를 많이 사용 l LPT(Printer), SCSI(HDD), ATAPI(HDD) ¡ 데이터의 비트수가 많아 여러 선이 필요하므로 원거리 통신에 불리 ¡시리얼이 고속 통신이 가능하여 사용이 주는 추세 l 시리얼 통신 (Serial) ¡ 동시에 보내는 데이터 수는 하나 ¡ 패럴럴에 비해 원거리 전송에 유리 l 현재는 고속으로 전송으로 거리 제한(SATA, USB) ¡ 패럴럴에 비해 저속이었으나 현재 고속이 가능 ¡ UART, SPI, I 2 C, USB, SATA(HDD), Serial-SCSI
시리얼통신 데이터 사이 분리 방식 l 동기식 통신 ¡ ¡ 전송 후 데이터 사이 구별을 데이터 클럭 사용 별도의 데이터 클럭 신호 필요 비교적 고속 전송, 가까운 거리 - 칩간 통신 SPI, I 2 C l 비동기식 통신 ¡ ¡ 전송 후 데이터 사이를 수신 쪽에서 구별 별도의 데이터 클럭이 필요 없음 비교적 저속 전송 속도, 원거리 장치간 통신 ( PC – PC, PC - 전자 장치)
UART (RS-232 C) l l l 두 지점 간 비동기 시리얼 통신 CPU의 초기부터 사용 데이터 수 5, 6, 7, 8로 설정 가능 에러 탐색을 위한 EVEN/ODD parity 사용 비교적 간단한 통신 방식, 속도 낮음, 원거리 ¡ BAUD RATE (BPS와 비슷함) l 전송 라인은 디지털 전압보다 높음 – 원거리 전송 ¡ Mark (1) : -3 ~ -12 V ¡ SPACE (0) : +3 ~ +12 V ¡ 높은 전압 필요
SPI Serial Peripheral Interface
I 2 C 수신 측에서 데이터 수신여부 확인하기 위 해 송신 측에서는 1로 하고 수신 측에서 ACK 신호를 출력 한다. SCL이 1일 때 SDA가 1에서 0으로 변하면 송신 시작
RS-232 C 타이밍 차트 5, 6, 7, 8 비트 0 x 58 전송 예 EVEN, ODD 1, 1. 5 비트
윈도우 설정
RS-232 C의 전압 특성 MARK : -3 ~-12 V SPACE : +3 ~ +12 V TX UART 모듈 CPU RX MAX 232 : 5 V <-> -10~+10 V MAX 3232: 3. 3 V <-> -10~+10 V 자체 전원 변환 회로 추가 되어 별도의 파워 전환 필요 없음 커넥터 DS 9
USART 신호 Signal Name Origin Abbreva tion DTE DCE DB-25 (TIA-574) EIA/TIA 561 Yost 4, 5 DE-9 Common Ground G 7 5 4 Protective Ground PG 1 - - Transmitted Data Tx. D 2 3 6 3 Received Data Rx. D 3 2 5 6 Data Terminal Ready DTR 20 4 3 2 Data Set Ready DSR 6 6 1 7 Request To Send RTS 4 7 8 1 Clear To Send CTS ● 5 8 7 8 Carrier Detect DCD ● 8 1 2 7 Ring Indicator RI ● 22 9 1 - ● ● ●
모뎀 제어 신호 모뎀은 우선 전화등을 이용 통신 채널을 열어야 하기 때문에 바로 옆에 있는 컴 퓨터 처럼 사용할 수 없다. 따라서 모뎀이 통신채널을 열었는지 확 인할 필요가 있다.
clock Serial 관련 레지스터
TMOD 레지스터 7 6 GATE C/T 5 M 1 Timer 1 4 3 2 M 0 GATE C/T 1 0 M 1 M 0 Timer 0 § GATE : 외부 인터럽트 핀(INT 1, INT 0)을 이용해서, 타이머를 정지/동 작을 제어 한다. 1. GATE=1, TR 0=1 : INT 0=1 – 타이머 0 동작, INT 0 – 정지 GATE=1, TR 1=1 : INT 1=1 – 타이머 1 동작, INT 1 – 정지 2. GATE=0 : INT 0, INT 1 핀을 사용하지 않으며, TCON내의 TR 0, TR 1 에 따라 동작/정지 된다. § C/T (Counter/Timer selector) : 카운터/타이머 모드를 결정 1. C/T=1 : 카운터 모드 – 입력 핀 T 0, T 1에서 들어오는 펄스를 센다. C/T=0 : 타이머 모드 – 시스템 클럭/12을 센다. § M 1: M 0 : 동작 모드 설정 4가지 모드
TCON 레지스터 7 6 5 4 3 2 1 0 TF 1 TR 1 TF 0 TR 0 IE 1 IT 1 IE 0 IT 0 Timer 1 Timer 0 Interrupt • TR 1/TR 0 : 타이머/카운터 동작/정지 제어 한다. TR 0=1 : 타이머/카운터 0 동작 TR 0=0 : 타이머/카운터 0 정지 • TF 1/TF 0 : 타이머/카운터 오버플로 플래그 TF 0 : 타이머/카운터 0의 카운터 레지스터(TH 1, TH 0)가 오버플로가 되면 셋된다. *이 때 다음과 같이 인터럽트 처리 된다. . - 인터럽트 인에이블되어 있고 - 인터럽트 요청하게 되면 - 인터럽트 처리가 끝나면 자동으로 클리어 된다
T 2 CON 레지스터 0 x. C 8 7 TF 2 6 5 4 3 2 EXF 2 RCLK TCLK EXEN 2 TR 2 1 0 CP/T 2 CP/RL 2 § TF 2 : Overflow가 되면 1로 되고 SW로 지움. RCLK/TCLK=1이면 동작 안 함. § EXF 2 : Capture/Reload일 때, T 2 EX가 오면 1로 됨. EXEN 2=1일 때 동작. - 인터럽트 요청 EXF 2=1이면 Timer 2 Vector로 처리-인터럽트 루틴 실행. - DCEN=1로 Up/Down Counter Mode에서 동작 안함. § RCLK : Serial Mode 1/3에서 Receive clock으로 사용. § TCLK : Serial Mode 1/3에서 Transmit clock으로 사용. § EXEN 2 : Timer 2 External 동작. § TR 2 : Timer 2의 동작 시작/멈춤 설정. § CP/T 2 : Timer / Counter(외부 입력 사용) 설정. § CP/RL 2 : Capture/Reload 선택.
Timer 2의 동작 모드 – T 2 CON TR 2 TCLK/RCLK CP/RL 2 T 2 OE 1 0 0 0 16비트 Auto-Reload 모드 1 0 16비트 Capture 모드 1 1 x x 16비트 Baud Rate 발생 모드 1 x x 1(C/T=0) 0 x x x 모드 16비트 Programmable Clock-Out모드 타이머 2 동작 OFF
SCON 레지스터 - 1 7 6 5 4 SM 0 SM 1 SM 2 REN 3 2 1 0 TB 8 RB 8 TI RI § RI : 수신완료 및 인터럽트 요청플래그 0 -수신없음, 1 -수신완료 § TI : 송신완료 및 인터럽트 요청플래그 0 -송신없음 또는 송신중, 1 -수신완료 § RB 8 : Mode 2, 3시 수신 9번째 데이터 비트 § TB 8 : Mode 2, 3시 송신 할, 9번째 데이터 비트 § REN : 수신가능 제어비트 0 -수신 불가, 1 -수신가능
SCON 레지스터 - 2 7 6 5 4 SM 0 SM 1 SM 2 REN 3 2 1 0 TB 8 RB 8 TI RI § SM : 시리얼의 동작 상태 정의 Mode : SM 0 SM 1 0 00 1 01 2 10 3 11 동작 Shift Register 8비트 UART 9비트 UART Baud Rate (속도) fosc/12 변화 fosc/12 또는 fosc/32 변화 § SM 2 : 모드 2, 3에서 멀티통신 관련 비트 0 - 싱글 통신 기능으로 동작함. 1 - 수신데이터 비트(RB 8)가 1인 경우만 RI 비트를 세트시켜 8051 코어로 하여금 수신을 가능하도록 함. 즉, 데이터 수신이 가능함.
SMOD – PCON 레지스터 7 SMOD 6 5 4 3 2 - - - GP 1 GP 0 1 0 *PD *ILD § SMOD : 시리얼 클럭 타이머 0 사용할 때 시리얼포트의 기준클록 입력소스인 타이머 0의 출력 펄스와 2분주된 시스템 클록을 다시 2분주할 것인지 선택하는 비트 0 – 타이머 1 클럭 / 2 : 2분주 함 1 – 타이머 1의 그대로 사용 § GP 1 : 보통목적(General Purpose) 플래그 비트 § GP 0 : 보통목적(General Purpose) 플래그 비트
clock Serial 클럭 발생 타이머
비동기 수신 인식 – HW로 처리 MARK SPACE § 데이터 신호가 MARK에서 SPACE로 가면 수신 시작 § 전송하는 한 비트에 16/64개의 사이클을 사용하여 수신 시작 § MARK에서 0으로 바뀌는 순간 부터 16 사이클 마다 비트를 분리 § 데이터 비트 사이를 이 클럭을 사용하여 시간을 구별 § 16개의 주기가 끝나면 무조건 다음 데이터로 인식
타이머를 사용한 UART 클럭 발생 XTAL oscillator ÷ 2 ÷ 12 Timer 1/2 RX/TX CLOCK
타이머을 사용한 클럭 발생 구조 C/T = 0 TM 1 Overflow TL 1 8 bits C/T = 1 1 OSC ÷ 12 T 1 pin ÷ 2 TR 1 ÷ 2 “ 0” TH 1 SMOD C/T = 0 T 2 pin TR 2 TL 2 8 bits C/T = 1 “ 1” TH 2 8 bits “ 0” RCLK 1 “ 1” RELOAD RCAP 2 L “ 1” RCAP 2 H “ 0” ÷ 16 RX CLOCK TCLK ÷ 16 TX CLOCK
SCON: SM 1=1 Serial Mode 1, 3 -Timer 1 Mode 2 PMOD[1: 0]: M 1 M 0=10 PMOD[2]: C/T=0 C/T = 0 TL 1 8 bits C/T = 1 OSC ÷ 12 T 1 pin 1 ÷ 2 RELOAD TCON: TR 1 ÷ 2 PCON TM 1 Overflow “ 0” TH 1 T 2 pin C/T = 1 “ 1” TH 2 8 bits RELOAD RCAP 2 L “ 0” T 2 CON: RCLK=0 RCLK “ 1” TR 2 “ 1” SMOD C/T = 0 TL 2 8 bits PCON: SMOD RCAP 2 H “ 0” ÷ 16 RX CLOCK TCLK ÷ 16 T 2 CON: TCLK=0 TX CLOCK
Serial Mode 1, 3 -Timer 2 Baud. Rate C/T = 0 C/T = 1 OSC ÷ 12 T 1 pin ÷ 2 TM 1 Overflow TL 1 8 bits ÷ 2 TR 1 “ 0” TH 1 PMOD[6]: C/T=0 SMOD T 2 CON: RCLK/TCLK=1 C/T = 0 T 2 pin TL 2 8 bits C/T = 1 “ 1” TH 2 8 bits “ 0” “ 1” RELOAD RCAP 2 L T 2 CON: RCLK=1 RCLK 1 TCON: TR 2 “ 1” RCAP 2 H “ 0” ÷ 16 RX CLOCK TCLK ÷ 16 T 2 CON: TCLK=1 TX CLOCK
Baud Rate 설정 Saud Rate fosc SMOD C/T Mode Reload Value Mode 0 Max: 1 MHZ 12 MHz X X Mode 2 Max: 375 K 12 MHz 1 X X X Modes 1, 3: 12 MHz 1 0 2 FFH 19200 11. 059 MHz 1 0 2 FDH 9600 11. 059 MHz 0 0 2 FDH 4800 11. 059 MHz 0 0 2 FAH 2400 11. 059 MHz 0 0 2 F 4 H 1200 11. 059 MHz 0 0 2 E 8 H 137. 5 11. 059 MHz 0 0 2 1 DH 110 6 MHz 0 0 2 72 H 62500
Serial 전송 모드 l 모드 0 ¡ 데이터의 시간 위치를 알리는 동기식. l Rx. D : Data In/Out으로 사용 l Tx. D : 데이터 클럭으로 사용 l 모드 1 ¡ 비동기 방식 – 데이터 만 사용(8 bit) - UART ¡ 에러 체크를 위한 Parity가 없다. l 모드 2/3 ¡ 비동기 방식 – 데이터(8 bit)+특수 1비트 – UART l SCON레지스터의 TB 8/RB 8비트를 CPU에서 설정 l 에러 체크를 위한 parity는 8051의 P을 TB 8에 전송
통신모드 0–동기전송 (SPI와 유사) SBUF에 송신 데이터 쓰기 Transmit SCOC에 쓰기(RI 지워짐) Receive
통신모드 1 – 비동기 전송 SBUF에 송신 데이터 쓰기 Transmit SCOC에 쓰기(RI 지워짐) Receive Parity 불가능
통신모드 2, 3(가변속도만 다름) Transmit Receive
Program Serial 프로그램
// file : uart. h #ifndef _UART_H #define _UART_H void Init_Serial. Tm(void) ; // Serial & Timer 초기화 void putchar(char ch); UART #endif #include <reg 8051. h> void putchar(char ch) { while (!TI); //시리얼 버퍼 SBUF가 비어질 때까지 대기 SBUF = ch; TI =0; } //////////////////////////// // Serial & Timer 초기화 void Init_Serial. Tm(void) { TMOD = 0 x 20; // 타이머 1 : 모드 2, 내부클럭사용 } PCON = 0 x 00; TH 1 = 0 xfd; SCON = 0 x 50; SBUF = 0; TR 1 = 1; // 만약에 19200보레이트인경우 SMOD =1 // 9600 보레이트로 사용 // 시리얼통신모드 1 사용 // 초기값을 0설정(쓰레기값 방지) // Timer 1 run #include <stdio. h> #include “uart. h” void main(void) { BYTE i, c; Init_Serial. Tm(); putchar(‘*’); // 초기화 while(1) { putchar(‘. ’); //데이터송신 delay(2); P 1= c; // Port 1 출력 } } void delay(int p) { int i, j; for(j=0; j<p; j++) for(i=0; i<1000; i++); }
#ifndef _UART_H #define _UART_H UART void Init_Serial. Tm(void) ; // Serial & Timer 초기화 void putchar(char ch); BYTE getchar(); #endif #include <reg 8051. h> typedef unsigned char BYTE; void Init_Serial. Tm(void) // Serial & Timer 초기화 { TMOD = 0 x 20; // 타이머 1 : 모드 2, 내부클럭사용 } PCON = 0 x 00; TH 1 = 0 xfd; SCON = 0 x 50; SBUF = 0; TR 1 = 1; // 만약에 19200보레이트인경우 SMOD =1 // 9600 보레이트로 사용 // 시리얼통신모드 1 사용 // 초기값을 0설정(쓰레기값 방지) // Timer 1 run void putchar(char c) { while (!TI); //시리얼 버퍼 SBUF가 비어질 때까지 대기 SBUF = c; TI =0; } BYTE getchar() { BYTE ch; while(!RI); // 수신 버퍼 ch = SBUF; RI=0; return ch; } #include <stdio. h> #include “uart. h” void main(void) { BYTE ch, cnt; Init_Serial. Tm(); putchar(‘*’); // 초기화 while(1) { ch= getchar(); // 데이터 수신 cnt++; // 수신 데이터 1증가 P 1 = cnt; // LED에 데이터 표시 putchar(ch); // 데이터 송신 } } void delay(int p) { int i, j; for(j=0; j<p; j++) for(i=0; i<1000; i++); }
#ifndef _UART_H #define _UART_H UART void Init_Serial. Tm(void) ; // Serial & Timer 초기화 void putchar(char ch); #endif #include <reg 8051. h> void Init_Serial. Tm(void) // Serial & Timer 초기화 { TMOD = 0 x 21; // 타이머 1 : 모드 2, 내부클럭사용 // 타이머 0 : mode 1, 내부 클럭사용 PCON = 0 x 00; // 만약에 19200보레이트인경우 SMOD =1 TH 1 = 0 xfd; // 9600 보레이트로 사용 SCON = 0 x 50; // 시리얼통신모드 1 사용 SBUF = 0; // 초기값을 0설정(쓰레기값 방지) TR 1 = 1; // Timer 1 run } void putchar(char ch) { while (!TI); //시리얼 버퍼 SBUF가 비어질 때까지 대기 SBUF = ch; TI =0; } // 시리얼 포트의 인터럽트 벡터 void Rx. Uart(void) interrupt 4 { BYTE ch; EA = 0; // 모든 인터럽트 디스인에이블(disable) } if (RI) { g_u. Ch = SBUF; RI = 0; SBUF = g_u. Ch; } EA = 1; //모든 인터럽트 인에이블(enable) #include <reg 8051. h> #include “uart. h” BYTE g_u. Ch; // UART 수신 문자 BYTE g_Rx. Flag; // 수신이 되었는지를 나타냄 unsigned int g_tm. Count; // Timer 0 인터럽트에 의해 1 증가 void main(void) { BYTE cnt; Init_Serial. Tm(); g_tm. Count = 0; cnt = 0; putchar(‘*’); // 초기화 } TR 0 = 1; // 타이머 0 실행 ET 0 = 1; // 타이머 0인터럽트 인에이블( enable) EA = 1; while(1) { if (g_Rx. Flag) { putchar(g_u. Ch); //데이터송신 g_Rx. Flag = 0; } if (g_tm. Count & 0 x. FF 00) { P 1= cnt++; // Port 1 출력 } } // 타이머 0 오버풀로워( Overflow) void intr. Tm 0(void) interrupt 1 { TR 0 = 0; // 타이머 0 정지 TH 0 = 0 xf 7; // 인터럽트 기간을 2 ms ? 2170 TL 0 = 0 x 86; //11. 0592 M/12=0. 9216 us-RELOAD g_tm. Count ++; TR 0 = 1; // 타이머 0을 다시 시작 }
#include <stdio. h> void main(void) { unsigned int cnt; } void Init_Uart(void) { SCON = 0 x 40; // mode 1, 8 -bit UART, disable rcvr TMOD = 0 x 20; // timer 1, mode 2, 8 -bit reload PCON &= 0 x 7 f; // SMOD = 0 TH 1 = 0 xfd; // reload value for 19, 200 baud TR 1 = 1; // timer 1 run TI = 1; // set TI to send first char of UART } Init_Uart(); printf(“Hellon”); putchar(‘O’); putchar(‘K’); putchar(‘n’); cnt = 0; while(1) { if (! (cnt & 0 x 0 FFF)) printf("%d ", cnt); cnt++; }
TX Interrupt 예 #include <reg 8051. h> void Init_Serial. Tm(void) // Serial & Timer 초기화 { TMOD = 0 x 20; // 타이머 1 : 모드 2 PCON = 0 x 80; // 19200인경우 SMOD =1 TH 1 = 0 xfd; // 19200 SCON = 0 x 52; // 시리얼통신모드 1 사용 SBUF = 0; // 초기값을 0설정(쓰레기값 방지) ES = 1; // IE – ES: Serial. Porfinterruptenablebit TR 1 = 1; // Timer 1 run } void putchar(char ch) { while (!TI); //시리얼 버퍼 SBUF가 비어질 때까지 대기 SBUF = ch; TI =0; } // 시리얼 포트의 인터럽트 벡터 void Uart_ISR(void) interrupt 4 { BYTE ch; } SBUF = buffer[g_su. Cnt]; delay(50); TI = 0; if (buffer[g_su. Cnt +] =='₩ 0') g_su. Cnt = 0; #include <stdio. h> #include “uart. h” int g_su. Cnt; char buffer[] = “ 8051 serial₩r₩n"; void main(void) { BYTE i, c; Init_Serial. Tm(); EA = 1; putchar(‘*’); // 초기화 while(1) { putchar(‘. ’); //데이터송신 delay(2); P 1= c; // Port 1 출력 } } void delay(unsigned int k) // delay function { while (k--) ; }
533104334ff1f25feb7e9539fd3f811d.ppt