80S52:RS232双工串口通信模块
功能:和PC机通信说骚话
模块介绍
串口通信主要四个要点
SBUF寄存
SBUF主要用来储存从PC接收的信息和准备向PC发送的信息,大小为8位
波特率匹配
要与PC通信必须遵守规则,也就是必须有相同的发送/接收频率(波特率)51单片机中使用T1定时/计数器来设置波特率定时器溢出一次代表传输一次数据
SCON串口控制寄存器(主要用方式1)
SM0、SM1:----确定工作方式
一般使用方式1,SM0=0,SM1=1;SM2:----多机通信控制位(可以先不理)
多机通信是工作在方式2和方式3的,所以SM2主要用于方式2和方式3,多级通信时,SM2=1,当SM2=1时,只有当接收到的数据帧第9位(RB8)为1时,
单片机才把前八位数据放入自己的SBUF中,否则,将丢弃数据帧。当SM2=0时,不论RB8的值是什么,都会把串口收到的数据放到SBUF中。
REN:-----允许接收位
REN用于控制是否允许接收数据,REN=1时,允许接收数据,REN=0时,拒绝接收数据
TB8:-------是要发送的第9位数据位
在方式2和方式3中,TB8是要作为数据帧第9位被发送出去的,在多机通信中,可用于判断当前数据帧的数据是地址还是数据,TB8=0为数据,TB8=1为地址
RB8:-------接收到的第9位数据位
当单片机已经接收一帧数据帧时,会把数据帧中的第9位放到 RB8中。方式0不使用RB8,在方式2和方式3中,RB8为接收到的数据帧的第9位数据位。
TI:-----发送中断标志位
方式0中,不用管他。其他方式下,当发送数据完毕,硬件会将其置1,当 TI 被置1,会向CPU发送中断请求。我们记得要在中断服务程序中把 IT 置回0.
RI:-----接收中断标志位
当接受完一帧数据时,RI 由硬件置1,当RI 被置1,会向CPU请求中断。同样要在中断服务程序中把 RI 置回0。
PCON功率控制寄存器
这个寄存器只有一个位SMOD,在方式1,2.,3时,波特率都与SMOD有关,当SMOD=1时,波特率会增加一倍。复位时,SMOD变回0
部分介绍摘自:
准备工作
设定两个寄存器,并打开波特率定时器
void InitUART(void)
{
TMOD = 0x20;//设置T1为定时器
SCON = 0x50;//工作方式1
TH1 = 0xF3;
TL1 = TH1;//定时与波特率匹配
PCON = 0x00;//不加倍(~~反手一个超级加倍~~)
EA = 1;
ES = 1;//中断开开
TR1 = 1;//计时
}
发送模块
每个字节发送完成后要将完成标识TI手动置0
void SendOneByte(unsigned char c)
{
SBUF = c;//向SBUF中放入数据
while(!TI);//等待发送结束标识
TI = 0;
}
接收模块
利用串口中断来执行读入操作,和发送类似接收完成标识RI也需要置0
void UARTInterrupt(void) interrupt 4
{
ES=0;//防止打扰
if(RI)
{
RI = 0;
res=SBUF
}
ES=1;
}
附上沙雕程序一枚
我是复读机。。。233333
波特率2400
#include <reg51.h>
typedef unsigned char u8;
typedef unsigned int u16;
u8 res ,b,num;
u8 save[10];
void InitUART(void)
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xF3;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
void SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI);
TI = 0;
}
void SendString(u8*t){
while(*t!='\0')
SendOneByte(*t++);
}
void main(void)
{
InitUART();
SendString("Hello I am a repeater!");
while(1){
if(b){
SendString(save);
b=0;
}
}
}
void UARTInterrupt(void) interrupt 4
{
ES=0;
if(RI)
{
RI = 0;
res=SBUF;
if(res!='#')
save[num++]=res;
else
{
b=1;
num=0;
}
}
ES=1;
}