2009_0326 – 简单调用timer2

timer2是52单片机比51型多出来的一个计时器(计数器),不过timer2的功能远不止是计时和计数这两个,所以之前一直弄不出来就是因为没注意到这点,而只将timer2认为是一个简单的16位资源,错误认为其调用也和timer0及timer1相同,其实不然,查看过datasheet后发现光是timer2的control寄存器T2CON的八个位的安排就与前面两个计数器(计时器)不相同。所以,花了点时间研究datasheet,学习了一下这个寄存器的设置,今天就弄了出来。

// use timer2 in an easy way

#include <reg52.h>
sbit P1_0 = P1^0;
sfr T2MOD = 0xC9;

main()
{
    T2MOD = 0x00;
    T2CON = 0x08;
    TH2 = 0xff00; TL2 = 0xff00;
    RCAP2H = 0xff00; RCAP2L = 0xff00;
    EA = 1; ET2 = 1;
    TR2 = 1;

    while(1);
}

void change(void) interrupt 5
{
    TF2 = 0;
    P1_0 = !P1_0;
}

程序中要三处加重的地方我之前一直没弄出来,经过datasheet的学习才发现其中的奥妙:
1.sfr T2MOD = 0xC9;
T2MOD
timer2的模式控制寄存器T2MOD其实没有多大的设置意义,顶多就是对其中DCEN位进行设置。DCEN全称decreasement enable即“递减使能”,设置为1的时候允许在计时时递减计时,相反,设置为0的时候就是递增计时。而出了这一个位,T2MOD的其它位都没有什么利用的价值(至少datasheet上没有说明其他位的具体用法,只是说允许用户自己设定),这个DCEN位又可以独立设置电平,所以整个T2MOD在reg51.h文件中都没有独立设置其地址。所以,如果在程序中要设置整个T2MOD的话,要在主程序之前给T2MOD设置全局变量的入口地址,就是0xc9,否则在主程序中调用会被编译器提醒没有T2MOD这个变量。

2.RCAP2H = 0xff00; RCAP2L = 0xff00;
之前我一直认为timer2的自动重装也就是给TH2和TL2重装原来的数罢了,所以写了两行这两个特殊功能寄存器的赋值,当然编译出来是错的。datasheet中讲到,要给timer2的TH2及TL2重新装入数值,必须把待装的数值存入RCAP2H以及RCAP2L这两个特殊功能寄存器,其实从电路图上可以更清楚地看出这样设置的原因:(图中红圈内)
auto_reload_mode 

3.TF2 = 0;
这点也是timer2与同样具有自动重装功能的timer0 timer1工作方式2不同的地方。0和1timer的工作方式2在计时满时相应的TF位会溢出,但进入中断处理后硬件会自动将其清零(当然如果使用查询的方式就得软件清零),但timer2的这个TF2位即使进入中断,也要软件清零,否则无法进入下一个计数周期。

Leave a comment