8051 Serial 통신 Mode 0 : 동기통신 Mode 123 1,2,3 : 비동기통신 dolicom@naver.com http://blog.naver.com/dolicom /d li
통신시동시에보내는데이터비트수 패럴럴통신 (Parallel) 두지점간데이터시데이터연결수가많다. 8비트를많이사용 LPT(Printer), SCSI(HDD), ATAPI(HDD) 데이터의비트수가많아여러선이필요하므로원거리통신에불리 시리얼이고속통신이가능하여사용이주는추세 시리얼통신 (Serial) 동시에보내는데이터수는하나 패럴럴에비해원거리전송에유리 현재는고속으로전송으로거리제한 (SATA, USB) 패럴럴에비해저속이었으나현재고속이가능 UART, SPI, I2C, USB, SATA(HDD), Serial-SCSI
시리얼통신데이터사이분리방식 동기식통신 전송후데이터사이구별을데이터클럭사용 별도의데이터클럭신호필요 비교적고속전송, 가까운거리 - 칩간통신 SPI, I2C 비동기식통신 전송후데이터사이를수신쪽에서구별 별도의데이터클럭이필요없음 비교적저속전송속도, 원거리 장치간통신 ( PC PC, PC - 전자장치 )
UART (RS-232C) 두지점간비동기시리얼통신 CPU 의초기부터사용 데이터수 5678 5,6,7,8 로설정가능 에러탐색을위한 EVEN/ODD parity 사용 비교적간단한통신방식, 속도낮음, 원거리 BAUD RATE (BPS 와비슷함 ) 전송라인은디지털전압보다높음 원거리전송 Mark (1) : -3 ~ -12 V SPACE (0) : +3 ~ +12V 높은전압필요
SPI Serial Peripheral Interface
I2C 수신측에서데이터수신여부확인하기위해송신측에서는 1 로하고수신측에서 ACK 신호를출력한다. SCL 이 1 일때 SDA 가 1 에서 0 으로변하면송신시작
RS-232C 타이밍차트 5678 5,6,7,8 비트 EVEN,ODD 1, 15 1.5 비트 0x58 전송예
윈도우설정
RS-232C 의전압특성 MARK : -3 ~-12 V SPACE : +3 ~ +12V UART 모듈 TX RX CPU MAX232 : 5V <-> -10~+10V MAX3232: 3.3V <-> -10~+10V 자체전원변환회로추가되어별도의파워전환필요없음 커넥터 DS9
USART 신호 Name Signal Abbreva tion DTE Origin DCE DB-25 DE-9 (TIA-574) EIA/TIA 561 Yost Common Ground G 7 5 4 45 4,5 Protective Ground PG 1 - - Transmitted Data TD TxD 2 3 6 3 Received Data RxD 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 5 4 3 2 1 0 GATE C/T M1 M0 GATE C/T M1 M0 Timer 1 Timer 0 GATE : 외부인터럽트핀 (INT1, INT0) 을이용해서, 타이머를정지 / 동작을제어한다. 1. GATE=1, TR0=1 : INT0=1 타이머0 동작, INT0 정지 GATE=1, TR1=1 1 : INT1=1 1 타이머 1 동작, INT1 정지 2. GATE=0 : INT0,INT1 핀을사용하지않으며, TCON내의 TR0, TR1에따라동작 / 정지된다. C/T (Counter/Timer selector) : 카운터 / 타이머모드를결정 1. C/T=1 : 카운터모드 입력핀T0, T1에서들어오는펄스를센다. C/T=0 : 타이머모드 시스템클럭 /12을센다. M1:M0 : 동작모드설정 4가지모드
TCON 레지스터 7 6 5 4 3 2 1 0 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 Timer 1 Timer0 Interrupt TR1/TR0 : 타이머 / 카운터동작 / 정지제어한다. TR0=1 : 타이머 / 카운터 0 동작 TR0=0 : 타이머 / 카운터 0 정지 TF1/TF0 : 타이머 / 카운터오버플로플래그 TF0 : 타이머 / 카운터 0 의카운터레지스터 (TH1, TH0) 가오버플로가되면셋된다. * 이때다음과같이인터럽트처리된다.. - 인터럽트인에이블되어있고 - 인터럽트요청하게되면 - 인터럽트처리가끝나면자동으로클리어된다
T2CON 레지스터 0xC8 7 6 5 4 3 2 1 0 TF2 EXF2 RCLK TCLK EXEN2 TR2 CP/T2 CP/RL2 TF2 : Overflow가되면 1로되고 SW로지움. RCLK/TCLK=1이면동작안함. EXF2 : Capture/Reload 일때,T2EX 가오면 1로됨. EXEN2=1 일때동작. - 인터럽트요청 EXF2=1이면 Timer2 Vector로처리-인터럽트루틴실행. - DCEN=1로 Up/Down Counter Mode에서동작안함. RCLK : Serial Mode1/3에서 Receive clock으로사용. TCLK : Serial Mode1/3에서 Transmit clock으로사용. EXEN2 : Timer2 External 동작. TR2 : Timer2의동작시작 / 멈춤설정. CP/T2 : Timer / Counter( 외부입력사용 ) 설정. CP/RL2 : Capture/Reload 선택.
Timer2 의동작모드 T2CON TR2 TCLK/RCLK CP/RL2 T2OE 모드 1 0 0 0 16 비트 Auto-Reload 모드 1 0 1 0 16 비트 Capture 모드 1 1 x x 16 비트 Baud Rate 발생모드 1 x x 1(C/T=0) 16 비트 Programmable Clock-Out 모드 0 x x x 타이머 2 동작 OFF
SCON 레지스터 - 1 7 6 5 4 3 2 1 0 SM0 SM1 SM2 REN TB8 RB8 TI RI RI : 수신완료및인터럽트요청플래그 0- 수신없음, 1- 수신완료 TI : 송신완료및인터럽트요청플래그 0-송신없음또는송신중, 1-수신완료 RB8 : Mode 2,3 시수신 9 번째데이터비트 TB8 : Mode 2,3 시송신할, 9 번째데이터비트 REN : 수신가능제어비트 REN : 수신가능제어비트 0- 수신불가, 1- 수신가능
SCON 레지스터 - 2 7 6 5 4 3 2 1 0 SM0 SM1 SM2 REN TB8 RB8 TI RI SM : 시리얼의동작상태정의 Mode : SM0 SM1 동작 Baud Rate ( 속도 ) 0 00 Shift Register fosc/12 1 01 8비트 UART 변화 2 10 9 비트 UART fosc/12 또는 fosc/32 3 11 9비트 UART 변화 SM2 : 모드23 2,3 에서멀티통신관련비트 0 - 싱글통신기능으로동작함. 1 - 수신데이터비트 (RB8) 가 1 인경우만 RI 비트를세트시켜 8051 코어로하여금수신을가능하도록함. 즉, 데이터수신이가능함.
SMOD PCON 레지스터 7 6 5 4 3 2 1 0 SMOD - - - GP1 GP0 *PD *ILD SMOD : 시리얼클럭타이머 0 사용할때 시리얼포트의기준클록입력소스인타이머 0 의출력펄스와 2 분주된시스템클록을다시 2분주할것인지선택하는비트 0 타이머1 클럭 / 2 : 2분주함 1 타이머 1 의그대로사용 GP1 : 보통목적 (General Purpose) 플래그비트 GP0 : 보통목적 (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 C/T = 1 TL1 8bits TM1 Overflow OSC 12 T1 pin 2 1 TR1 TH1 2 0 1 SMOD C/T = 0 T2 pin C/T = 1 TR2 1 TL2 8bits TH2 8bits RELOAD 1 0 1 0 RCLK 16 TCLK RX CLOCK RCAP2L RCAP2H 16 TX CLOCK
SCON:SM1=1 Serial Mode1,3-Timer1 Mode2 OSC 2 PMOD[2]:C/T=0 C/T = 0 C/T = 1 12 T1 pin 1 TCON:TR1 PMOD[1:0]:M1M0=10 TL1 8bits TH1 RELOAD TM1 Overflow PCON 2 PCON:SMOD 0 1 SMOD T2 pin TR2 C/T = 0 C/T = 1 TL2 8bits TH2 8bits RELOAD 1 0 T2CON:RCLK=0 1 0 RCLK 16 TCLK RX CLOCK RCAP2L RCAP2H 16 TX CLOCK T2CON:TCLK=0
Serial Mode1,3-Timer2 BaudRate C/T = 0 C/T = 1 TL1 8bits TM1 Overflow OSC 12 2 T1 pin PMOD[6]:C/T=0 C/T = 0 T2 pin C/T = 1 TCON:TR2 TR1 TH1 T2CON:RCLK/TCLK=1 TL2 8bits TH2 8bits 2 0 1 RCLK SMOD 1 0 T2CON:RCLK=1 1 RX 16 CLOCK 1 0 RELOAD TCLK RCAP2L RCAP2H 16 T2CON:TCLK=1 TX CLOCK
Baud Rate 설정 Saud Rate fosc SMOD C/T Mode Reload Value Mode0 Max: 1MHZ 12MHz X X X X Mode2 Max: 375K 12MHz 1 X X X Modes1,3: 62500 12MHz 1 0 2 FFH 19200 11.059MHz 1 0 2 FDH 9600 11.059MHz 0 0 2 FDH 4800 11.059MHz 0 0 2 FAH 2400 11.059MHz 0 0 2 F4H 1200 11.059MHz 0 0 2 E8H 137.5 11.059MHz 0 0 2 1DH 110 6MHz 0 0 2 72H
Serial 전송모드 모드 0 데이터의시간위치를알리는동기식. 모드 1 RxD :DataIn/Out 으로사용 TxD : 데이터클럭으로사용 비동기방식 데이터만사용 (8bit) - UART 에러체크를위한 Parity가없다. 모드 2/3 비동기방식 데이터 (8bit)+ 특수 1비트 UART SCON 레지스터의 TB8/RB8 비트를 CPU 에서설정 에러체크를위한 parity 는 8051 의 P 을 TB8 에전송
통신모드0 동기전송 (SPI 와유사 ) SBUF 에송신데이터쓰기 Transmit SCOC 에쓰기 (RI 지워짐 ) Receive
통신모드 1 비동기전송 Parity 불가능 SBUF 에송신데이터쓰기 Transmit SCOC 에쓰기 (RI 지워짐 ) Receive
통신모드 2, 3( 가변속도만다름 ) Transmit Receive
Program Serial 프로그램
// file : uart.h #ifndef _UART_H #define _UART_H void Init_ SerialTm(void) ; // Serial & Timer 초기화 void putchar(char ch); UART #endif #include <reg8051.h> #include <stdio.h> #include uart.h void putchar(char ch) void main(void) while (!TI); // 시리얼버퍼 SBUF 가비어질때까지대기 SBUF = ch; BYTE i,c; TI =0; Init_SerialTm(); putchar( * ); // 초기화 //////////////////////////////////////////////////////// // Serial & Timer 초기화 void Init_SerialTm(void) TMOD = 0x20; // 타이머1 : 모드2, 내부클럭사용 PCON = 0x00; // 만약에 19200보레이트인경우 SMOD =1 TH1 = 0xfd; // 9600 보레이트로사용 SCON = 0x50; // 시리얼통신모드1 사용 SBUF = 0; // 초기값을 0설정 ( 쓰레기값방지 ) TR1 = 1; // Timer1 run while(1) putchar(. ); // 데이터송신 delay(2); P1= c; // Port1 출력 void delay(int p) int ij; i,j; for(j=0;j<p;j++) for(i=0;i<1000;i++);
#ifndef _UART_H #define _UART_H void Init_SerialTm(void) ; // Serial & Timer 초기화 void putchar(char ch); BYTE getchar(); th UART #endif #include <reg8051.h> typedef unsigned char BYTE; void Init_SerialTm(void) // Serial & Timer 초기화 TMOD = 0x20; // 타이머 1 : 모드 2, 내부클럭사용 PCON = 0x00; // 만약에 19200보레이트인경우 SMOD =1 TH1 = 0xfd; // 9600 보레이트로사용 SCON = 0x50; // 시리얼통신모드1 사용 SBUF = 0; // 초기값을 0설정 ( 쓰레기값방지 ) TR1 = 1; // Timer1 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_SerialTm(); putchar( * ); // 초기화 while(1) ch= getchar(); // 데이터수신 cnt++; // 수신데이터 1증가 P1 = cnt; // LED에데이터표시 putchar(ch); // 데이터송신 void delay(int p) int ij i,j; for(j=0;j<p;j++) for(i=0;i<1000;i++);
#ifndef _UART_H #define _UART_H UART void Init_SerialTm(void) ; // Serial & Timer 초기화 void putchar(char ch); #endif #include <reg8051.h> void Init_SerialTm(void) // Serial & Timer 초기화 TMOD = 0x21; // 타이머1 : 모드2, 내부클럭사용 // 타이머0 : mode 1, 내부클럭사용 PCON = 0x00; // 만약에 19200보레이트인경우 SMOD =1 TH1 = 0xfd; // 9600 보레이트로사용 SCON = 0x50; // 시리얼통신모드1 사용 SBUF = 0; // 초기값을 0설정 ( 쓰레기값방지 ) TR1 = 1; // Timer1 run void putchar(char ch) while (!TI); // 시리얼버퍼 SBUF가비어질때까지대기 SBUF = ch; TI =0; // 시리얼포트의인터럽트벡터 void RxUart(void) interrupt 4 BYTE ch; EA = 0; // 모든인터럽트디스인에이블 (disable) if (RI) g_uch = SBUF; RI = 0; SBUF = g_uch; EA = 1; // 모든인터럽트인에이블 (enable) #include <reg8051.h> #include uart.h BYTE g_uch; // UART 수신문자 BYTE g_ RxFlag; // 수신이되었는지를나타냄 unsigned int g_tmcount; // Timer0 인터럽트에의해 1 증가 void main(void) BYTE cnt; Init_SerialTm(); g_tmcount = 0; cnt = 0; putchar( * ); // 초기화 TR0 = 1; // 타이머0 실행 ET0 = 1; // 타이머0인터럽트인에이블 ( enable) EA = 1; while(1) if (g_rxflag) putchar(g_uch); // 데이터송신 g_rxflag = 0; if (g_tmcount t & 0xFF00) P1= cnt++; // Port1 출력 // 타이머 0 오버풀로워 ( Overflow) void intrtm0(void) interrupt 1 TR0 = 0; // 타이머0 정지 TH0 = 0xf7; // 인터럽트기간을 2ms? 2170 TL0 = 0x86; //11.0592M/12=0.9216us-RELOAD g_tmcount ++; TR0 = 1; // 타이머0을다시시작
#include <stdio.h> void main(void) unsigned int cnt; void Init_Uart(void) SCON = 0x40; // mode 1, 8-bit UART, disable rcvr TMOD = 0x20; // timer 1, mode 2, 8-bit reload PCON &= 0x7f; // SMOD = 0 TH1 = 0xfd; // reload value for 19,200 baud TR1 = 1; // timer 1 run TI = 1; // set TI to send first char of UART Init_Uart(); printf( Hello\n ); putchar( O ); putchar( K ); putchar( \n ); cnt = 0; while(1) if (! (cnt & 0x0FFF)) printf("%d ", cnt); cnt++;
TX Interrupt 예 #include <reg8051.h> void Init_SerialTm(void) // Serial & Timer 초기화 TMOD = 0x20; // 타이머1 : 모드2 PCON = 0x80; // 19200인경우 SMOD =1 TH1 = 0xfd; // 19200 SCON = 0x52; // 시리얼통신모드 1 사용 SBUF = 0; // 초기값을 0설정 ( 쓰레기값방지 ) ES = 1; // IE ES:SerialPorfinterruptenablebit TR1 = 1; // Timer1 run void putchar(char ch) while (!TI); // 시리얼버퍼 SBUF가비어질때까지대기 SBUF = ch; TI =0; // 시리얼포트의인터럽트벡터 void Uart_ISR(void) interrupt 4 BYTE ch; SBUF = buffer[g_sucnt]; delay(50); TI = 0; if (buffer[g_sucnt +] ==' 0') g_sucnt = 0; #include <stdio.h> #include uart.h int g_sucnt; char buffer[] = 8051 serial r n"; void main(void) BYTE i,c; Init_SerialTm(); EA = 1; putchar( * ); // 초기화 while(1) putchar(. ); // 데이터송신 delay(2); P1= c; // Port1 출력 void delay(unsigned int k) // delay function while (k--) ;