通常情况下,8051系列单片机外接晶振频率一般是12MHz、24MHz、48MHz如图7-6-1,为什么会这样选取呢?从前面的章节已经介绍8051系列单片机的每12个时钟周期为一个指令周期,当8051系列单片机外接12MHz晶振时,指令周期=12/12MHz=1us;若外接24MHz晶振时,指令周期=12/24MHz=0.5us;若外接48MHz晶振时,指令周期=12/48MHz=0.25us。8051系列单片机外接能够被除尽的晶振,在使用单片机内部的定时器/计数器资源时作定时器使用时能够得到精确定时应用;当使用汇编语言编程时,可以清楚知道当前每一行代码执行的时间。
8051系列单片机外接能够被除尽的晶振即12MHz、24MHz、48MHz这些晶振时,波特率的精确性就得不到保证。
假若现在单片机外接的晶振为12MHz时,以T/C2作波特率发生器,根据波特率公式:
波特率=Fosc/2x16x(65536-t)
9600=12MHz/2x16x(65536-t)
t=65496.9375
“65496.9375”不是一个整数值,是一个带有小数点的数值。对于常用的8位、9位、11位一帧的数据接收与传输,最大的允许误差分别是6.25%、5.56%、4.5%。虽然波特率允许误差,但是这样通信时便会产生积累误差,进而影响数据的正确性。唯一的解决办法就是更改单片机外接的晶振频率,更改为常用于产生精确波特率的晶振如11.0592MHz、22.1184MHz。
假若现在单片机外接的晶振为11.0592MHz时,以T/C2作波特率发生器,根据波特率公式:
波特率=Fosc/2x16x(65536-t)
9600=11.0592MHz/2x16x(65536-t)
t=65500=0xFFDC
虽然使用11.0592MHz、22.1184MHz的晶振能够产生精确的波特率,但是用于系统精确的定时服务不是十分的理想。例如单片机外接11.0592MHz晶振时,指令周期=12/11.0592MHz≈1.085us,是一个无限循环的小数。当单片机外接22.1184MHz晶振时,指令周期=12/22.1184MHz≈0.5425us,也是一个无限循环的小数。
串口工作在方式1时分别采用T/C1和T/C2产生常用波特率初值表如下。
波特率 (11.0592MHz) |
初值 |
波特率 (12MHz) |
初值 |
||
TH1、TL1 (SMOD=0) |
TH1、TL1 (SMOD=1) |
TH1、TL1 (SMOD=0) |
TH1、TL1 (SMOD=1) |
||
1200 |
0xE7 |
0xD0 |
1200 |
0xE5 |
0xCB |
2400 |
0xF3 |
0xE7 |
2400 |
0xF2 |
0xE5 |
4800 |
0xF9 |
0xF3 |
4800 |
0xF9 |
0xF2 |
9600 |
0xFC |
0xF9 |
9600 |
0xFC |
0xF9 |
14400 |
0xFD |
0xFB |
14400 |
0xFD |
0xFB |
19200 |
0xFE |
0xFC |
19200 |
0xFE |
0xFC |
波特率 (11.0592MHz) |
初值 |
波特率 (12MHz) |
初值 |
||
RCAL2H |
RCAL2L |
RCAL2H |
RCAL2L |
||
1200 |
0xFE |
0xE0 |
1200 |
0xFE |
0xC8 |
2400 |
0xFF |
0x70 |
2400 |
0xFF |
0x64 |
4800 |
0xFF |
0xD8 |
4800 |
0xFF |
0xB2 |
9600 |
0xFF |
0xDC |
9600 |
0xFF |
0xD9 |
14400 |
0xFF |
0xE8 |
14400 |
0xFF |
0xE6 |
19200 |
0xFF |
0xEE |
19200 |
0xFF |
0xED |
如果大家想通过设置不同的晶振获取更加多的波特率的值,可以下载工具进行计算