STC89C52_51单片机_串口配置_UART串口通信
2020-06-27 来源:eefocus
寄存器配置
PCON电源管理寄存器
位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
– 模式 模式 模式1直接清零 使能串口接收 模式1接收停止位 发送标志位,软件清零 接受标志位,软件清0
//不能位寻址
SCON串口控制寄存器
位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
– 模式 模式 模式1直接清零 使能串口接收 模式1接收停止位 发送标志位,软件清零 接受标志位,软件清0
/* SCON */
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;
模式&波特率(宋雪松P183)
SCON主要用模式1,的波特率
对应的,要用定时器T1&T2的模式2
TH1 = TL1 = 256 - 晶振值/12/2/16/波特率
(256是TL1的溢出值,12指12个时钟周期,16是硬件因素)
SBUF
两个SBUF寄存器,分别负责接收和发送缓冲
流程
配置串口为模式1
配置定时器T1为模式2
根据波特率计算TH0&TL0的值
配置PCON&SCON寄存器
打开定时器
IO口模拟UART串口通信
UART串口传送数据示意图
挖坑:波特率&TH0是怎么算的?
#include sbit PIN_RXD = P3^0; sbit PIN_TXD = P3^1; bit RxdOrTxd = 0; bit RxdEnd = 0; bit TxdEnd = 0; unsigned char RxdBuf = 0; unsigned char TxdBuf = 0; void configUART(unsigned long baud); void startRXD(void); void startTXD(unsigned char dat); void main(void) { EA = 1; configUART(9600); while(1) { while(PIN_RXD); startRXD(); while(!RxdEnd); startTXD(RxdBuf+1); while(!TxdEnd); } } void configUART(unsigned long baud) { TMOD &= ~(0xF<<0); TMOD |= 0x1<<1; TH0 = 256 - (11059200 / 12) / baud; } void startRXD(void) { TL0 = 256 - ((256 - TH0) >> 1); ET0 = 1; TR0 = 1; RxdEnd = 0; RxdOrTxd = 0; } void startTXD(unsigned char dat) { TxdBuf = dat; TL0 = TH0; ET0 = 1; TR0 = 1; PIN_TXD = 0; RxdEnd = 0; RxdOrTxd = 1; } void timer0(void) interrupt 1 { static unsigned char cnt = 0; if(RxdOrTxd) { cnt++; if(cnt<=8) { PIN_TXD = TxdBuf & 0x01; TxdBuf >>= 1; } else if(cnt==9) { PIN_TXD = 1; } else { cnt = 0; TR0 = 0; TxdEnd = 1; } } else { if(cnt==0) { if(!PIN_RXD) { RxdBuf = 0; cnt++; } else { TR0 = 0; } } else if(cnt<=8) { RxdBuf >>= 1; if(PIN_RXD) { RxdBuf |= 0x80; } cnt++; } else { cnt = 0; TR0 = 0; if(PIN_RXD) { RxdEnd = 1; } } } } UART串口通信 教学版 #include void configUART(unsigned long baud); void main(void) { configUART(9600); while(!RI); RI = 0; SBUF = SBUF + 1; while(!TI); TI = 0; } void configUART(unsigned long baud) { SCON = 0x50; TH1 = 256 - (11059200 / 12 / 2 / 16) / baud; TL1 = TH1; TMOD &= ~(0xF<<4); TMOD |= 0x2<<4; ET1 = 0; TR1 = 1; } 工业版 #include void configUART(unsigned long baud); void main(void) { EA = 1; configUART(9600); while(1); } void configUART(unsigned long baud) { SCON = 0x50; TH1 = 256 - (11059200 / 12 / 2 / 16) / baud; TL1 = TH0; TMOD &= ~(0xF<<4); TMOD |= 0x2<<4; ET1 = 0; ES = 1; TR1 = 1; } void UART(void) interrupt 4 { if(RI) { RI = 0; SBUF = SBUF + 1; } if(TI) { TI = 0; } } 计算机发送数据,在数码管中显示 #include sbit wei = P2^7; sbit duan = P2^6; unsigned char code weitable[6] = { ~0x20,~0x10,~0x08,~0x04,~0x02,~0x01 }; unsigned char code duantable[16] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71 }; unsigned char ledbuff[6] = { 0x00,0x00,0x00,0x00,0x00,0x00 }; unsigned char T0RH = 0,T0RL = 0; unsigned char RxdByte = 0; void configtimer0(unsigned char ms); void configUART(unsigned long baud); void main(void) { EA = 1; configtimer0(1); configUART(9600); while(1) { ledbuff[0] = duantable[RxdByte & 0x0F]; ledbuff[1] = duantable[RxdByte >> 4]; } } void configtimer0(unsigned char ms) { unsigned long tmp; tmp = 11059200 / 12; tmp = (tmp * ms) / 1000; tmp = 65536 - tmp; tmp = tmp + 12; T0RH = (unsigned char)(tmp>>8); T0RL = (unsigned char)tmp; TH0 = T0RH; TL0 = T0RL; TMOD &= ~(0xF<<0); TMOD |= 0x1<<0; ET0 = 1; TR0 = 1; } void configUART(unsigned long baud) { TH1 = 256 - (11059200 / 12 / 2 / 16) / baud; TL1 = TH0; SCON = 0x50; TMOD &= ~(0xF<<4); TMOD |= 0x2<<4; ET1 = 0; ES = 1; TR1 = 1; } void ledscan(void) { static unsigned char i = 0; P0 = 0x00; duan = 1; duan = 0; P0 = weitable[i]; wei = 1; wei = 0; P0 = ledbuff[i]; duan = 1; duan = 0; if(i<5) i++; else i = 0; } void timer0(void) interrupt 1 { TH0 = T0RH; TL0 = T0RL; ledscan(); } void UART(void) interrupt 4 { if(RI) { RI = 0; RxdByte = SBUF; SBUF = RxdByte; } if(TI) { TI = 0; } }