标准51单片机在任意时钟频率下产生任意波特率的独特方法
2017-03-17林志琦任超越
林志琦, 任超越, 张 睿
(长春工业大学 电气与电子工程学院, 吉林 长春 130012)
0 引 言
随着计算机网络化与微机分级分布式应用系统的发展,通信在各方面显得尤为重要。通信是指计算机与外界进行信息传输,既包含计算机和计算机之间的传输,也包括计算机和外部设备,例如终端、扫描仪和移动硬盘等设备之间的传输[1]。单片机的串口通信是自动化工业、智能终端、光电系统等领域非常重要的信息传输手段。在光电系统中,单片机一般充当控制器的角色,通过串口发送一定格式的数据来控制与之相连设备的动作,同时设备也会将一些自身的状态信息反馈给单片机,供单片机进行判断并进行相应的控制[2]。例如对云台的控制,当键盘输入信息时,单片机和软件相互配合对信息进行识别,根据所识别的信息向云台中的步进电机发出指令,实现对方向角、俯仰角控制、速度控制和程序控制等功能[3]。云台控制器通常以单片机为核心,通过单片机串口通信实现控制。
文中对标准51单片机串口数据传输的方式进行了改进。标准51单片机在进行串口传输数据时存在不足,当串口传输速度增加时,波特率误差将会增大,随着误差的增大,传输的数据会出现错误,直接影响了串口传输的质量。文中经过对标准51单片机传输方式的改进,串口波特率误差明显减小,串口传输质量显著提高。
1 51单片机的结构及传输方式
标准的51单片机有2个16位的定时计数器,2个外部中断,5个中断源,1个全双工的异步串行通信接口[4]。在标准的51单片机中,没有专门的波特率发生器,而是由定时计数器T1的溢出作为串口数据传输的定时基准。在标准51单片机刚推出时,串口的数据传输速率在300~2 400 bit/s,传输每位二进制数的时间在416~3 300 μs之间,而当时的51单片机指令周期为1 μs,采用8位自动加载的工作方式时,最大溢出时间为256 μs,不能达到传输一位数据所需的时间。为了满足416~3 300 μs的定时时间,标准51单片机的设计者在定时T1的溢出与串行数据收发移位寄存器之间加入了一个16/32进制可选的计数器,对定时计数器的溢出进行分频,使其定时时间得到延长,从而满足416~3 300 μs的定时需求[5],其工作原理如图1所示。
图1 51单片机波特率发生器工作原理图
2 标准51单片机串口传输的误差分析
标准51单片机每计一个数的时间为一个机器周期,一个机器周期等于12个时钟周期,如果用12 MHz晶振时产生9 600 bit/s的波特率,其误差为3.3%,它是指传输一位数据的误差,当传输一帧数据时的误差为33%,随着误差的增大,传输的数据会出现错误,其误差过大的原因如下:
采用波特率计算公式:
(1)
(2)
式中:X----定时器初值。
这里以晶振频率12 MHz,SMOD=0,波特率=9 600 bit/s为例, 根据式(1)、式(2)推导出:
(3)
由式(3)可以看出,如果定时器初值X想得到一个整数值,那么晶振频率必须是波特率乘以32再乘以12的整数倍,通过计算可知6、12、 24 MHz等晶振频率都不是波特率乘以32再乘以12的整数倍,所以X不可能为整数值,然而在装载定时器初值时,X必须为整数(因为单片机计时时只能记录整数个时钟周期),所以产生误差,其误差产生的来源是由于T1溢出率存在误差。选择9 600 bit/s的波特率,传送一个位数据所需要的时间为104.167 μs,那么
(4)
其中,T1溢出率在6、12、24 MHz等晶振频率下(见图1),经过16分频和2分频,在SMOD=0时,根据式(4)T1的误差放大了32倍,造成了误差大于3.3%无法发送准确数据的情况,所以51单片机在6、12、24 MHz等晶振频率下无法产生任意波特率。
由于标准的51单片机的这种结构,当串口通信速度由300~2 400 bit/s提高到9 600~115 200 bit/s,甚至256 000 bit/s时,就会出现误差大于3.3%的情况,这也是标准51单片机设计的一个缺陷。以9 600 bit/s的波特率为例进行分析。9 600 bit/s的串行数据传输速率,传输每位二进制数据所需的时间为1/9 600=104.167 μs,这时要求T1的溢出时间为104.167 μs/32=3.255 μs或104.167 μs/16=6.510 μs,在通常的12 MHz时钟频率下,计数时间单位是1 μs,要产生3.255 μs或6.510 μs的延时,只能用3 μs或4 μs近似,这时的误差为
和
这样采取舍入的方法误差见表1。
由表1可见,误差已超过了最大误差3.3%。标准51单片机发送一帧数据时,每3位检测一次,以每个数据帧10位数据,能识别的最大误差为33%计算,则每个数据位的误差应小于(33%)/10=3.3%。
表1 在时钟频率为12 MHz、波特率为9 600 bit/s的情况下传输每位二进制数的时间误差
通过上面的分析知道,在波特率增加后,每位二进制数据位的传输时间变短,而这个时间的16或32分之一就更小,而这时定时计数器以1 μs为时间单位的情况下,小数点后面的舍取对定时时间的影响很大,即这个误差被放大了16倍或32倍[6]。定时时间大一个或小一个时间单位,它们的误差都超过了3.3%。也就是由于标准51单片机波特率产生方式的特殊结构,在6、12、24 MHz等时频都超过了3.3%。也就是说,由于标准51单片机波特率产生方式的特殊结构,在6、12、24 MHz等时频率下产生不了任意的波特率。
在实际工作中,通常采用可行的方法是选择一个小数时钟频率,如11.059 2 MHz,或22.118 4 MHz,此时可以产生9 600,19 200和38 400的波特率,但很难产生57 600和115 200等其他波特率。同时由于采用非整数时钟频率,使得定时很难产生整数的定时时间。而在标准的51单片机中为了产生整数的定时时间,通常采用6、12、24 MHz等时钟频率,为了解决这一矛盾,文中提出了一种可以让标准51单片机在6、12、24 MHz等时钟频率下产生任意波特率的独特、新颖的方法。
3 任意时钟频率下产生任意的波特率的方法
由以上分析可知,产生波特率误差的原因由于对定时器T1的溢出时间进行了1/16或1/32的分频,使得定时器T1的溢出时间变短并且带有小数,同时误差也被放大了,实现这种去掉误差放大现象的方法如图2所示。
(a) 累积误差
(b) 特殊方法
(c) 自动重新加载
标准51单片机的波特率累计误差信号的产生见图2(a),从图中可以看到,收发一位串行数据的时间被平均分为16份或32份,这样对每份的精度要求就提高了很多,如果采取特殊的方法,不是平均分配每次溢出的时间,那么就可以减小对每次溢出的精度要求,基于这种想法,我们将16次(或32次)溢出分为两部分,一部分是连续的快速15次(或31次)溢出[7],此时定时器T1的初值为0FFH,定时器只需一个定时脉冲就可以溢出,这样需要15个(或31个)时间单位,另外一部分定时时间为串行数据传输一位所需的时间减去那15(或31个)个单位时间,此时上电初始化的TL1的值由这个时间确定:
(5)
标准51单片机的定时器工作方式为自动重新加载方式[8],开始定时由TL1中的初值开始进行加计数,加到0FFH后再加一溢出,同时把其他TH1中的数值0FFH自动加载到TL1中,继续进行第二次定时,在上电初始化时TL1满足传输一位二进制数减去15(或31)的定时时间值,这样就可以高精度的实现总的溢出时间为传输一位二进制数时间的波特率(发生器见图2(b))。当然还有一个最大的问题,这种方法只能产生一次,满足要求的波特率发生器定时,因为除了第一次的定时时间为初始化时的TL1值外,以后就都是由重新加载值0FFH了,为了重复以上过程,不断产生满足要求的波特率信号,在连续送15(31)次连续快速的溢出后要重新初始化一次TL1,这个任务由定时器T0完成[9]。
将T0定时时间为传输一帧数据的时间[10]。在T0中断服务程序中,对TL1重新初始化一次,TH1仍然保持0FFH不变,就可以使上面的高精度波特率发生过程不断重复下去(见图2(c))。
经过在多种型号的标准51单片机上实验验证时得到的实验数据见表2。
表2 标准51单片机在6、12、24 MHz的时钟频率下产生任意的波特率的初始值
根据实验,传输一位数据的时间波形如图3所示。
(a) 改善之前
(b) 改善之后
没有改进之前的波形见图3(a),传输一位数据所需要的时间为94.57 μs,而理论上波特率为9 600时,所需要的时间为104.167 μs,此时传输每位二进制数的误差为-9.21%。不能准确收发数据,改进之后传输数据波形见图3(b)。传输一位数据所需要的时间为104.63 μs,此时传输每位二进制数据的误差为0.44%;数据收发无误。
标准51单片机在6、12、24 MHz的时钟频率下产生任意的波特率的测试程序:
#include
void main (void)
{
PCON = 0x80;
SCON = 0x50;/* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x22; /* TMOD: timer 1, timer 0, mode 2, 8bit reload */
TH1 = 0xff; /* TH1: reload value for 1200 baud @ 16MHz */
TL1 = 237; /*show tab 1*/
TH0 = 231; /*abut baud show tab 1 */
TL0 = 231; /*show tab 1*/
TCON = 0x50; /* :timer 1 & timer 0 run whih one time */
PT0 = 1;
ET0 = 1;
EA = 1;
while (1) { /* test progrqm loop output to uart 0~255 */
char i;
for(i=0;i<255;i++)
{
SBUF=i;
while (!TI)
{}
TI=0;
}
}
}
void plus_int1(void) interrupt 1
{
TL1 = 237; /*show tab 1*/
}
4 结 语
根据标准51单片机串口传输的缺陷,提出了文中特殊改进方法,并介绍了这种特殊方法的工作原理。实验结果证明,对标准51单片机串口传输的方式改进后,串口传输一位的误差为0.44%,相比改进之前的误差有了明显的改善。实现了标准51单片机在6、12、24 MHz等时钟频率下能够产生任意的波特率。
[1] 李鹏.MCS-51系列单片机串行通信波特率的研究[J].电脑知识与技术,2013(28):6265-6267.
[2] 宣明.微型机械及相关理论和技术[J].光学精密工程,1994,2(3):1-5.
[3] 韩双喜.基于DSP的运动姿态控制系统设计[J].世界电子元器件,2013(2):44-47.
[4] 陈粤初,窦振中.单片机应用系统设计与实践[M].北京:北京航空航天大学出版社,1991.
[5] 李会杰,李俊廷,张伟,等.一种51系列单片机的解密方法[J].长春工业大学学报,2017,38(4):335-339.
[6] 于建群,王立鼎,刘军山.集成毛细血管电泳芯片的结构及其制作技术研究进展[J].中国机械工程,2003,14(2):166-175.
[7] 徐骏平,胡兵,马平化,等.USB接口技术在激光打标中的应用[J].激光杂志,2006,27(3):77-78.
[8] 陈翠华,柴金华.模数转换与波特率设置对大气激光语音通信质量的影响[J].量子电子学报,2006,32(2):225-230.
[9] 林志琦,李会杰,郎永辉,等.用四象限光电探测器获得光斑参数[J].光学精密工程,2009,17(4):764-770.
[10] 张新宝,王海璇,周胜利,等.基于串口提高MCU-51矩形单脉冲脉宽精度的方法[J].吉林大学学报,2016,34(4):496-500.