串口通信
-
串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。
-
单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。
-
51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。
-
简单双向串口通信有两根通信线(发送端TXD和接收端RXD)
-
TXD与RXD要交叉连接,当只需单向的数据传输时,可以直接一根通信线当电平标准不一致时,需要加电平转换芯片。
-
电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:
-
TTL电平:+5V表示1,0V表示0
-
RS232电平:-3~-15V表示1,+3~+15V表示0
-
RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)
-
-
常见通信接口比较
-
名称 引脚定义 通信方式 特点 UART TXD、RXD 全双工、异步 点对点通信 I²C SCL、SDA 半双工、同步 可挂载多个设备 SPI SCLK、MOSI、MISO、CS 全双工、同步 可挂载多个设备 1-Wire DQ 半双工、异步 可挂载多个设备 -
相关术语:
-
全双工:通信双方可以在同一时刻互相传输数据
-
半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
-
单工:通信只能有一方发送到另一方,不能反向传输
-
异步:通信双方各自约定通信速率
-
同步:通信双方靠一根时钟线来约定通信速率
-
总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)
-
STC89C52有1个UARTSTC89C52的UART有四种工作模式: 模式0:同步移位寄存器 模式1:8位UART,波特率可变(常用) 模式2:9位UART,波特率固定 模式3:9位UART,波特率可变(下面都是模式1来讲解的)
-
波特率:串口通信的速率(发送和接收各数据位的间隔时间)
-
检验位:用于数据验证
-
停止位:用于数据帧间隔
-
-
SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器
-
数据显示模式
-
HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
-
文本模式/字符模式:以原始数据编码后的形式显示
-
串口向电脑发送数据
#include <REGX52.H> #include "Delay.h" unsigned char sendData; //这个是stc软件生成的。 void UartInit() //4800bps@12.000MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率 // AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T // AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xF3; //设定定时初值 TH1 = 0xF3; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 } //发送一个字节 void UART_SendByte(unsigned char Byte){ SBUF = Byte; while(TI==0); TI = 0; } void main(){ UartInit(); while(1){ sendData++; UART_SendByte(sendData); Delayms(500); } }
电脑向串口发送数据
//模块化UART #include <REGX52.H> unsigned char sendData; void UartInit() //4800bps@12.000MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率 TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xF3; //设定定时初值 TH1 = 0xF3; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 EA = 1; //添加中断(按键的时候中断获取) ES = 1; //上面那个不用加这个 } //发送一个字节 void UART_SendByte(unsigned char Byte){ SBUF = Byte; while(TI==0); TI = 0; } /* 串口中断函数模板 void UART_Routine() interrupt 4 { if(RI == 1) { //SBUF 赋值给别人就是电脑下发数据给单片机, //其他等于SBUF就是单片机给电脑。 P2 = SBUF; RI = 0; UART_SendByte(P2); } } */ -------------------------------------------------------------------------------------------------------- #ifndef __UART_H__ #define __UART_H__ void UartInit(); #endif ------------------------------------------------------------------------------------------------------- #include <REGX52.H> #include "Delay.h" #include "UART.h" void main(){ UartInit(); while(1){ } } //需要定义中断,查手册,得出是中断4 void UART_Routine() interrupt 4 { if(RI == 1) { //SBUF 赋值给别人就是电脑下发数据给单片机, //其他等于SBUF就是单片机给电脑。 P2 = SBUF; RI = 0; UART_SendByte(P2); } }