51单片机共有两个定时器,T0与T1,包含计数和定时两种模式,使用定时器需要设置的寄存器如下
1.TMOD
TMOD寄存器低四位为T0模式选择 高四位为T1
GATE——门控制。
GATE=1时,由外部中断引脚INT0、INT1来启动定时器T0、T1。 当INT0引脚为高电平时TR0置位,启动定时器T0; 当INT1引脚为高电平时TR1置位,启动定时器T1。 GATE=0时,仅由TR0,TR1置位分别启动定时器T0、T1。
C/T——功能选择位
C/T=0时为定时功能,C/T=1时为计数功能。 置位时选择计数功能,清零时选择定时功能。
M0、M1——方式选择功能 由于有2位,因此有4种工作方式:
M1M0 工作方式 计数器模式 TMOD(设置定时器模式)
0 0 方式0 13位计数器 ,很少使用,兼容早期单片机
0 1 方式1 16位计数器 ,TH为高八位 TL0为低八位,这种模式下,在中断中要么重新赋值,要么关闭定时器
1 0 方式2 自动重装8位计数器 TH保留一个值,TL计数溢出之后,在中断发生的时候自动重装,所以要是定时器中断很长,记住在中断进入的时候关闭,否则会造成中断嵌套
1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器 (很少使用)
2.TH0 TL0赋值(51单片机计数器向上计数,属于溢出型)
2.EA ET分别打开中断
3.TR,用于启动定时器
(T1一般当作串口的波特率发生器)
示例代码如下
#include "timer.h" //1ms֨ʱǷ݆˽ //11059200ƵÊ 1us ԼֈԚ1לǚ 1msղΪ1000 ֨ʱǷԵֵ65535-1000 ɭݾט //ܲ֟ؔ֯ט,200usһՎ,ɭݾŚҿנՎ݆˽ //ch 0 tim0 1 tim1 //mode 1 timecount 0 trig count void TimeInit(u8 ch ,u8 mode) { u8 value = TMOD; switch(ch) { case 0: if(mode) { value &= 0xf0;//clear t0 value |= 0x02;//mode2 time count } else { value &= 0xf0;//clear t0 value |= 0x06;//mode2 trig count } TMOD = value; TH0 = 255-200;//200 clk TL0 = 255-200; EA = 1; ET0 = 1; TR0 = 1; break; case 1: if(mode) { value &= 0x0F;//clear t1 value |= 0x20;//mode2 time count } else { value &= 0x0F;//clear t1 value |= 0x60;//mode2 trig count } TMOD = value; TH1 = 255-100;//100 clk TL1 = 255-100; EA = 1; ET1 = 1; TR1 = 1; break; } } u32 t0Count = 0; void Time0Handler(void) interrupt 1 { t0Count++; if(t0Count == 500) { //user do } if(t0Count == 1000) { //user do t0Count = 0; } } u32 t1Count = 0; void Time1Handler(void) interrupt 3 { t1Count++; if(t1Count == 500) { //user do } if(t1Count == 1000) { //user do t1Count = 0; } TF1=0; //clear flag }