定时器+外部中断
前言
通过对照51单片机开发手册,学习定时器的原理以及相关寄存器的程序设置方法 ,学会定时器。
一、定时器解析
1.1.什么是定时器?
1.SOC的一种内部外设
2.定时器就是CPU的“闹钟”
1.2.什么是计数器?
1.定时器就是用计数的原始实现的
2.计数器可以计算外部脉冲个数
1.3.定时器如何工作?
1.先设置好定时器时钟源(就是脉冲源)(如果需要的话)
2.初始化时钟相关寄存器
3.设置定时时间(计数个数)
4.设置中断处理程序
5.打开定时器
6.运行时:定时器计数到 后产生中断,然后执行中断isr
2.软件控制硬件的关键–寄存器
什么是寄存器?
(1)register
(2)寄存器,寄存,内容可变,一般按位定义 (如8比特位内存,每一格存储一个二进制位1/0,8位彼此独立)
(3)寄存器使用地址访问,编程上像内存一样
2.1.寄存器的工作原理
(1)寄存器和硬件之间有双向影响
(2)软件可以 读 寄存器
(3)总结:寄存器是软件能够控制硬件的关键 软件 - 寄存器 - 硬件
3.定时器介绍
参考数据手册
1.内置的两个16(16个二进制位)位定时器/计数器T0和T1都具有计数方式和定时方式两种工作方式 (2字节最大能存65535,16位溢出标志最大到63356就溢出)
2. 位数越多,计的脉冲越多,时间越长
3. 计数方式=数脉冲的个数
4. 定时方式=定个时间
5. 特殊功能寄存器 TMOD中都有一个控制位-C/T来选择t0/t1为定时器还是计数器
6. 定时器/计数器的核心部件是一个加法(减法)的计数器,其本质是对脉冲进行计数。以后基本上是减法计数器。
3.1定时器内部脉冲计算方式
3.1.1如为内部脉冲则为定时方式:
如外部12mhz晶振,单片机工作在12T模式下,则内部时钟频率是1mhz,则时钟脉冲宽度为1us (计算方法:1/1mhz=1us)
如在6t模式下,则内部时钟频率是2mhz,时钟脉冲宽度为0.5us (计算方法:1/2mhz=0.5us)
3.1.2.如为外部脉冲则为计数方式 :来自单片机外部引脚(T0-P3.4,T1-P3.5)则为计数方式,每来一个脉冲加1.
4.寄存器解析
51单片机由2个特殊功能寄存器构成
4.1.模式寄存器(工作方式寄存器)TMOD
TMOD寄存器不可位寻址,共8位,7-4位表示T1,3-0位表示T0.
- GATE:门控位。GATE=0时,TCON中的 TR0/TR1=1定时/计数器启动。
GATE=1时,TCON中的TR0/TR1=1且外部引脚INT0/1为高电平时,定时/计数器启动。 - C/T:定时/计数模式选择位。当C/T=0 定时模式,当C/T=1 计数模式
- M1,M0:工作方式设置位。定时/计数器有4种工作方式:其中M1M0为01时,代表的是工作方式1,即定时器T0模式TMOD=0X01.
一般选择为方式1,也可按实际需求来选择
4.2.控制寄存器TCON
TCON寄存器可位寻址,共8位。高4位(TF1、TR1、TF0、TR0)用于控制定时/计数器启动和终端申请,低4位用于外部中断
- TF1/TF0:T1/T0溢出中断请求位。T1/T0计数溢出时硬件自动为1(TF1/TF0=1),CPU响应中断后TF1/TF0由硬件自动清0。
- TR1/TR0: T1/T0 运行控制位。 TR1/TR0=1时,T1/T0开始工作.TR1/TR0=0时,T1/T0停止工作.且TR1/TR0需要软件置1或0.
- IE1/IE0和IT1/IT0与定时、计数器无关,是用来控制外部中断的。
4.3.外部中断允许控制寄存器IE
如同,IE寄存器也是可按位操作,可位寻址。
- 当TCON中TR1/TR0=1计数开启时(T1/T0模式),且需要计数结束时中断引入,那么IE中断寄存器中的ET1/ET0(T1/T0模式)的中断允许位就需要初始化。即ET1/ET0=1即可。
- EA:cpu中断总允许位初始化为1。
5.定时器中断的初始化设置
- 对TMOD 赋值,以确定T0 和T1 的工作方式。如果使用定时器0 即对T0 配置,如果使用定时器1 即对T1 配置(再强调一下TMOD高4位表示T1,低4位表示T0共8位)。
- 根据所要定时的时间计算初值,并将其写入TH0、TL0 或TH1、TL1。如定时时间为1ms,1ms=1000us 65536-1000=64536=0XFC18, 那么TH0=0XFC TL0=0X18
- 使TR0 或TR1 置位,启动定时/计数器定时或计数。
- 如果使用中断,则对IE寄存器 赋值,开放定时器中断。
- 打开EA总中断允许为。
二、定时器+外部中段程序
1.定时器初始化程序设置
代码如下(示例):定时时间:50ms
void main(void)
{
TMOD = 0X01; // T0设置工作在定时器模式下,16位定时器
TL0 = 0xb0; //(65536-50000)% 256
TH0 = 0x3c; //(65536-50000)/ 256
TR0 = 1; // 开启计数器,开始计数
ET0 = 1; // 开启T0中断
EA = 1; // 开启总中断开关
for(; ; ) // 主程序
{
}
2.中断程序
代码如下(示例):
void timer0_isr(void) interrupt 1 using 1
{
TH0 = 0x3c;
TL0 = 0xb0;
+所要实现的中断控制程序,如LED =~ LED; (让LED闪烁程序等等)
}
3.完整程序
代码如下(示例):在主程序运行不变的情况下,使LED每间隔1s闪烁
#include "reg51.h"
sbit LED1 = P0^0;
unsigned char smg[9] = {0x9e, 0x24, 0x0c, 0x98, 0x48, 0x40, 0x1e, 0x00, 0x08}; // 定义数码管段选数据
unsigned char count0 = 20; // count0变量的作用是循环定时时间的次数至我们需要的定时时间。
unsigned char i = 0;
void timer0_isr(void) interrupt 1 using 1 // 中断函数
{
TH0 = 0x3c;
TL0 = 0xb0;
count0--;
if(count0 == 0)
{
LED1 =~ LED1;
count0 = 20; // COUNT0变量重置20
}
}
void main(void)
{
TMOD = 0X01; // T0设置工作在定时器模式下,16位定时器
TH0 = 0x3c; //(65536-50000)/ 256
TL0 = 0xb0; //(65536-50000)% 256
TR0 = 1; // 开启计数器,开始计数
ET0 = 1; // 开启T0中断
EA = 1; // 开启总中断开关
count0 = 20; // count0变量的作用是循环定时时间的次数至我们需要的定时时间。
for(; ;) // 主任务,让静态数码管一直循环0-9
{
p1 = smg[i];
i++;
if(i == 9)
{
i = 0;
}
}
}
补充:由于51单片机16位模式最大存储量为65536也就是65.536ms就溢出了,所以当我们需要定时间隔为1s时就需要定义一个变量count进行重复计数,用来达到需要的定时时间。
总结
定时器这个章节最主要的是需要根据开发手册上对于TMOD,TCON和IE寄存器各个组成位的理解与运用,了解各寄存器中各个位所代表的不同功能。在以后对于STM32单片机的操作时也是如此。纯手白,希望大家多提意见,谢谢!