定时器_计数器的介绍与使用
在介绍定时器之前我们先放一张表格,我们会反复用到
定时功能与计数器功能
定时功能:所谓定时功能其本质就是对来自于单片机内部的时钟脉冲作为计数脉冲,使计数器计数,即按照设定值加一,当计数值达到设置的值后,定时/计数模块产生溢出。
计数器功能:所谓计数器功能就是对外部事件进行计数,外部事件的发生以输入脉冲表示(引脚为RA4/TOCKI,RC0)
定时功能对内部脉冲进行计数,计数功能对外部脉冲进行计数
PIC887单片机配置有三个定时器/计数器模块,分别为:TMR0,TMR1和TMR2。
三个定时器/计数器共同点:按照递增方式进行累加工作,累加到计数器溢出,同时产生一个对应的溢出中断标志(和上节课中断有关)
异同点可以看看图:
预分频:实现计数/记时范围的扩大
比如1:128就是每来128计为1次。
TMR0
TMR0的特点:
1.TMR0是个8位计数器,所以总共可以记录2^8=256个数,从0开始到255.
2.对内部时钟进行计数的时候,触发方式固定为上升沿计数。溢出后标志位T0IF变为1.可以通过查询或者中断的方式实现控制逻辑
3.当对外部时钟源进行计数的时候,TMR0工作在计数器模式,此时触发方式可以由自己设置。即
注意区分外部中断触发设置,这里0/1代表意思不同。在计数器中,1代表下降沿,0代表上升沿。在外部事件触发中断中INTEDG,相反。
4.这就要求我们使用计数器TMR0前要对其进行初始化
TMR0使用:
几个需要初始化的端口介绍:
1.OPTION_REG
我们需要关注的几个端口在后面。前两个(高位第一和第二)我们在这节课中先不关注。抓住主要矛盾去分析。
初始化说明1
1.TOCS 这个是设置你TMR0处在什么工作状态 1是外部 0是内部
2.TOSE 这个是给你设置当处在外部输入的时候,是上升沿计数还是下降沿计数。只有在TOCS选择1的时候才需要去设置它
3.PSA 用于预分频的分配位 是把预分频功能给TMR0还是WDT(看门狗)
4.PS2–PS0 用于设置预分频的比率
2.INTCON 中断控制寄存器
如果要采取中断而不是查询的方式实现逻辑控制,这时候就得使用到INTCON
初始化声明2
1.总开关打开GIE=1
2.分开关打开 T0IE=1
注意:T0IF是标志位!!!溢出后要进行清0
初始化声明3
PORTA的模式定义:即TRISA
由于四号是输入引脚,所以定义的时候要注意定义为输入
1.TRISA=0b00001000
同时要注意外部电路也应该能够提供脉冲信号
初始化声明4
要对TMR0进行赋初值!!! 看例题2
TMR0题目
假设晶振振荡频率fosc=4MHz,求TMR0最大延时时间是多少?
/*
指令周期是机器周期的4倍
指令周期Tcy=1us
TMR0的最大延时时间为:
256×256×Tcy=65536×Tcy=65536us。
*/
假设现要延时12ms,即12000us.请问如何配置TMR0?
1.先计算预分频系数K:
256×K×Tcy=12000,得K=48.9,取K=64 //此时预分频比就应该设置为1:64
2.再计算延时常数X:
(256-X)×K×Tcy=12000,得X=68.5,四
舍五入取整X=69,即:TMR0=69 //即赋初值,可以采取宏定义的方式
注意事项
课件PPT例题可以看一看,这道题体现了上面提到的知识点。
若此时延迟的时间超过了TMR0的最大计时时间,可以采用IF语句的方式实现
注意static是一个关键字,意思是静态变量。使用了这个字符延长了子函数中变量的生命周期,否则子函数中的变量一旦子函数执行完毕,就被消灭,无法直接保存。
双灯也是差不多的,不过要考虑好可能出现的特殊情况
查询的方式实现上面的功能
TMR1
有了TMR0的基础,TMR1就比较好学习和掌握
外部输入的计数初始化
可能需要使用到的几个寄存器
这里的门控信号可以理解为三态门中的使能引脚,当输入的某个端口符合某种要求的时候,TMR1工作。(这个知识点后续会学习到,现在追求知道就好,不求甚解即可)
老问题:
晶振振荡频率fosc=4MHz,TMR1的最大延迟时间为?
指令周期是机器周期的4倍
指令周期Tcy=1us
TMR0的最大延时时间为:
65536×8×Tcy=524288×Tcy=524,288us。
4MHz晶振,若要延时100ms,即100,000us.请计算TMR1的配置
1.先计算预分频系数K:
65536×K×Tcy=100000,得K=1.52,取K=2
2.再计算延时常数X:
(65536-X)×2×Tcy=100000,得
X=15536=0x3CB0,即TMR1H=0x3C,TMR1L=0xB0
注意事项
◼ 在定时初始化时TMR1需赋初值;
◼ 一次定时完成后需重新赋初值;
◼ 一次定时完成后需清除中断请求标志位TMR1IF;
◼ TMR1有启/停控制开关TMR1ON;
◼ 门控TMR1:指TMR1只有当某指定引脚(RB5/T1G)的输出值满足要求时,才能进行工作;
◼ 当T1CON.TMR1GE=0时,关闭门控功能,即TMR1始
终工作。
由于TMR1由两个寄存器组成,所以可能发生读取一个寄存器的时候,另一个寄存器发生了进位,导致读取的数值是有问题的。
例如:假设当前TRM1H_TMR1L=0x01FF,则在读取TMR1时就可能发生错误:
➢ 如先读低字节0xFF,假设此时发生进位,则结果
为0x2FF,显然是错误的
➢ 如先读高字节0x01,假设此时发生进位,则结果
是0x100,显然也是错误的
所以在读取TMR1的时候就要格外的注意:
1.如果允许的话,在读之前让TMR1停止计数
2.如果不允许停止计数,则先读高字节,再读低字节,再读一次高字节,如果前后2次读的高字节不同,说明在读期间发生了进位。
A=TMR1H; //先读高字节
B=TMR1L; //再读低字节
C=TMR1H; //再读高字节
if(A==C) //判断读期间是否发生从低字节向高字进位
X=(A<<8)+B; //没有进位,就用第一次读高字节的结果
else
X=(C<<8)+0; //发生进位,用第二次读高字节的结果
右移:低位移出,高位补0;
左移:丢弃高位,最低位补0;
例题1
宏定义中AAA 定义为 65536-10 TMR1最大的计数次数为665536,由于按10次引起中断,所以减去10;
TMR2(略微学习即可)
TMR2编程注意事项
◆在定时初始化时需赋值PR2;
◆一次定时完成后无需重新赋初值;
◆一次定时完成后需清除中断请求标志位TMR2IF;
◆TMR2有启/停控制开关TMR2ON