串行通信原理
并行通信[多条数据线同时传输一条数据(1字节)]

串行通信[一条数据线同时传输一条数据(1字节)]


串行通信又分为异步通信和同步通信
同步通信

同步通信分为外同步和自同步


异步通信

由于异步通信的数据间传输时间间隔是任意的,所以要告诉传输设备,数据是从哪里开始的,哪里结束的。所以传输的数据的最前面要加上起始位,最后面要加上停止位。

传输速率

串行接口的结构

//SBUF寄存器既可以用于存放要发送的数据,也可以用于存放要接收的数据
//接收数据,设需要把接收进来的数据放在变量a中
a = SBUF; //把接收到的放在SBUF的数据用变量a记录
//发送数据,设需要发送变量a
SBUF = a; //把a交给SBUF发送
51单片机串口相关的寄存器
IE寄存器

串行口控制寄存器SCON(可位寻址)






//操作IE寄存器设置中断
//设置串口的工作方式
//配置允许接收位
//接收标志位和请求标志位软件清零
//用定时器1产生波特率
//定时器的配置,1打开定时器开关,2设置工作模式,3配置TH,TL初值
//串口初始化函数
void UARTInit()
{
EA = 1; //打开总中断
ES = 1; //打开串口中断
SM0 = 0; SM1 = 1; //串口工作方式1,8位UART波特率可变
REN = 1; //串口允许接收
//用定时器1产生波特率,控制每个传送数据中每个“位”的间隔
TR1 = 1; //启动定时器
TMOD |= 0x20; //定时器1工作模式2,8位自动重装;或运算符“|”可以与其它TMOD的值进行求和
TH1 = 0xfd; //重装数
TL1 = 0xfd; //253
}
以下是完整程序
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
uchar num = 0;
//数码管段选码表
uchar code SMGduan[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f} ;
//数码管位选码表
uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};
void display(uchar i)
{
static uchar wei; //退出函数后变量得到保留
/*******************************************************/
P0 = 0xff; //清除断码
WE = 1; //打开位选
P0 = SMGwei[wei];
WE = 0; //锁住位选数据
switch(wei)
{
case 0 : DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;
case 1 : DU = 1; P0 = SMGduan[i / 10 % 10]; DU = 0; break;
case 2 : DU = 1; P0 = SMGduan[i % 10]; DU = 0; break;
}
wei++;
if(wei == 3)
wei = 0;
}
//定时器0初始化
void timer0Init()
{
EA = 1; //打开总中断
ET0 = 1; //允许T0中断
TR0 = 1; //启动定时器0
TMOD |= 0x01; //定时器0工作模式1,16位定时模式;或运算符“|”可以与其它TMOD的值进行求和
TH0 = 0xed;
TL0 = 0xff; //5ms
}
//串口初始化函数
void UARTInit()
{
EA = 1; //打开总中断
ES = 1; //打开串口中断
SM0 = 0; SM1 = 1; //串口工作方式1,8位UART波特率可变
REN = 1; //串口允许接收
//用定时器1产生波特率,控制每个传送数据中每个“位”的间隔
TR1 = 1; //启动定时器
TMOD |= 0x20; //定时器1工作模式2,8位自动重装;或运算符“|”可以与其它TMOD的值进行求和
TH1 = 0xfd; //重装数
TL1 = 0xfd; //253
}
void main()
{
timer0Init(); //定时器0初始化
UARTInit(); //串口初始化
while(1);
}
// 定时器0中断函数
void timer0() interrupt 1
{
TH0 = 0xed;//重放初值
TL0 = 0xff;
display(num);
}
//串口中断函数
void UART() interrupt 4
{
uchar temp;
if(RI) //判断接收是否完成
{
num = SBUF; //读SBUF,读出串口接收到的数据
RI = 0; //软件清零接收标志位
temp = num;
SBUF = ++temp; //写SBUF,向上位机发送+1后的数
}
if(TI) //判断是否发送完成
{
TI = 0; //软件清零发送完成标志位
}
}


网友评论