《如何使用定时器计数器精品文稿.ppt》由会员分享,可在线阅读,更多相关《如何使用定时器计数器精品文稿.ppt(27页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、如何使用定时器计数如何使用定时器计数器器第1页,本讲稿共27页n n8.1 什么是定时器什么是定时器/计数器计数器n n8.2 为什么需要定时器为什么需要定时器/计数器计数器n n8.3 SPCE061A的定时器的定时器/计数器计数器n n8.4 定时器应用示例定时器应用示例第2页,本讲稿共27页8.1 什么是定时器/计数器 n n“定时器”是单片机系统中最基本、最常用的部件之一。什么是定时器呢?举一个简单的例子:假如我们下午4点要参加一个重要的会议,那么为了准时到场,我们要每过一段时间看看表,确定是不是该出发了。实际上还有更好的解决办法,就是设定一个闹钟,到时候提醒我们去开会,这样我们就可以
2、专心做别的事情,省去了不断看表的麻烦。在单片机中,“定时器”就是充当了这个闹钟的角色。第3页,本讲稿共27页下面我们简单了解一下定时器的工作原理。第4页,本讲稿共27页通过设定计数初值实现定时 第5页,本讲稿共27页n n我们的程序怎样才能知道是否发生了计数溢出呢?这要涉及到“中断”的概念了。简单地说,每发生一次溢出,可以通过设置使CPU中止执行目前的程序(即“中断”),转而执行事先设计好的“处理计数溢出”的一段程序(即“中断服务程序”);当中断服务程序执行结束后,CPU会返回当初中断的位置,继续执行原来的程序。第6页,本讲稿共27页第7页,本讲稿共27页8.2 为什么需要定时器/计数器 n
3、n通过上一节的学习,我们对定时器/计数器有了一个大体上的了解。定时器/计数器的出现使我们拥有了既可精确计时又能及时提醒的“闹钟”,这将大大简化我们的程序设计。拿一个最简单的例子来说,要实现LED发光管每0.5秒闪烁一次,如果不使用定时器,就需要设计一个循环,经过繁琐的计算来确定循环需要执行的次数,从而实现延时0.5秒;有了定时器就方便得多,只需设定好计数频率和计数初值就可以了。第8页,本讲稿共27页n n另外,对于某些功能需求,没有定时器/计数器是无法实现的。例如把上面LED闪烁的例子做一点点扩展,用按键控制一个LED发光管的亮灭,同时让另一个LED发光管每0.5秒闪烁一次。此时只有使用定时器
4、才能实现0.5秒的准确定时了。第9页,本讲稿共27页8.3 SPCE061A的定时器/计数器 n nSPCE061A单片机拥有两个16位的定时器TimerA和TimerB,它们也可以作为计数器使用。“16位”就是说它的计数部件可以记录的最大数值是(216-1),即65535。第10页,本讲稿共27页n n这两个定时器的使用方法非常简单,只需对单片机中的几个寄存器进行控制就可以了。两个定时器可以分别设置工作状态而互不影响。第11页,本讲稿共27页SPCE061A的定时器控制寄存器 第12页,本讲稿共27页n n只要向上述几个寄存器里写入适当的数值就可以达到定时或计数的目的了。例如,要将Timer
5、A设定为每0.43秒溢出一次,那么只需令P_TimerA_Ctrl的值为0 x0032,再令P_TimerA_Data的值为0 xC8F6就可以了。第13页,本讲稿共27页8.4 定时器应用示例 n n设计程序使一个LED发光管以0.6秒为周期闪烁,即发光管每0.3秒点亮或熄灭一次。n n分析题目要求,主要涉及两方面的操作,即控制LED发光管的亮灭以及定时0.3秒。对于LED发光管,只用一个IO就可以控制了(例如使用IOA0);而对于0.3秒定时,我们可以利用TimerA定时器轻易地实现。第14页,本讲稿共27页n n首先设置首先设置P_TimerA_CtrlP_TimerA_Ctrl寄存器。
6、从寄存器。从SPCE061ASPCE061A编程手册编程手册或或SPCE061ASPCE061A单片机教材书单片机教材书中可以查到,中可以查到,当当P_TimerA_CtrlP_TimerA_Ctrl设置为设置为0 x00320 x0032时,时,n n定时器的计数频率将被设置为定时器的计数频率将被设置为32768Hz32768Hz。也就是说,。也就是说,CPUCPU每每1/327681/32768秒向秒向TimerATimerA发出一次计数信号。我们需发出一次计数信号。我们需要定时要定时0.30.3秒,也就是每次要等秒,也就是每次要等CPUCPU发出发出0.3/(1/32768)=98300
7、.3/(1/32768)=9830个计数信号之后对个计数信号之后对LEDLED发光管进行发光管进行一次点亮或熄灭操作。一次点亮或熄灭操作。第15页,本讲稿共27页怎样才能知道CPU已经发出了9830个计数信号?大体上有两种做法:n n方法一:给定时器一个方法一:给定时器一个初始计数值初始计数值0 0,开始定时后,程序,开始定时后,程序不断查询不断查询P_TimerA_DataP_TimerA_Data的值,当的值,当P_TimerA_DataP_TimerA_Data达到达到98309830时时,表示,表示0.30.3秒已经到了秒已经到了,再通过程序把,再通过程序把P_TimerA_DataP
8、_TimerA_Data的值恢复为的值恢复为0 0,进行下一轮定时。这种,进行下一轮定时。这种方法比较简洁易懂,但缺点是明显的:程序需要不方法比较简洁易懂,但缺点是明显的:程序需要不停地判断计数值是否达到了停地判断计数值是否达到了98309830,一方面难以,一方面难以“集中集中精力精力”完成其他工作(本例题只需完成一项工作,因此完成其他工作(本例题只需完成一项工作,因此这一点在本例中体现得并不明显),另一方面也浪费了这一点在本例中体现得并不明显),另一方面也浪费了大量的大量的CPUCPU时间。时间。第16页,本讲稿共27页n n方法二:与方法一相比,方法二的效率将大大提高,但是要利用“中断”
9、了。给TimerA设定一个初始计数值,让它在这个初始值的基础上开始计数,在9830个计数信号之后刚好发生溢出,进入中断,第17页,本讲稿共27页n n在中断服务程序中处理LED灯的点亮或熄灭工作。由于TimerA的最大计数值是65535,所以这个初始计数值就应该是(65536-9830),即55706(想一想为什么要用65536减,而不是65535?)。把55076(相当于16进制的0 xD724)赋给P_TimerA_Data,就完成了初始计数值的设定。(这回应该清楚前一节提到的0.43秒定时中,0 x0032和0 xC8F6是怎么来的了吧?)第18页,本讲稿共27页定时器应用示例程序流程图
10、 第19页,本讲稿共27页C语言编写程序如下n n#define P_TimerA_Data(unsigned int*)0 x700A n n#define P_TimerA_Ctrl(unsigned int*)0 x700B 第20页,本讲稿共27页n n#define P_IOA_Data(unsigned int*)0 x7000 n n#define P_IOA_Dir(unsigned int*)0 x7002 n n#define P_IOA_Attrib(unsigned int*)0 x7003 第21页,本讲稿共27页n n#define P_Watchdog_Clear
11、(unsigned int*)0 x7012 第22页,本讲稿共27页n nmain()n n n nint LED_Flag=0;/LEDint LED_Flag=0;/LED灯亮灭标志灯亮灭标志 n n*P_IOA_Dir=0 x0001;/P_IOA_Dir=0 x0001;/设置设置IOA0IOA0为同相输出为同相输出 n n*P_IOA_Attrib=0 x0001;P_IOA_Attrib=0 x0001;n n*P_IOA_Data=0 x0000;/LED*P_IOA_Data=0 x0000;/LED初始状态为熄灭初始状态为熄灭 第23页,本讲稿共27页n n*P_Timer
12、A_Ctrl=0 x0032;/P_TimerA_Ctrl=0 x0032;/计数频率计数频率32768Hz 32768Hz n n*P_TimerA_Data=0;/*P_TimerA_Data=0;/计数器初值设为计数器初值设为0 0 n nwhile(1)while(1)n n n nif(*P_TimerA_Data=9830)/if(*P_TimerA_Data=9830)/计数达到计数达到9830 9830 n n n n*P_TimerA_Data=0;/*P_TimerA_Data=0;/计数清计数清0 0 n nif(LED_Flag=0)/if(LED_Flag=0)/如果
13、如果LEDLED的状态是熄灭的的状态是熄灭的 n n n n*P_IOA_Data=0 x0001;/*P_IOA_Data=0 x0001;/点亮点亮LED LED n nLED_Flag=1;/LED_Flag=1;/改变状态标志改变状态标志 n n 第24页,本讲稿共27页n nelse/else/如果如果LEDLED的状态是点亮的的状态是点亮的 n n n n*P_IOA_Data=0 x0000;/*P_IOA_Data=0 x0000;/熄灭熄灭LED LED n nLED_Flag=0;/LED_Flag=0;/改变状态标志改变状态标志 n n n n n n*P_Watchdo
14、g_Clear=0 x0001;/*P_Watchdog_Clear=0 x0001;/清看门狗清看门狗 n n n n 第25页,本讲稿共27页n n程序的程序的1616行对程序中用到的几个寄存器名称进行了定义,这样在程行对程序中用到的几个寄存器名称进行了定义,这样在程序中就不必出现晦涩难懂寄存器地址了。第序中就不必出现晦涩难懂寄存器地址了。第1010行设计了一个标志变量行设计了一个标志变量LED_FlagLED_Flag,用来反映,用来反映LEDLED的亮灭状态。第的亮灭状态。第1616和和1717行设置了定时行设置了定时器的计数频率和初始值。器的计数频率和初始值。n n第第1936193
15、6行是一个循环,它任务是不断检测行是一个循环,它任务是不断检测P_TimerA_DataP_TimerA_Data的值,如的值,如果发现这个计数值达到了果发现这个计数值达到了98309830,说明,说明0.30.3秒已经到来,于是改变秒已经到来,于是改变LEDLED灯的亮灭状态,并把计数值清零,准备迎接下一个灯的亮灭状态,并把计数值清零,准备迎接下一个0.30.3秒。秒。n n好了,连接好好了,连接好6161板和板和LEDLED灯(手头没有灯(手头没有LEDLED灯?那么拿万用表灯?那么拿万用表凑合一下吧,测量凑合一下吧,测量IOA0IOA0的电压即可),把程序下载到的电压即可),把程序下载到6161板里,板里,运行之。看到运行之。看到LEDLED灯不停地闪烁了吧?灯不停地闪烁了吧?第26页,本讲稿共27页小结小结n n什么是定时器什么是定时器/计数器计数器n n为什么需要定时器为什么需要定时器/计数器计数器n nSPCE061A的定时器的定时器/计数器计数器n n定时器应用示例定时器应用示例第27页,本讲稿共27页
限制150内