一、原理
串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。51单片机内部有一个可编程全双工串行通信接口。该部件不仅能同时进行数据的发送和接收,也可作为一个同步移位寄存器使用。AT89C51串行口结构框图如下:
(1)串行数据缓冲器SBUF
SBUF是串行口缓冲寄存器,包括发送寄存器和接收寄存器,以便能以全双工方式进行通信。在逻辑上,SBUF只有一个,它既表示发送寄存器,又表示接收寄存器,具有同一个单元地址99H。但在物理结构上,则有两个完全独立的SBUF,一个是发送缓冲寄存器SBUF,另一个是接收缓冲寄存器SBUF。如果CPU写SBUF,数据就会被送入发送寄存器准备发送;如果CPU读SBUF,则读入的数据一定来自接收缓冲器。即CPU对SBUF的读写,实际上是分别访问上述两个不同的寄存器。
(2)串行控制寄存器SCON
串行控制寄存器SCON用于设置串行口的工作方式、监视串行口的工作状态、控制发送与接收的状态等。它是一个既可以字节寻址又可以位寻址的8位特殊功能寄存器。
(图片来源:B站小蜜蜂笔记)
在AT89C51中,串行发送中断TI和接收中断RI的中断入口地址同是0023H,因此在中断程序中必须由软件查询TI和RI的状态才能确定究竟是接收还是发送中断,进而作出相应的处理。单片机复位时,SCON所有位均清0。
二、程序编写
实现功能:利用51单片机的串行接口与上位机建立传输信道进行数据的收发。采用8位的UART模式,即模式1,波特率为9600BPS。数据发送采用查询方式,数据接收采用中断方式。系统上电初始化之后,单片机向上位机发送两个字节:0x5a和0xa5,然后等待接收上位机的数据,每接收到一个字节后,在该字节的基础上加1然后返回给上位机。
#include <reg52.h>
sfr AUXR=0x8e;//定义辅助寄存器
unsigned char dat;
void InitUart()//串口初始化函数
{
TMOD=0x20; //将TMOD的M1位置1,设置成自动装入的8位定时器
TH1=0xfd;//设置波特率为9600,晶振频率12MHZ
TL1=0xfd;
TR1=1;//启动定时器1,作为串口波特率发生器
SCON=0x50;//10位异步收发,波特率由定时器控制。允许串口接收
AUXR=0x00;//设置辅助寄存器
ES=1;//允许串口中断
EA=1;//开总中断
}
void serviceUart() interrupt 4 //串口中断服务函数
{
if(RI==1)//查询串口接收程序,如果接收标志位为1,说明有数据接收完毕
{
RI=0;//清除接收标志位
dat=SBUF;//将接收缓冲区内容转至dat寄存器中
SBUF=dat+1;//将接收到的内容+1后发送出去
}
}
void sendByte(unsigned char urdat)
{
SBUF=urdat;//将要发送的数据urdat送给SBUF
while(TI==0);//等待数据发送完成
TI=0;//清除发送完成标志
}
void main()
{
InitUart();
sendByte(0x5a);
sendByte(0xa5);
while(1);
}
结果中,串口一开始会多一个00,关闭串口也有00,是由于由于电源不稳(上电时的充电和断电时的放电)造成的干扰,影响不大。