通讯的基本概念
51单片机不仅可以实现串口通信,还可以通过IO口模拟实现多种其他通信,比如 SPI,IIC等,学习这些通信前,我们很有必要了解下通信的基本概念。通信的方式可以分为多种,按照数据传输方式可分为串行通信和并行通信。按照通信的数据同步方式,可分为异同通信和同步通信。按照数据的传输方向又可分为单工,半双工和全双工通信。
串行通信与并行通信
(1)串行通信
串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机,计算机与外设之间的远距离通信,先传输低位在传输高位。如下图所示:
串行通信的特点:传输线少,长距离传送时成本低,且可以利用电话网等现成的设备,但数据的传送控制比并行通信复杂。
(2)并行通信
并行通信通常是将数据字节的各位用多条数据线同时进行传送,通常是8位,16位,32位等数据一起传输。如下图所示:
并行通信的特点:控制简单,传输速度快;由于传输线较多,长距离传送时成本高且接收方的各位同时接受存在困难,抗干扰能力差。
异步通信与同步通信
(1)异步通信
异步通信是指通信的发送与接受设备适用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。
异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的,即字符之间不一定有“位间隔”的整数倍的关系,但同一字符的各位之间的距离均为“位间隔”的整数倍。如下图所示:
异步通信的特点:不要求收发双方时钟的严格一致,实现容易,设备开销较小,但每个字符要附加2~3位用于起止位,各帧之间还有间隔,因此传输效率不高。
(2)同步通信
同步通信时要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙,即保持位同步关系,也保持字符同步关系。发送方对接收方的同步可以通过两种方法实现。如下图所示:
单工,半双工与全双工通信
(1)单工通信
单工是指数据传输仅能沿一个方向,不能实现反向传输。如下图所示:
(2)半双工通信
半双工的指数据传输可以沿两个方向,但需要分开时间进行,不能同时进行。如下图所示:时间1和时间2,是两个时间进行接收,发送,不能接收和发送同时进行。
(3)全双工通信
全双工是指数据可以同时进行双向传输。如下图所示:同一时间既可以发送,又可以接收
通信速率
衡量通信性能的一个非常重要的参数就是通信速率,通常以比特率(Bitrate)来表示。比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps).如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位)这时的比特率为:10位×240个/秒=2400 bps。
后面会一段一个“‘波特率’”的概念,它表示每秒传输了多少个码元。而码元是通信信号调制的概念,通信常用时间间隔相同的符号来表示一个二进制数字,这样的信号成为码元。如常见的通信传输中,用 0V 表示数字 0, 5V 表述数字 1 ,那么一个码元可以表示两种状态 0 和 1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致;如果在通信传输中,有 0V,2V,4V 以及 6V分别表示二进制数 00,01,10,11 那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半 。由于很多常见的通信中一个码元都是表示两种状态,所以我们常常直接以波特率来表示比特率
单片机串口通信介绍
串口通信简介
串口通信,是指外设和计算机间通过数据信号线,地线等按位进行传输数据的一种通信方式,属于串行通信方式。串口是一种接口标准,它规定了接口的电器标准,没有规定接口插件电缆以及使用的协议。
(1)接口标准
串口通信的接口标准有甚多,有RS-232C、 RS-232、 RS-422A、 RS-485 等。 常用的是 RS-232 和 RS-485。RS-232 其实是 RS-232C 的改进,原理是一样的。 这里我们就以 RS-232C 接口进行讲解。
RS-232C 是 EIA(美国电子工业协会)1969 年修订 RS-232C 标准。RS-232C 定义了数据终端设备(DTE)与数据通信设备(DCE)之间的物理接口标准。
RS-232C 接口规定使用 25 针连接器,简称 DB25,连接器的尺寸及每个插 针的排列位置都有明确的定义,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/d02df0005dc2089fcc89a517e26deb8f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9b07bfcfffb2a147e551789c54e3e1fa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4de158b51e3613f707721dc66ac590a9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/90403663a0e9ba92269fa25d9cb73d1a.png)
串口相关寄存器
(1)串口控制寄存器SCON
![](https://i-blog.csdnimg.cn/blog_migrate/383ba95ecabe9a4b65d1ffc52097db11.png)
![](https://i-blog.csdnimg.cn/blog_migrate/53925339ac6224925e9ce780e86f2d91.png)
SM2:多机通信控制位,主要用于方式 2 和方式 3。当 SM2=1 时可以利用收到 的 RB8 来控制是否激活 RI(RB8=0 时不激活 RI,收到的信息丢弃;RB8=1 时收 到的数据进入 SBUF,并激活 RI,进而在中断服务中将数据从 SBUF 读走)。当 SM2=0 时,不论收到的 RB8 为 0 和 1,均可以使收到的数据进入 SBUF,并激活 RI (即此时 RB8 不具有控制 RI 激活的功能)。通过控制 SM2,可以实现多机通信。
![](https://i-blog.csdnimg.cn/blog_migrate/da77721e92d907b590a61e0e4e6e8d51.png)
方式1
方式1是10位数据的异步通信口,TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如下所示。其中1位起始位,8位数据位,1位停止位。
对应输入输出的时序图如下所示:
用软件置REN为1时,接收器以所选择波特率的16倍速采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。接收过程中,数据从输入移位寄存器右边移入,起始位移位寄存器最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的停止位1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI=1,向CPU请求中断。
方式2和方式3
方式2或方式3时为11为数据的异步通信口,TXD为数据发送引脚,RXD为数据接收引脚。其数据局格式如下:
对应的输入输出时序图如下所示:
① 方式2,方式3输出
发送开始时,先把起始位0输出到TXD引脚,然后发送 移位寄存器的输出位(D0)到TXD引脚。每一个移位脉冲都使输出移位寄存器的各位右移一位,并由TXD引脚输出。第一次移位时,停止位“1”移入输出寄存器的第9位上,以后每次移位,左边都移入0。当停止位移至输出位时,左边其余位全为0,检测电路检测到这一条时,使控制电路进行最后一次移位,并置 TI=1,向CPU请求中断。
② 方式2,方式3输入
接收时,数据从右边移入输入移位寄存器,在起始位 0 移到最左边时,控制电路进行最后一次移位。当 RI=0,且 SM2=0(或接收到的第9位数据位1)时,接收到的数据装入接收缓存器 SBUF和 RB8(接收数据的第9位),置 RI=1,向CPU请求中断。如果条件不满足,则数据丢失,且不置位RI,继续搜索 RXD 引脚的负跳变。
串口的使用方法
(1)如何计算波特率
在学习51单片机串口时,非常重要的一点是学位如何计算波特率。以下列出了集中方式下波特率的计算公式:
![](https://i-blog.csdnimg.cn/blog_migrate/4fa711b2a78615e5e5eab1fb2cc05953.png)
![](https://i-blog.csdnimg.cn/blog_migrate/45c9f5b914f9f917f7b28371d39422ff.png)
/*******************************************************************************
* 函 数 名 : uart_init
* 函数功能 : 串口通信中断配置函数,通过设置 TH 和 TL 即可确定定时时间
* 输 入 : baud:波特率对应的 TH、TL 装载值
* 输 出 : 无
*******************************************************************************/
void uart_init(u8 baud)
{
TMOD|=0X20; //定时器设置,计数器工作方式 2
SCON=0X50; //串口通信,设置为工作方式 1
PCON=0X80; //波特率加倍的设置
TH1=baud; //计数器波特率初始值设置
TL1=baud;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
uart_init(0XFA);//波特率为 9600
从上图中可以看出,通过 CH340 芯片把 51 单片机的串口与 PC 机的 USB 口 进行连接,不仅可以实现程序的烧入,还可实现串口通信功能。根据前面介绍, 串口通信需将数据收发管脚交叉连接,所以可以看到在 CH340 芯片的 2 和 3 脚 已做处理。电路中其他部分是自动下载电路部分,目的是控制单片机的电源,无 需冷启动。使用 USB 转串口芯片,免去了一根串口线,使用普通 USB 数据线(支 持安卓手机数据线)就可以进行串口通信。
从上图中可以看到 CH340 的 2、3 脚串口并非直接连接到单片机串口,而是 连接在 P5 端子上,这样就把 CH340 的串口与单片机串口独立出来,为什么不直 接连接而要使用这个 P5 端子呢?这是方便用户可以使用开发板上的 USB 转 TTL 模块(也就是 CH340 转串口模块)做一些串口类模块的调试,比如:WIFI、蓝牙、 GPS、GPRS 等,直接利用 PC 上位机来调试模块。同时也方便用户使用板载 USB 转 TTL 模块给其它类型单片机下载程序。 如果使用黄色跳线帽将 P5 端子的 1、2 短接,3、4 短接,那么 CH340 串口与 单片机串口是连接一起的,此时即可实现程序的下载或串口通信。
如果使用黄色跳线帽将 P5 端子的 1、2 短接,3、4 短接,那么 CH340 串口与 单片机串口是连接一起的,此时即可实现程序的下载或串口通信。
软件设计
本章所要实现的功能是:当串口助手发送数据给单片机,单片机原封不动转 发给串口助手显示。
/**********************************************************************************
****
实验名称:串口通信实验
接线说明:
实验现象:下载程序后,当串口助手发送数据给单片机,单片机原封不动转发给串口助手显示
注意事项:使用黄色跳线帽将 CH340 旁的 P5 端子的 UTX 和 P30 短接,URX 和 P31 短接,出厂默
认已短接好
***********************************************************************************
****/
#include "reg52.h"
typedef unsigned int u16;//对系统默认数据类型进行重定义
typedef unsigned char u8;
/*******************************************************************************
* 函 数 名 : uart_init
* 函数功能 : 串口通信中断配置函数,通过设置 TH 和 TL 即可确定定时时间
* 输 入 : baud:波特率对应的 TH、TL 装载值
* 输 出 : 无
*******************************************************************************/
void uart_init(u8 baud)
{
TMOD |=0X20;//设置定时器的计数器工作方式 ,设置定时器的是计数器工作方式 2
SCON = 0X50;//串口工作方式配置 ,设置为工作方式 1
PCON = 0X80;//波特率加倍的设置
TH1 = baud; //计数器波特率初始值设置
TL1 = baud;
ES = 1;//串口中断打开
EA = 1;//总中断打开
TR1 = 1;//定时器打开,一般都放在最后面
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
uart_init(0XFA);//波特率为 9600
while(1)
{
}
}
/*******************************************************************************
* 函 数 名 : uart
* 函数功能 : 串口中断函数,串口的中断号是4,interrupt 4
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void uart() interrupt 4 //串口通信中断函数
{
u8 rec_data;
RI = 0; //中断标志清0 ,等待下次的接收
rec_data=SBUF; //存储接收到的数据
SBUF=rec_data; //将接收到的数据放入到发送寄存器
//等待发送数据完成,数据是一位一位地发送,没有发送完成TI=0
//,取反一下TI=1,为真就继续发送 。发送完成TI=1,取反TI=0,条件为假,退出循环
while(!TI);
TI=0; //清除发送完成标志位
}
![](https://i-blog.csdnimg.cn/blog_migrate/75d17e106d4b5cc27fa196fe878d6195.png)