Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁

跳过中断直接讲TM中断是不是有些超前了?
由于最近参加了一个项目,真是忙的不要不要的,没办法,只有抽了点放假的时间来更新下自己的博文,希望对正在学习HT单片机的同学有帮助。
重庆合泰初赛是5月15日,嗯,大概还有1个月时间。希望自己小组能顺利通过初赛,也不枉我这几周对HT单片机的学习。
(声明下,这篇博文是我在完成外部中断情况下来讲述的,如果不知道的还是先看看手册,因为我在使用时中间出了点小问题,所以暂时先不更新外部中断。后面更新了(三)就可以忽略此信息。)

前文有讲过,任何关于单片机开发,或者外设都离不开手册的说明,这次也不例外。
而本次实验并不需要任何外设,依然会用前面博文(一)中的2个LED灯进行。

1、先讲述下什么时候会用到TM定时器。
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
学过51的肯定都做过这个led闪烁的实验(HT与51的定时器区别真的不是一般的大)。然而没做过项目的可能只是粗略的了解了一下,而做过项目的肯定知道TM定时器,比如超声波测距(这个实验在我项目之内,后面我会看情况更新),这便是运用了TM计数功能,单片机内部计数从发送超声波到接收超声波时间,然后用公式S=340*t/2便可算出距离。而计时功能主要用于中断的产生,每过多少时间就会进入中断产生其他操作,就比如每过1ms就让超声波发一次波。有人就会问了,为什么不用GCC_delay()函数?有这些问题的人,大可去试试,的确也能完成简单的操作,但是更为复杂的操作就不行了。
下面我只截手册上有用的信息,其他信息就自己多看看TM定时器与中断部分。
2、
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
有些理论得知道,HT单片机中的TM定时器有3中类型,分别是简易、标准、增强型,只要了解了简易型,其他两种基本能随意上手,它们三种有功能的限制,具体是哪些,就请自己看看手册。本次实验用的是简易型的TM0,那么10bit CTM是什么意思,就是10位,这个先了解,下面会仔细的讲解。
3、
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
TM中断,在讲此之前请不要用51的思想去理解。
HT内部中有比较器,比较器就是用来对比电压的,超过某个电压就会出现警报之类的,也可以用来进行计数器的对比,TM计数器都是从0开始向上计数,当计数器的值与比较器预设的值相同时,就会触发中断,计数器清零,从新开始计数。本次实验用的简易型TM定时/计数器,所以比较器只能用A或P。(计数器=计时器)
比较器这个东西先不用管。
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
放上此图,方便理解。
4、经过上面讲解大概知道了TM定时器的一些基本内容。
下面便开始讲解一些寄存器,此内容关系到如何编程。
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
这是TM总的寄存器。就比如目录一样。其中TMnC0(n=0,1,2,3)与TMnC1最为重要。
我先放上我自己的TM初始化程序,一一进行讲解。

void tm_init(void)
{
 _tm0c0=0x00;           //TM0  FSYS/4=0.5us
 _tm0c1=0xc1;           //定时/计数器模式与A配对
 _tm0al=0x8f;
 _tm0ah=0x03;           //比较器初值d1000
 _t0on=1;               //开定时器
 _t0ae=1;               //tm0,比较器A中断使能 
 _mf0e=1;               //多功能中断使能
 _emi=1;                //开总中断
} 

(提醒:在HT编译软件中,每用到内部程序,都会以_xxxx的形式出现)
TMnC0:
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
结合我的程序:
_tm0c0=0x00;(0000 0000)
其他的可以先不看,我只讲下bit 6~4 位时什么意思,即选择时钟位是什么意思,在博文(一)我就计算过一次频率,这里依然是计算频率,fsys是什么意思,看过我第一篇博文的都有印象吧。
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
这里就不废话了,直接告诉结论:bit 6~4位选择000,即fsys/4。注释中fsys/4=0.5us,意思就是计数器加一个1花了0.5us。如果想用其他时钟,可以自己去计算一下时间。
TMnC1:
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
结合我的程序:
_tm0c1=0xc1;(1100 0001)
其他自己看下,只需记住最后一位是1,即选择了TM0与比较器A配对。
既然选择了与比较器A配对,那么就要设置比较器A的预设值。
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
可以看出比较器A有2个寄存器,TMnAL(n=0,1,2,3)、TMnAH。其中L是低8位,H是高2位,所以比较器A是10位的,记忆力好的可以还记得TH0也是10位的。
10位是什么意思?就是计数器中00 0000 0000开始计数到11 1111 1111就满了,就会溢出,产生未知的中断。
看上面的程序可以知道我给的是1000,就是表示每过0.5us*1000=0.5ms就会产生一次中断。
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
TnON是寄存器TMnC0的一部分,即寄存器里面的8位可以单独拿出来赋值。
TnON=1用于打开定时器。
定时器讲完了,就开始讲中断了。
我只截图重要部分,后面有时间我会将外部中断部分补上。
下面截图要结合我的程序对应着看。

Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
Holtek合泰单片机 《四》 从TM定时器中断到led灯1s闪烁
为什么要开多功能中断?看下图,,,- -!我没找到图,我清楚的记得,TM中断也属于多功能中断。
到此为止,基本是就知道了TM定时器该怎么初始化了。
下面开始将中断服务程序。(跳过了中断真还不好讲呢。。。)
放上我的程序:

void __attribute((interrupt(0x14))) tim_int(void)  
{ 
 _emi=0;            //关总中断
 _t0af=0;           //清除TM2比较器A中断标志位
 i--;
 if(!i){
 _pf=~_pf; 
 i=2000;
 }
 _emi=1;           //开总中断
}

中断服务程序名函数格式为:void __attribute((interrupt(0x14))) tim_int(void),不多讲,不懂的自己看V3手册或者等更新外部中断。 - -。 V3手册在前面介绍过。
中断程序功能说明:每进入一次中断i就会加1,直到加了2000次,即一秒,便会是led闪烁。
注意两点:
1、进入一个中断服务程序后必须关掉中断,防止进入其他程序中。
2、标志位必须手动清除。
放上剩下的程序:

#include "HT66F70A.h"
#include "type.h"
volatile unsigned int i;
unsigned char num,flag,x;
void main(void)
{
  _pfc=0x00;                //输出模式
  _wdtc=0b10101011;         //关狗
  tm_init();                //tm0初始化
  i=2000;
  _pf=0x00;                 //关LED
  while(1);    
}

main中的功能主要是初始化功能。

至此,TM定时器中断led灯1s闪烁实验便结束了。
总结下:
1、HT与51定时器有一丢丢相似,51是直接直接给计数器赋值后等计数溢出便进入中断,而HT是与比较器对比,相同后才进入中断,HT的计数器只能读,不能去修改它,这就是我最开始最不明白的一点,不能修改计数器怎么计数?
2、因为TM定时器非常复杂,牵扯到了比较器,中断,与时钟频率,导致初学者不能很快的上手,博主也是花了一周左右才入了门。提醒下,就是手册中会有单独来讲比较器与振荡器,其实这两部分根本不用去管。我虽然看完了,但最后发现根本没用到。
3、关于中断的问题,希望大家先实现了外部中断,或者其他中断实验的基础上再学习TM中断,不然的话会非常复杂难懂。

关于上文提到的超声波测距,看情况更新吧。

在此希望本博文对大家学习有所帮助。

上一篇:Handsontable - 一键清空所有单元格数据


下一篇:redis底层数据结构分析