51单片机定时器
字数统计:966 阅读时长 ≈ 3分钟51单片机定时器工作原理
1. 模式0:13位计数器模式
在某一个初值的基础上加 1 计数,当计数器计满为全“1”,再来一个计数脉冲时,就产生一个“溢出中断信号”TF1=1。
注:由于低 8 位计数器中的高三位没有参与工作,故填装初值时应“避开”此三位。
2.模式 1:16 位定时/计数模式
类同于模式 0,由于两个计数器为完整的 8 位,故将计算好的 16 位初值可直接填装到 TH、TL 中。
3.模式2:8 位自动重装初值模式
TL 做计数器,TH 做初值寄存器,工作前 TL1,TH1 分别预置相同的初值,TL1 计数时,产生溢出的同时,将 TH1 中的初值自动重装 TL1,TL1 继续计数。
4.模式 3:组合扩展模式(仅适用于 T0)
将 T0 和 T1 重新进行“拆分、组合”,将 T0 变为由 TH0,TL0 组成的两个独立的 8 位定时/计数器。
四种模式比较
工作方式0:13位定时器/计数器工作模式,最多可计数2的13次方次,即:8192次
工作方式1:16位定时器/计数器工作模式,最多可计数2的16次方次,即:65536次
工作方式2:8位定时器/计数器工作模式,最多可计数2的8次方次,即:256次
工作方式3:8位定时器/计数器工作模式,最多可计数2的8次方次,即:256次
定时器初值
以12M晶振为例:每秒钟可以执行1000000次机器周期个机器周期。而定时器每次溢出 最多65536 个机器周期。
那么对12MHz的晶振来讲
1个机器周期 1us ( 12/fosc = 1us)
方式0 13位定时器最大时间间隔 = 2^13 = 8.192ms
方式1 16位定时器最大时间间隔 = 2^16 = 65.536ms
方式2 8位定时器最大时间间隔 = 2^8 = 0.256ms =256 us
方式3 8位定时器最大时间间隔 = 2^8 = 0.256ms =256 us
以上是对定时器定时的最大时间间隔做一个说明,下面具体说明怎么计算初值(小于最大时间间隔)假如定时10ms那么的定时器初值计算如下:
当使用12M晶振,12MHz除12为1MHz,也就是说一秒=1000000次机器周期。10ms=10000次 机器周期。
预置数的计算公式:
预置数=最大值-需要计数的次数
(65536-10000)
再将预置数装入16位定时计数器,如下:
TH0=(65536-10000)/256
TL0=(65536-10000)%256
当使用11.0592M晶振,11.0592MHz除12为921600Hz,就是一秒921600次机器周期,10ms=9216次机器周期。
预置数的计算公式:预置数=最大值-需要计数的次数
(65536-9216)
再将预置数装入16位定时计数器,如下:
TH0=(65536-9216)/256
TL0=(65536-9216)%256
编程
1. TMOD : 定时器工作方式
51单片机共有2个定时器:T1、T0
所以TMOD有8个bit,高四位控制 T1,、低四位控制 T0。
工作方式设置:
TMOD = 0x00(工作方式0)
TMOD = 0x01(工作方式1)
TMOD = 0x02(工作方式2)
TMOD = 0x03(工作方式3)
以上是控制低4位的,所以是对应着T0,高4位控制如下:
TMOD = 0x00(工作方式0)
TMOD = 0x10(工作方式1)
TMOD = 0x20(工作方式2)
TMOD = 0x30(工作方式3)
2. TRx:Tx使能
对于定时器T0
TR0 = 1,开始工作
TR0 = 0,停止工作
对于定时器T1
TR1 = 1,开始工作
TR1 = 0,停止工作
3. ETx:Tx中断开关
定时时间一到,就会跑去中断程序。
对于T1:
ET0 = 1,中断使能
ET0 = 0,中断失能
4. EA :中断总开关
你可以想象成电路的总电闸,EA=1,中断使能; =0,中断失能。
5. THx,TLx : Tx定时器计数寄存器
组成16位的计数:
0x0000--0xFFFF(0--65535)
只要TH0TL0=0xFFFF(65535),将会运行中断程序
在中断程序中,我们要重新给TH0,TL0重新赋值的
假设定时50毫秒,TH0,TL0的计算方法如下:
TH0,TL0,组成的16位计数器计数范围是 0-65535 。
50ms = 50 000us
只要让 TH0 TL0 从(65535 - 50000)开始计数,TH0,TL0就会不停的+1
直到TH0,TL0=65535,就是计数了50000次,时间就是过了50ms。
我们只要在中断程序里面,重新赋值给TH0,TL0=(65535 - 50000),定时器就会不停得每50ms中断一次了。
所以,TH0=(65535-50000)/256; TL0 = (65535-50000)%256 ;
程序:模式1
// T0中断服务函数
void T0_ISR() interrupt 1
{
TH0=(65536-16)/256; //重新给定时器计数器赋值
TL0=(65536-16)%256;
}
// T0中断init
void T0_init()
{
TMOD=0x02; // T0模式:1
TH0=(256-16)/256; // 设置计时
TL0=(256-16)%256;
TR0=1; // 使能开关
ET0=1; // 中断开关
EA=1; // 中断总开关
}
main()
{
T0_init();
while(1);
}
(TMOD = 0x01, ET0 ,TR0,TH0,TL0 ,interrput 1) 改为
(TMOD = 0x10, ET1 ,TR1,TH1,TL1 ,interrput 3) 这样就变成了T1,定时器的程序。
本文由simyng创作,
采用知识共享署名4.0 国际许可协议进行许可,转载前请务必署名
文章最后更新时间为:December 28th , 2020 at 07:12 pm