完成的功能:
1.将接收到的数据加1再发送回去;
2.控制点亮一个led灯;
代码如下:
#include <reg52.H>
sbit PIN_RXD=P3^0;
sbit PIN_TXD=P3^1;
sbit led_1=P1^1;
bit RXDEND=0;
bit RXDorTXD=0;
bit TXDEND=0;
unsigned char RXDbuf=0;
unsigned char TXDbuf=0;//发送的数据的缓冲区
void configuart(unsigned int baud);
void startRXD();
void startTXD(unsigned char dat);
void main()
{
EA=1;//开总中断
configuart(9600);
while(1)
{
while(PIN_RXD);//RXD引脚为0时开始接收数据
startRXD();
while(!RXDEND);//接收完毕
startTXD(RXDbuf+1);//收到数据加1再返回
while(!TXDEND);//发送完毕
if(RXDbuf==1)
{
led_1=0;
}
}
}
void configuart(unsigned int baud)
{
TMOD &=0xF0;//将TMOD寄存器的低4位,保留高4位的值不变。准备设置T0。
TMOD |=0x02;//将TMOD寄存器的工作模式设置为8位自动重载定时器模式。
TH0=256-(11059200/12)/baud;
}
/*其中11059200是晶振频率,12是预分频因子,baud是串口通信的波特率。
该计算结果表示每个波特率所需的计数器初始值。
最后,256减去计算结果,是因为定时器是8位的,所以要将计数器初始值转换为补码形式。*/
void startRXD()
{
TL0=256-((256-TH0)>>1);// 将定时器的计数器初始值设置为TH0的一半,这样定时器在计数到一半时会产生溢出中断,从而在波特率信号的电平的中间位置进行读取,以提高可靠性。
ET0=1;//ET0是定时器0中断使能寄存器的位,将其设置为1表示允许定时器0的溢出中断发生。
TR0=1;//TR0是定时器0的控制位,将其设置为1表示启动定时器0。
RXDEND=0;//串口接收的结束标志。
RXDorTXD=0;//0表示接收模式,1表示发送模式
}
void startTXD(unsigned char dat)
{
TXDbuf=dat;
TL0=TH0;
ET0=1;
TR0=1;
PIN_TXD=0;//起始位为0
TXDEND=0;
RXDorTXD=1;
}
void InterruptTimer0() interrupt 1
{
static unsigned char cnt=0;//静态变量表示发送到哪一位
if(RXDorTXD) //发送
{
cnt++;
if(cnt<=8) //未发送完
{
PIN_TXD=TXDbuf & 0x01; //将TXDbuf的最低位赋给PIN_TXD变量,用于控制发送引脚的电平。
TXDbuf >>= 1; //将TXDbuf向右移动一位,以准备发送下一位数据。
}
else if(cnt==9) //已经发送完8位数据
{
PIN_TXD = 1; //发送停止位
}
else //发送操作完成
{
cnt = 0;
TR0 = 0;
TXDEND = 1; //告诉程序发送结束
}
}
else //接收
{
if(cnt==0) //准备接收第一位数据
{
if(!PIN_RXD)
{
RXDbuf = 0; //将接收缓冲区RXDbuf清零
cnt++;
}
else
{
TR0 = 0;
}
}
else if(cnt<=8)
{
RXDbuf>>=1; //接收缓冲区RXDbuf向右移动一位,为接收下一位数据做准备。
if(PIN_RXD)
{
RXDbuf |= 0x80; //将接收缓冲区RXDbuf的最高位设置为1,表示接收到1。
}
cnt++;
}
else
{
cnt=0;
TR0=0;
if(PIN_RXD)
{
RXDEND = 1;
}
}
}
}
搭建proteus仿真:
设置好端口和波特率:
发送数据01,接收到返回数据02并点亮led