
串口通信原理
-
2023年3月16日发(作者:调薪通知)串行口通信原理及操作流程
51单片机的串行口是一个可编程全双工的通信接
口,具有UART(通用异步收发器)的所有功能,能同时
进行数据的发送和接受,也可以作为同步移位寄存器使
用。
51单片机的串行口重要由两个独立的串行数据缓冲
寄存器SBUF(发送缓冲寄存器和接受缓冲寄存器)和发
送控制器、接受控制器、输入移位寄存器及若干控制门电
路组成。
51单片机可以通过特殊功能寄存器SBUF队串行接
受或串行发送寄存器进行访问,两个寄存器共用一个地址
99H,但在物理上是两个独立的寄存器,由指令操作决定
访问哪一个寄存器。执行写指令时访问串行发送寄存器;
执行读指令时,访问串行接受寄存器。(接受器具有双缓
冲结构,即在接受寄存器中读出前一个已接受到的字节之
前,便能接受第二个字节,假如第二个字节已接受完毕,
而第一个字节还没有读出,则将丢失其中一个字节,编程
时应引起注意。对于发送器,由于是由cpu控制的,所
以不需要考虑。
与串行口紧密相关的一个特殊功能寄存器是串行口
控制寄存器SCON,它用来设定串行口的工作方式、接受/
发送控制以及状态标志等。
串行口控制寄存器SCON
串行口控制寄存器SCON在特殊功能寄存器中,字节
地址为98H,可位寻址,单片机复位时SCON所有被清零。
位序号
D7
D6
D5
D4
D3
D2
D1
D0
位符号
SM0
SM1
SM2
REN
TB8
RB8
T1
R1
SM0,SM1为工作方式选择位。串行口有四种工作方
式,它们由SM0、SM1设定。其中方式一最为常用。
SM2为多机通信控制位。
REN为允许串行接受位。
TB8为方式2、3中方式数据的第九位。
RB8为方式2、2中接受数据的第九位。
TI为发送中断标志位,在方式0时,当串行发送第8
位数据结束时,或在其他方式,串行发送停止位的开始时,
由内部硬件使TI置一,向CPU发出中断申请。在中断服
务程序中,必须使用软件将其清零,取消此中断申请。
RI为接受中断标志位。在方式0时,当串行接受第8
位数据结束时,或在其他方式,串行接受停止位的中间时,
由内部硬件使RI置一,向CPU发出中断申请。在中断服
务程序中,必须使用软件将其清零,取消此中断申请。
串口工作方式1简介(0、2、3以后再说),串行口
方式传送1帧数据共10位,其中一位起始位(0),八位
数据位(最低位在前,高位在后),一位停止位(1)。
帧与帧之间可以有空闲,也可以无空闲。TXD(P3.1)位
数据发送引脚,RXD(P3.0)为数据接受引脚。其传输波
特率是可变的,对于51单片机,波特率由定期器1的溢
出率决定。
串行口方式1编程与实现
当数据被写入SBUF寄存器后,单片机自动开始从起
始位发送数据,发送到停止位的开始时,由内部硬件使
TI置1,向CPU申请中断,接下来可在中断服务程序中做
相应的解决,也可选择不进入中断。
用软件置REN为1时,接受器以所选择波特率的16
倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生
负跳变时,则说明起始位有效,将其移入输入移位寄存器,
并开始接受这一帧信息的其余位。接受过程中,数据从移
位寄存器右边移入,起始位移至输入移位寄存器最左边
时,控制电路进行最后一次移位。当RI=0,且SM2=0(或
接受到的停止位为1时),将接受到的9位数据的前8
位数据装入接受SBUF,第9位(停止位)进入RB8,并置
RI=1,向CPU请求中断。
在具体操作串口之前需要对单片机的一些与串口有
关的特殊功能寄存器进行初始化设立,重要是设立产生波
特率的定期器1、串行口控制和中断控制。具体环节如下:
1.
拟定T1的工作方式(编程TMOD寄存器)
2.
计算T1的初值,载入TH1、TL1
3.
启动T1(编程TCON中的TR1位)
4.
拟定串行口工作方式(编程SCON寄存器)
5.
串行口工作在中断方式时,要进行中断设立(编程
IE,IP)
/**********************
实现功能:
RS232通信(串口通信)
**********************/
#include;
#defineuintunsignedint
#defineucharunsignedchar
ucharflag;
uchardate;
voidinit()
{
TMOD=0X20;//定期器1工作方式2
TH1=0xfd;//9600
TH0=0xfd;//9600
TR1=1;//启动定期器1
REN=1;//允许串口接受
SM0=0;//设定串口工作方式1
SM1=1;//设定串口工作方式1
EA=1;//开总中断
ES=1;//开串口中断
}
voidmain()
{
init();
while(1)
{
if(flag==1)
{
ES=0;//关闭串口中断
P1=date;
SBUF=date;
while(!TI);//等待串行发送停止位的开始,TI=1,并
向CPU发送中断请求
TI=0;//取消本次中断
ES=1;//开串口中断
flag=0;
}
}
}
voidtime1()interrupt4
{
RI=0;//取消中断申请
date=SBUF;
flag=1;
}