目录
1.2.2按照通信的数据同步方式,可分为异步通信和同步通信;
1.2.3按照数据的传输方向又可分为单工、半双工和全双工通信;
前言
新人首发,最近学习总结,对串口通信有大概的了解,很高兴能分享出来,感谢支持,有空互三!
希望对大家能有所帮助,欢迎大家指教。
一.串口前置知识
1.1单片机通信概念
首先我们认识一下什么是通信?
单片机通信:指单片机与其他设备或单片机之间进行信息交换的过程。单片机的通信主要是通过通信接口与其他设备进行数据交流,可以实现单片机与外部硬件设备之间的数据传输、控制和监测等功能。通信的目的是将各种设备连接起来,使它们能够协同工作,相互传递信息和指令,实现协同控制和信息处理。
1.2通信方式
1.2.1按照数据传送方式可分为串行通信和并行通信;
-
并行通信:数据的各位同时进行发送或接收的通信方式。优点是速率高。缺点是需要的传输线多,成本高,只适合近距离的数据通信。
-
串行通信:一位一位的按顺序的进行发送或接收的通信方式。优点是需要的传输线少,成本低。缺点是传输的速率慢,适合远距离的数据通信。
-
1.2.2按照通信的数据同步方式,可分为异步通信和同步通信;
- 同步通信:发送端在发送串行数据的同时,提供一个时钟信号,并按照一定的约定(例如:在时钟信号的上升沿的时候,将数据发送出去)发送数据,接收端根据发送端提供的时钟信号,以及大家的约定,接收数据。如:I2C、SPI等有时钟信号的协议,都属于这种通信方式。
- 异步通信: 接收方并不知道数据什么时候会到达,收发双方可以有各自自己的时钟。发送方发送的时间间隔可以不均,接收方是在数据的起始位和停止位的帮助下实现信息同步的。
1.2.3按照数据的传输方向又可分为单工、半双工和全双工通信;
- 单工通信:在单工通信中,通信的信道是单向的,发送端与接收端也是固定的,即发送端只能发送信息,不能接收;接收端只能接收信息,不能发送。基于这种情况,数据信号从一端传送到另外一端,信号流是单方向的。
- 半双工通信:半双工通信可以实现双向的通信,但不能在两个方向上同时进行,必须轮流交替地进行。这种工作方式下,发送端可以转变为接收端;相应地,接收端也可以转变为发送端。但是在同一个时刻,信息只能在一个方向上传输。因此,也可以将半双工通信理解为一种切换方向的单工通信。
- 全双工通信:全双工通信允许数据同时在两个方向上传输,又称为双向同时通信,即通信的双方可以同时发送和接收数据。
二.串口通信简绍
2.1串口通信简介
51单片机串口通信是指通过单片机内部硬件自带的串口模块实现的通信方式。串口通信是一种全双工,异步通信方式,它通过发送和接收数据来使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,单片机不仅可以使用串口来实现通信,还可以通过IO口模拟实现多种其他通信,比如 SPI,IIC等。
2.2硬件电路
串口通信有两根通信线(发送端TXD和接收端RXD)。串口数据收发线要交叉连接,计算机的 TXD 要对应单片机的 RXD,计算机的 RXD 要对应单片机的 TXD,并且共 GND。
模块使用:USB转串口模块
2.3工作模式
STC89C52有1个UART(Universal Asynchronous Receiver Transmitter,通用异步收发器)。
STC89C52的UART共有四种工作模式:
- 模式0:同步移位寄存器;
- 模式1:8位UART,波特率可变(常用);
- 模式2:9位UART,波特率固定;
- 模式3:9位UART,波特率可变;
三.串口配置相关寄存器
3.1串行控制寄存器SCON
SCON寄存器是用于选择串行通信的工作方式,和某些控制功能。其格式如下:
如上图所示,常用位只有SM0,SM1,REN,TI和RI。
- SM0和SM1,用确定串口UART的工作模式,通过软件置位SM0和SM1,确定出了四种组合,对应着四种UART工作模式,在不同模式下,串口的功能和波特率都不相同,下图写出了各个不同模式下的波特率因如何计算。
- REN,允许/禁止穿行接收控制位。由软件置位REN,REN=1为允许串行接收状态,可启动串行接收器RXD,开始接收信息;软件复位REN,即REN=0,则禁止接收;
- TI: 发送中断请求标志位。在方式0,当串行发送数据第8位结束时,由内部硬件自动置位,即TI=1,向主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬件置位,必须用软件复位;
- RI:接收中断请求标志位。在方式0,当串行接收到第8位结束时由内部硬件自动置位RI=1,向主机请求中断,响应中断后必须用软件复位,即RI=0。在其他方式中,串行接收到停止位的中间时刻由内部硬件置位,即RI=1,必须由软件复位,即RI=0。
3.2电源控制寄存器PCON
该寄存器较常用到就是SWOD位,知道SWOD就好了。
- SWOD,波特率选择位,就是用于波特率是否加倍。
○ 当用软件置位SMOD,即SMOD=1,则使波特率加倍;
○ SMOD=0,则各工作方式的波特率不加倍不变。复位时默认SMOD=0。
现在我们认识SMOD,由此可以大概把握波特率的计算(一般可以从STC-ISP_波特率计算器中获取自己想要的波特率)
公式,由上上个图可知:(一般是把定时器1作为波特率的发生器,而且常用的是工作方式2)
定时器溢出率也就是定时器溢出的频率,即 定时器溢出率 = 定时器溢出的次数/溢出所用时间 = 1/溢出一次所用时间 。 (单位:us)
3.3SBUF寄存器
前面讲了一大堆铺垫,相信大家都有一个疑问:单片机是怎么发送数据呢?它又是如何接收数据呢? 它是通过SBUF寄存器实现的。
SBUF寄存器有俩个,一个是发送寄存器,另一个是接收寄存器(名字都一样),但在逻辑上SBUF只有一个(地址都为99H),物理结构上,这是俩个完全独立的寄存器。如果CPU写SBUF,数据就会被送入发送寄存器准备发送;如果CPU读SBUF,则读入的数据一定来自接收寄存器。
简单来讲:a=SBUF,代表单片机从计算机接收到了数据(接收到的数据自动存在接收寄存器SBUF中)并且从接收寄存器SBUF读取数据并赋给a。SBUF=a,代表单片机要给计算机发送a数据,只需将a赋给发送寄存器SBUF就行,发送寄存器SBUF会自动给计算机发送SBUF中的数据。
四.串口配置
4.1配置SCON寄存器(用于串口初始化)
以常用的串口模式1(8位UART,波特率可变)来举例。
在模式1下,SM0和SM1置为0 1.
REN,可置0 可置1,根据自己代码需求。
SCON = 0X40; //模式1,REN置0,禁止接受信息
SCON =0X50 //模式1,REN置1,启用TXD,允许接受信息
4.2配置PCON寄存器(用于串口初始化)
这里我们只考虑SWOD位,需不需要波特率加倍,如果要加倍,则SWOD位置1。
PCON |= 0x80; //波特率加倍
4.3串口初始化
1.配置SCON寄存器为0x40(或0x50);
2.配置PCON寄存器(波特率是否加倍);
3.配置定时器T1(只有定时器1才能串口通信,使用8位自动重装工作模式),启动定时器T1;
4.禁止定时器T1中断(T1在这里起配置相应的串口波特率的作用,为波特率发生器);
5.开启串口中断和总中断,后续中断函数做铺垫
代码如下:
void UartInit(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //设定模式1,REN置1串口可接收可发送
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES=1; //开启串口中断
EA=1; //开启总中断
}
注:串口初始化代码也可以从STC-ISP中获取:
4.4配置发送数据函数
代码如下:
(串口发送一个字节数据)
void UART_SendByte(char Byte)
{
SBUF=Byte; //向缓存器中写入数据
while(TI==0); //等待是否完成
TI=0; //TI复位
}
4.5配置中断函数
中断函数:
//串口中断函数格式
void (函数名无所谓)() interrupt 4
{
中断程序;
}
//中断接收数据函数
void UART_Routine() interrupt 4
{
if(RI==1) //判断接收中断请求标志位是否置1
{
RI=0; //清空标志位,复位
UART_Send(SBUF); //查看接受的数据
}
}
五.代码实验
5.1单片机与PC串口通信
代码如下:
UART.c--用于定义两个函数。
一个是单片机发送数据函数,向PC发送数据。另一个是单片机接收函数,接收PC发送的数据。
#include <REGX52.H>
//串口初始化
void UartInit(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //设定模式1,REN置1串口可接收可发送
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES=1; //开启串口中断
EA=1; //开启总中断
}
//单片机发送数据函数
void UART_SendByte(char Byte)
{
SBUF=Byte; //向缓存器中写入数据
while(TI==0); //等待是否完成
TI=0; //复位
}
//中断接收PC发送的数据函数
void UART_Routine() interrupt 4
{
if(RI==1) //判断接收中断请求标志位是否置1
{
RI=0; //清空标志位,复位
P2=SBUF; //从SUBF中读取数据,LED显示接收是否成功
UART_Send(SBUF); //执行发送数据函数,将数据发回电脑
}
}
main.c--调用封装好的串口函数库
#include <REGX52.H>
#include "UART.h"
int main() //主函数就这么简单
{
int Data;
Data=0; //发送的数据进行赋值
UartInit();
while(1)
{
UART_SendByte(Data); //单片机发送数据
}
}
5.2实验现象
5.2.1单片机向PC发送数据
可以看到单片机发送的数据在STC-ISP中的串口助手接受区显示。
注:开启串口助手,一定要选对串口端口号和相对应的波特率,然后点击“打开串口”按钮,就可以查看了。
如图所示Data数据在while循环中,由单片机持续向PC发送数据0;
5.2.2PC向单片机发送数据,单片机接收数据
在串口助手上PC发送十六进制数据,可以看见接受区得到相应的值。
LED以相应的状态显示,串口发送成功。
总结
1.注意硬件,连接发送端TXD和接收端RXD要交叉连接,通信波特率配置要相同;
2.串口通信只能配置定时器1,为波特率发生器,无需开启定时器中断,开启串口中断;
能看到这里,就意味着你一不小心又掌握了一个新知识,你说气不气人?建议点赞收藏,做一个真正的IT人,乐于分享,互帮互助...