定时器的作用:精准定时,在定时器在嵌入式中有什么作用?也是非常的好奇,我想到的是定时器+中断,在定时器计时的这段时间,CPU可以去忙别的事情,不必一直盯着然后等待事情的发生。还有别的什么用途没。
一,测试代码
根据官方提供驱动代码测试 程序
我测试ok,接着详细了解
二,定时器相关寄存器
看手册最主要的就是掌握寄存器的使用,也是看家本领,与32不同的是,根据参考代码去研究寄存器,真的与32有很大不同,一堆指针和结构体,根据库函数去驱动,也来越有意思了嘿嘿
STC15W104拥有的定时器资源:定时器0 定时器2
AUXR
为了很好解释AUXR的作用,看结构图理解,可以理解为定时器计数的频率
T0X12=1,不分频,计数频率为时钟频率;T0x12=0,计数频率=时钟频率/12
TMOD
主要是用来设置定时器的工作模式
C/T 置1时当做计数器,置0时用做定时器 | ||
M1 | M0 | 模式选择 |
0 | 0 | 16位自动重装定时器,溢出时将值重新装入TH0和TR0 |
0 | 1 | 16位不可重装模式 |
1 | 0 | 8位自动重装,溢出时将TH0存放的值自动装入TL0 |
1 | 1 | 不可屏蔽中断的16位自动重装定时器 |
TL0 TH0
这两个寄存器的值是需要手动计算,表示定时的时长,并且填充到寄存器,配合定时器的工作模式,溢出时是否重装
TCON
控制定时器1和定时器0的控制寄存器,主要讲解和定时器0有关的控制位
TR0 | 该位由软件置位或清零,TR0=1,定时器0开始计数,TR0=0,禁止定时器计数 |
TF0 | 定时器中断标志位,定时器0溢出时,由硬件置1,CPU响应中断时,由硬件置0 |
有个问题,在范例代码中使用reg51.h的库文件,我到底该使用哪个,我倒是觉得都可以
//reg51.h
/* TCON */
sbit TF1 = 0x8F;
sbit TR1 = 0x8E;
sbit TF0 = 0x8D;
sbit TR0 = 0x8C;
sbit IE1 = 0x8B;
sbit IT1 = 0x8A;
sbit IE0 = 0x89;
sbit IT0 = 0x88;
//STC15WXX.H
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;
IE
定时器1和定时器0的中断控制寄存器
各中断源首先受EA控制,其还受各中断源自己的中断允许控制位控制
定时器的驱动流程
- 设置定时器的时钟和工作模式
- 给TH0和TL0赋初值
- 打开定时器(TR0=1),并且打开中断EA=1,ET0=1,
- 定时器溢出,TF0=1, 检查中断允许位是否开启,若ET0=1,执行中断函数,并且TF0=0,否则TF0=0
三,定时器计数时间的计算
首先确定定时器的工作频率。烧录软件确定单片机时钟频率T,再由AUXR确定定时器的工作频率
若是AUXR = 1T ,定时器工作频率=T/1 定时器溢出最大时间 = 65536 / T(单位:s)
单位计数时间 = 1 / 工作频率 (单位:s)
若AUXR = 12T , 定时器工作频率 = T/12 定时器溢出最大时间 = 65536 / ( T/12 ) (单位:s)
单位计数时间 = 1 / ( T/12 ) (单位:s)
计算完才发现与32 非常不同,32有自动重装载寄存器,只需要定义目标值,然后由计数器增加到目标值即可,单片机非常的不同,首先判断定时器溢出的最大时长,如果目标时长为20ms,根据单片机频率计算出定时器在不同频率下的最大时长,可自己根据结果调节单片机频率,对于需要计时秒的,单片机频率越小越好
确定好最大时长后,选取适合的定时器频率,根据以下计算结果确定TH0和TL0的值
单片机工作模式5.5296MHZ, 定时时长分别是400us 1.2ms 12.4ms 确定TH0 TL0的值。
AUXR=T1 最大时长=65536 / 5529600 = 11.851 ms
AUXR = 12T 最大时长= 142.222ms
都没有超过最大时长的范围,我倒是觉得都可以,12T为例,
计时1ms 需要计数:(T/12) / 1000 = 460
计时1us需要计数:(T/12) / 1000000=0
上面那种算法有误差,列式计算比较好
12.4ms 12.4 / ((12 / T) * 1000) = 5713 TH0 TL0 =65536 - 5713 = 59832 E9AF
1.2ms 1.2 / ((12 / T) * 1000) = 552
400us 400 / ((12 / T) * 1000000) = 184
// 1.选择时钟模式 2.定时器工作模式 3.赋初值 4.开启定时器和定时器中断
AUXR |= 0x80; //定时器0为1T模式
// AUXR &= 0x7f; //定时器0为12T模式
TMOD = 0x00; //设置定时器为模式0(16位自动重装载)
TL0 = T1MS; //初始化计时值
TH0 = T1MS >> 8;
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;