51单片机中的串口通信设置及串口中断
串口通信:异步通信,全双工,串行通信
注意:负责串口通信的有2个寄存器,都叫SBUF,一个负责存入计算机给单片机的数据,另一个负责将单片机的数据发给计算机。
注意串口通信的方式:查询法或者中断法,其中查询法不需要打开串口中断。
注意引发串口中断的方式:当串口接收到数据时,RI由单片机的硬件直接置1,这时直接引发串口中断;当串口向外面写数据时,TI由单片机硬件直接置1,这是也会直接引发串口中断。
1、串口通信的设置:
① 设置串口工作方式SM0 SM1;最常用的工作方式就是工作方式1;
② 打开串口接收允许位REN;
③ 设置串口通信的波特率:包括SMOD、T1定时器的工作方式、T1定时器的初值
④ 打开T1定时器;
#如果使用中断法的话,需要打开串口中断
⑤ 打开总中断EA=1
⑥ 打开串口中断ES=1
以下程序实现的是当串口接收到数据时就发送回来:
/*************串口通信*************/
/**如果串口接收到了数据,数据会存在SBUF寄存器里面,P0=SUBF就可以让SBUF里面的数据传给P0口**/
/*************① 查询法;② 中断法************/
/*① 查询法:当串口接收数据时RI由硬件置1,查询RI的状态即可知道串口是否接收到了数据*/
/*② 中断法:当RI=1时或者TI=1时会引发串口中断,程序去执行串口中断子程序中的指令,执行完之后再回主函数*/
/*中断法的注意事项:接收数据时,接接收一次RI=1会引发串口中断;而发送数据时,发送一次TI=1也会引发串口中断*/
/*串口通信的设置:设置工作方式-打开串口接受允许位-设置波特率*/
/******以下程序实现的是当串口接收到数据时就发送回来******/
# include <reg52.h>
# include <math.h>
# include <intrins.h>
void DelayMs(int Delaytime); //延时函数DelayMs()的声明
unsigned int FlagReceive = 0; //单片机串口接收数据判定,当串口接收到数据时FlagReceive=1
unsigned int Receive;
void main()
{
SM0 = 0; //设置串口工作方式为方式1
SM1 = 1;
REN = 1; //打开串口接收允许位
TMOD = 0x20; //设置波特率:设置定时器T1工作方式为方式2
TH1 = 0xfd; //设置波特率:T1定时器装入初值
TL1 = 0xfd;
TR1 = 1; //设置波特率:打开T1定时器
/********************① 查询法********************/
// while(1)
// {
// while(RI) //当检测到RI=1的时候,执行循环中的操作
// {
// RI = 0;
// P0 = SBUF; //把SBUF中的数据传给P0
// DelayMs(1000);
P0 = 0xff;
// }
// }
//
/********************① 中断法********************/
EA = 1; //中断法的时候,必须要打开中断开关
ES = 1; //打开串口中断开关ES
while(1)
{
while(FlagReceive) //判断串口有没有接收到数据,接收到时就开始执行发送程序
{
FlagReceive = 0; //先把FlagReceive置0
SBUF = Receive; //然后把接收到的数据发给SBUF,注意这个SBUF是用来送数据的SBUF
//注意当数据写入SBUF之后,TI=1,就直接引发串口中断了
}
P0 = 0xfe;
DelayMs(50);
P0 = 0xfd;
DelayMs(50);
}
}
/*********各类函数的定义*********/ //中断函数不需要声明;其余函数要声明
void DelayMs(int Delaytime)
{
int x,y;
for(x=Delaytime;x>0;x--)
for(y=110;y>0;y--);
}
//串口中断对应的是interrupt 4,
void SeriInterrupt() interrupt 4 //当串口接收到数据时就会进入串口中断子程序
{
if(RI==1)
{
RI = 0; //接收到数据时,RI=1引发中断,进入中断后使RI复位
FlagReceive = 1; //接收到数据了,就使FlagReceive=1
Receive = SBUF; //把接收到的数据存起来,注意这个SBUF是用来存数据的SBUF
P0 = SBUF; //把接收到的数据给P0
DelayMs(1000);
}
if(TI==1) //当T1引发串口中断时,把T1置0再返回主程序
{
TI = 0;
}
}