序:在嵌入式产品里,串口常用于程序调试、程序烧录和模块通信接口。本例首先介绍单片机串口的结构和原理,然后通过一个双机通信实例说明串口通信的应用编程。
一、实例目的
通过本实例,我们应:
1. 了解串口与并口通信的区别。
2. 掌握51单片机的串口结构与原理。
3. 掌握51单片机的串口编程。
二、串口与并口通信
在数字世界里,信息由0和1编码组成。一串数据对于不同模块,意义也不同。犹如点头在大多数国家表示YES,摇头表示NO,但在某些国家如保加利亚、斯里兰卡等正好相反。也就是说,在数字世界里,信息表示的意义,是由解码器解释的。一般来说,编码器与解码器都是专用的,是基于应用的。
那么,信息的传递,是如何实现的呢?通俗地说,信息是由0和1组成的一串数据(二进制流,每位(0或1)称为 比特(bit))。传递信息就是按照顺序向对端发送逐位比特或多位比特。逐位发送称为串行通信,多位同时发送称为并行通信,见图1。对于串行通信,发送比特流顺序有先发最高位(MSB First)和先发最低位(LSB First)。在电气上(物理层),一般用低电平表示0,高电平表示1。
图1 并行通信与串行通信
串口传输数据的基本单位为帧(Frame),一帧包括帧头、有效数据、校验位、帧尾等。有效数据称为有效载荷(Payload),帧头、校验位、帧尾等称为开销(overhead)。
51串口的帧有8位、10位和11位三种,见图2,先传最低位(MSB First)。
图2 51单片机的帧结构
三、51单片机串口结构
51单片机有一个全双工的串行接口,简称串口。图3给出了51单片机的串口内部结构图。
图3 51单片机串口内部结构框图
串口引脚有TXD(串行数据发送管脚)和RXD(串行数据接收管脚)。串口主要由发送缓冲SBUF、接收缓冲SBUF、移位寄存器、波特率发生器组成。相关模块的功能说明如下:
发送缓冲SBUF:把字节数据写到SBUF,串口自动逐位将数据通过TXD管脚输出,发送完毕后置TI中断标志位为1。如果串口中断允许,则触发串口中断处理函数。
接收缓冲SBUF:串口接收到一帧数据后,将8位有效载荷存到SBUF,并置RI中断标志位为1。如果串口中断允许,则触发串口中断处理函数。
移位寄存器:在波特率节拍控制下,采样RXD引脚上的电平,将接收到的0/1存到SBUF。
波特率发生器:串口数据发送和数据接收均在时钟的控制下进行,每秒发送的比特数称为波特率(baud rate),单位为bps。常见的波特率有2400bps,4800bps,9600bps,115200bps。波特率越高,数据传输速率越快。
注意:串口是异步通信,收发双方独立使用自己的时钟,要求双方波特率必须设置一致。一般来说,波特率相差不能超过2%,否则无法正确发送/收到数据,导致出现乱码。
RI/TI:接收/发送中断标志位。
RI用于指示是否接收到数据,1表示接收到一帧数据,如果串口中断是使能的,则触发串口中断。当接收到数据时,必须及时清零RI,否则无法接收到下一帧数据(自动丢弃)。
TI用于指示一帧数据是否发送完成,1表示一帧数据已经发送完毕,如果串口中断是使能的,则触发串口中断。
RI和TI均需软件清零。采用串口中断编程时,RI和TI用于判断是接收数据还是发送数据引起的串口中断。
三、51单片机串口编程接口
串口相关的寄存器包括:
SBUF——串行口数据缓冲器(99H)
共两个:一个发送寄存器SBUF,一个接收SBUF,二者共用一个地址99H。
写数据到SBUF,访问的是发送寄存器SBUF;读SBUF,访问的是接收SBUF。
SCON——串行口控制寄存器(98H)。
PCON——电源控制寄存器(87H)。PCON.SMOD是波特率倍增控制位。
IE ——中断控制寄存器。ES是串口中断允许控制位。
下面主要介绍SCON寄存器。
图4 SCON寄存器定义
SCON字节地址为98H,支持按位寻址。
SM0和SM1用于选择串口的工作方式。
对于串口双机通信,一般采用模式1或模式3。
例:设串行口工作在方式1,允许接收,则C51语句为:
SCON = 0x50;
SM2用于多机通信。SM2=1,从机处于多机模式。
REN为串口接收允许控制位,1有效。
TB8为11帧里发送的第9位数据,如奇偶校验位、多机通信地址/数据指示位等,RB9为11帧里接收到第9位数据。
RI/TI分别为接收中断标志和发送中断标志。
PCON——电源控制寄存器(87H)。PCON.SMOD是波特率倍增控制位。
四、51单片机串口应用编程
串行口的初始化编程:
设置串行口的工作方式( SCON :SM0、SM1 )。
2. 对于工作方式2或3,应根据需要在TB8中写入待发送的第9位数据(地址为1,数据为0)。
若选定的工作方式不是方式0,还需设定接收/发送的波特率。设定SMOD状态,以控制波特率是否加倍。
4. 若选定工作方式1或3,则应对定时器T1进行初始化以设定其溢出率。
(5)串行通信编程有两种方式:查询方式和中断方式,这两种方式中发送和接收数据后都用注意清TI和RI。一般来说,使用查询方式发生数据,使用中断方式接收串口数据。
下面以双机通信为例,介绍单片机的串口应用编程。设双机通信电路图如下所示。主机P1.0接一个独立按键K0,从机P1.0接一个红色LED。要求基于串口通信,实现通过主机K0控制从机的LED的亮灭。假设晶振频率为12MHz,波特率设置为4800bps。
图5 双机通信仿真电路图
编程思路:主机用一个标志位flag存储LED的状态,当按键K0闭合,更新flag状态,并将更新的flag发送到从机。从机根据主机发来的flag控制灯。flag为1时,控制LED亮,flag为0时,控制LED灭。初始化时,flag为0。
图6 主机流程图
图6 从机流程图
利用51波特率初值计算小工具,计算T1的初值。根据已知,晶振频率为12MHz,取T1为方式2(8位初值自动重装定时器),波特率倍增,则T1初值为0xF3。
图7 T1初值计算(fosc=12MHz, 波特率=4800bps)
注意:在使用串口的应用中,单片机晶振通常选择11.0592MHz,使常见波特率对应的T1初值没有误差。
编程步骤:
运行Keil,新建两个工程,MasterMCU和SlaveMCU,分别对应主机和从机程序。
编写相应程序。MasterMCU.c为主机程序,SlaveMCU.c为从机程序,代码如下。
//MasterMCU.c
#include
sbit key0 = P1^0; //K0接口为P1.0
bit flag = 0; //从机LED使能标志位,初始化为0
/****************************
*函数:delayMS
*功能:ms级延时函数@12MHz主频
*参数:ms:unsinged int,延时时间,单位:ms
*返回值:无
*****************************/
void delayMS(unsigned int ms)
{
unsigned int i,j;
for(i=0;i
for(j=0;j
}
void main() //主程序
{
//初始化UART
SCON = 0x40; //设置串口为工作方式1,8位/帧,REN=0,不接收
PCON = 0x80; //PCON.SMOD=1,波特率倍增
TCON = 0x20; //设置T1为方式2 定时器
TH1 = 0xF3; //T1初值,串口波特率4800bps@12MHz
TL1 = 0xF3;
TR1 = 1; //启动定时器T1
while(1)
{
//按键判断
if(key0 ==0) //按键闭合
{
delayMS(10); //软件去抖动
if(key0==0) //确认按键闭合
{
flag = ~flag; //LED使能位取反
while(key0==0); //等待按键松开
SBUF = flag; //通过串口发送flag到从机
while(TI==0); //等待发送完成
TI = 0; //发送完成,软件清理TI
}
}
}
}
//SlaveMCU.c
#include
sbit led_red = P1^0; //LED接口为P1.0
bit flag = 0; //LED使能标志位,初始化为0
void main() //主程序
{
//初始化UART
SCON = 0x50; //设置串口为工作方式1,8位/帧,REN=1,允许接收
TCON = 0x20; //设置T1为方式2 定时器
PCON = 0x80; //PCON.SMOD=1,波特率倍增
EA = 1; //总中断使能
ES = 1; //串口中断使能
TH1 = 0xF3; //T1初值,串口波特率4800bps@12MHz
TL1 = 0xF3;
TR1 = 1; //启动定时器T1
led_red = 1; //初始化LED灭
while(1); //主循环
}
//串口中断处理函数
//中断号为4
void ISR_Serial() interrupt 4
{
if(RI==1) //由接收引起串口中断,取数
{
led_red = 1;
flag = SBUF; //取flag
led_red = ~flag; // flag为1时,输出0,点亮LED;flag为0时,输出1,熄灭LED
RI = 0; //软件清零
}
}
分别生成主机和从机的.hex程序。
4.在proteus ISIS仿真电路图里,关联对应的.hex。
仿真验证,仿真结果如图8所示。
图8 串口编程
五、小结
本实例介绍了串口的结构与原理,通过一个简单实例介绍了串口的应用编程。在串口编程时,注意串口的初始化,特别是使用串口中断函数时,ES和EA别忘了置1。此外,不管采用软件查询法还是串口中断法,必须软件清零RI和TI。在下一个串口实例,我们将学习串口与PC通信编程。
领取专属 10元无门槛券
私享最新 技术干货