关于89C52单片机11.0592M晶振产生115200波特率的方法

当然下面所讨论产生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的单片机。。。哈哈。。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值