当然下面所讨论产生115200波特率的最大难题就是因为它的时钟周期是等于12个机器周期的(12T模式)
定时器T1要想作为波特率发生器,必须是工作在8位自动重装载模式下,并且禁止使能T1的中断!
还有一个重要的寄存器就是PCON了,最高位SMOD可以使得波特率加倍!当然这里由于这里的8位自动重装载模式的限制,也并不是像我们想象的那样,既然可以产生9600的波特率那个加倍以下不就是115200了嘛?!
Too young, Too simple!
先看两个公式吧,,
当波特率不加倍使用定时器T1,产生波特率的计算方法:
TH1 = TL1 = 256 - 晶振值/12/2/16/波特率
使用波特率加倍后的计算公式为:
TH1 = TL1 = 256 - 晶振值/12/16/波特率
当我们不加倍的时候,产生的最大波特率(让TH1 = 0xFF)
28800
加倍后产生的最大波特率为57600(刚好就是28800的两倍)
所以就增强型的51单片机89C52来说,T0是可定不能作为波特率发生器的,而T1貌似又达不到要求,没辙了吗? 别忘了,它还有T2呢!!!
先来简单的认识一下T2及其有关的寄存器!
先看主要的,咱们要用的!
①作为波特率发生器
T2CON的TCLK和RCLK位为0(默认)时,串行口发送和接受的波特率由定时器1提供;置位为1时,由定时器2提供。可以一个通过定时器1,一个通过定时器2,这样可以获得发送和接受时不同的波特率。
注意的地方: 定时器2作为定时器时,递增频率为晶振频率的12分频,而定时器2作为波特率发生器时,它的递增频率为晶振频率的2分频。
定时器2作为波特率发生器的时候,TH2溢出并不会置位TF2,所以此时可以不用禁止定时器2中断,若是EXEN2位被置位时,可以将T2EX作为附加的外部中断。。
定时器2作为波特率发生器的时候,不要对TH2和TL2读写,可以读陷阱寄存器,但是也不要写。当对定时器2的陷阱寄存器进行访问时,应关闭定时器(TR2清0)。
波特率 = 模式1和模式3的波特率=(振荡器频率/32) * [65535-(RCAP2H,RCAP2L)]
115200时对应的初值
#include <reg52.h>
#include <stdio.h>
void init_com( void )
{
SCON=0x50;
TH2=0xFF;
TL2=0xFD;
RCAP2H=0xFF;
RCAP2L=0xFD;
/*****************/
TCLK=1;
RCLK=1;
C_T2=0;
EXEN2=0;
/*****************/
TR2=1 ;
TI = 1;
}
void main()
{
init_com();
while(1)
{
printf("Hello World\n");
}
}
然后再次选择115200的波特率实验现象
emmmmm,本来写到这里这篇算是完结了,,但是突然的收尾似乎显得有点意犹未尽,,没错,想说的还没说完,继续造起来,一起来再来领悟一下神奇的T2以及探索一下还有哪些神奇的操作。。。
继续来看T2吧,
对了,它自身定时功能。。
16位自动重装模式中,定时器2可通过C/T2位配置为定时器/计数器,根据外部使能标志位EXEN2的置位和清0,可分为两种情况:
<1>EXEN2=0时
定时器2为16位自动重装的普通定时器,由陷阱寄存器提供重装的值,只需要预设一下即可,可用于定时精度要求高,定时时间长(16位)的情况。
<2>EXEN2=1时,根据递减计数使能位DCEN的置位和清0可分为两种情况:
A1、T2MOD=0x00(DCEN=0;默认情况);
与上一种情况相比,此时16位自动重新装载可由外部T2EX的负跳变,和溢出任意一种触发,并都能产生中断。
A2、T2MOD=0x01(DCEN=1);
此时允许T2EX控制计数的方向;T2EX=0时,重装的值为0FF和0FF,递减计数与陷阱寄存器预存值相等时,置位TF2产生中断。T2EX=1时;自动重装值为陷阱寄存器中的值,溢出时置位TF2产生中断。
#include "reg51.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//-----------------------------------------------
/* define constants */
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) //1ms timer calculation method in 12T mode
/* define SFR */
sbit ET2 = IE^5;
sfr T2CON = 0xc8; //timer2 control register
sbit TF2 = T2CON^7;
sbit TR2 = T2CON^2;
sfr T2MOD = 0xc9; //timer2 mode register
sfr RCAP2L = 0xca;
sfr RCAP2H = 0xcb;
sfr TL2 = 0xcc;
sfr TH2 = 0xcd;
sbit TEST_LED = P1^0; //work LED, flash once per second
/* define variables */
WORD count; //1000 times counter
//-----------------------------------------------
/* Timer2 interrupt routine */
void tm2_isr() interrupt 5 using 1
{
TF2 = 0;
if (count-- == 0) //1ms * 1000 -> 1s
{
count = 1000; //reset counter
TEST_LED = ! TEST_LED; //work LED flash
}
}
//-----------------------------------------------
/* main program */
void main()
{
RCAP2L = TL2 = T1MS; //initial timer2 low byte
RCAP2H = TH2 = T1MS >> 8; //initial timer2 high byte
TR2 = 1; //timer2 start running
ET2 = 1; //enable timer2 interrupt
EA = 1; //open global interrupt switch
count = 0; //initial counter
while (1); //loop
}
②当然不外乎还有时钟输出功能
可参考这里看下其他时钟输出
52系列单片机,可设定定时器/计数器2通过T2(p1^0)引脚输出时钟。
P1^0除了可以作为普通I/O口外,还可以作为定时器2的外部计数输入和时钟信号输出。
C/T2=0并且T2MOD的T2OE位为1时,可将定时器2选为时钟信号发生器,自动装初值。设置公式:
时钟信号输出频率=(振荡器频率/4)* (65535-N)
在时钟输出模式下,计数器溢出不会产生中断请求。这种功能相当于定时器2可同时作为波特率发生器和时钟发生器。
因为此时外部中断并没有被暂用,若是在设置上不冲突的话可能同时还可以响应T2EX引入的外部信号,这个只是猜想,还没有用实验证明过,哈哈*
注:单片机对于外来脉冲信号具有计数功能,但是有要求: 计数脉冲的最高频率=振荡器的频率/24
并且为了确保给定电平在电平变化之前能被采样一次,则这个电平至少要维持一个机器周期。
#include "reg51.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//-----------------------------------------------
/* define constants */
#define FOSC 11059200L
#define F38_4KHz (65536-18432000/4/38400)
/* define SFR */
sfr T2CON = 0xc8; //timer2 control register
sbit TF2 = T2CON^7;
sbit TR2 = T2CON^2;
sfr T2MOD = 0xc9; //timer2 mode register
sfr RCAP2L = 0xca;
sfr RCAP2H = 0xcb;
sfr TL2 = 0xcc;
sfr TH2 = 0xcd;
sbit T2 = P1^0; //Clock Output pin
//-----------------------------------------------
/* main program */
void main()
{
T2MOD = 0x02; //enable timer2 output clock
RCAP2L = TL2 = F38_4KHz; //initial timer2 low byte
RCAP2H = TH2 = F38_4KHz >> 8; //initial timer2 high byte
TR2 = 1; //timer2 start running
EA = 1; //open global interrupt switch
while (1); //loop
}
其实,额,,虽然51很是LOW,但是有限的资源玩的花了,有了更多更大的资源后,也更能会合理利用,那才是本事对不对。。。
嗯,就是这样。。
对了,除了T2还有哪些种方法嘞?
1,把11.0592M换成22.1184M晶振。那么当在TH1=0xff时,刚好可以产生115200波特率。
2、换个IT的单片机。。。哈哈。。