51单片机串口通信时的定时器设置的相关问题

时间:2022-04-03 23:26:48

51单片机在串口通信时需要有一个定时器去调节与计算机通信的波特率,而定时器设置时需要中断寄存器(IE),

51单片机串口通信时的定时器设置的相关问题

定时器控制寄存器(TCON)


51单片机串口通信时的定时器设置的相关问题

,还有T/C控制寄存器共同配合作用,

 51单片机串口通信时的定时器设置的相关问题

 

但在启动定时器功能时,这三个寄存器的配置顺序十分重要,因为在数据传输时的高速情况下,一点点的数据误差就会导致传输的数据出现错误。而在51单片机的串口通信时必须将配置TCON放在配置这三个寄存器的最后,因为在TCON中含有启动定时器的TR1和TR0位,若先启动后对工作方式和溢出率进行配置,就会导致启动时定时器根本无法像预先设定的方式工作导致整体的工作出现系统误差,无法消除,就像开车一般,方向选错了,加快脚步也无法到达目的。在这里我举个我开发的例子以供参考。(请注意红字部分的顺序)

经过正常计算在SMOD = 0,以P1作为计时器(工作方式为常数自动装入的8位定时器),且串口工作方式为方式一时以9600Bd的波特率进行通信时,P1的起始数应为0xfd(工作方式为2时只有高4位在工作,低四位作为为储存重装数据储存器而不参与波特率调节)。

代码原稿

#include<reg52.h>
unsigned char num;
void initIE();
void initTCON();
void initSCON();
void initT1();
void initTMOD();
void init();
void main()
{

init();
initSCON();
initT1();
initTMOD();
initTCON();
initIE();
while(1){;}
}
void RES() interrupt 4
{
unsigned char resv;
if(RI)
{
RI = 0;
resv = SBUF;
num++;
SBUF = num;
while(!TI);
TI = 0;
SBUF = resv;
while(!TI);
TI = 0;
if(num>=256)num = 0;
}
}
void initIE()
{
EA =1;
ES =1;
}
void initSCON()
{
SM0 = 0;
SM1 = 1;
REN = 1;
}
void initTCON()
{
TR1 = 1;
}
void initTMOD()
{
TMOD = 0x20;
}
void initT1()
{
TH1 = 0xfd;
TL1 = 0xfd;
}void init()
{
num = 0;
}

第一种顺序

initT1();
initTMOD();
initTCON();

在这种顺序下,P1初始化数设置为计算好的0xfd,并没有任何问题。

第二种顺序

initTCON();

initT1();

initTMOD();

在这种顺序下传输数据就会出现错误,在这种情况下就需要对定时器的初值进行重新实验确定,经试验后发现PH1 = 0xfc,PL1 = 0xfc。时传输的错误就消除了。

所以在大家平时开发单片机时应小心各个寄存器的配置先后顺序,有时候检查代码发现逻辑并无错误而一直出错时可以考虑是否是寄存器配置出现了并不在预想中的问题。