如何使用定时器计数器_第1页
如何使用定时器计数器_第2页
如何使用定时器计数器_第3页
如何使用定时器计数器_第4页
如何使用定时器计数器_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

如何使用定时器计数器第1页,共27页,2023年,2月20日,星期六8.1什么是定时器/计数器8.2为什么需要定时器/计数器8.3SPCE061A的定时器/计数器8.4定时器应用示例第2页,共27页,2023年,2月20日,星期六8.1什么是定时器/计数器“定时器”是单片机系统中最基本、最常用的部件之一。什么是定时器呢?举一个简单的例子:假如我们下午4点要参加一个重要的会议,那么为了准时到场,我们要每过一段时间看看表,确定是不是该出发了。实际上还有更好的解决办法,就是设定一个闹钟,到时候提醒我们去开会,这样我们就可以专心做别的事情,省去了不断看表的麻烦。在单片机中,“定时器”就是充当了这个闹钟的角色。第3页,共27页,2023年,2月20日,星期六下面我们简单了解一下定时器的工作原理。第4页,共27页,2023年,2月20日,星期六通过设定计数初值实现定时第5页,共27页,2023年,2月20日,星期六我们的程序怎样才能知道是否发生了计数溢出呢?这要涉及到“中断”的概念了。简单地说,每发生一次溢出,可以通过设置使CPU中止执行目前的程序(即“中断”),转而执行事先设计好的“处理计数溢出”的一段程序(即“中断服务程序”);当中断服务程序执行结束后,CPU会返回当初中断的位置,继续执行原来的程序。第6页,共27页,2023年,2月20日,星期六第7页,共27页,2023年,2月20日,星期六8.2为什么需要定时器/计数器通过上一节的学习,我们对定时器/计数器有了一个大体上的了解。定时器/计数器的出现使我们拥有了既可精确计时又能及时提醒的“闹钟”,这将大大简化我们的程序设计。拿一个最简单的例子来说,要实现LED发光管每0.5秒闪烁一次,如果不使用定时器,就需要设计一个循环,经过繁琐的计算来确定循环需要执行的次数,从而实现延时0.5秒;有了定时器就方便得多,只需设定好计数频率和计数初值就可以了。第8页,共27页,2023年,2月20日,星期六另外,对于某些功能需求,没有定时器/计数器是无法实现的。例如把上面LED闪烁的例子做一点点扩展,用按键控制一个LED发光管的亮灭,同时让另一个LED发光管每0.5秒闪烁一次。此时只有使用定时器才能实现0.5秒的准确定时了。第9页,共27页,2023年,2月20日,星期六8.3SPCE061A的定时器/计数器SPCE061A单片机拥有两个16位的定时器——TimerA和TimerB,它们也可以作为计数器使用。“16位”就是说它的计数部件可以记录的最大数值是(216-1),即65535。第10页,共27页,2023年,2月20日,星期六这两个定时器的使用方法非常简单,只需对单片机中的几个寄存器进行控制就可以了。两个定时器可以分别设置工作状态而互不影响。第11页,共27页,2023年,2月20日,星期六SPCE061A的定时器控制寄存器第12页,共27页,2023年,2月20日,星期六只要向上述几个寄存器里写入适当的数值就可以达到定时或计数的目的了。例如,要将TimerA设定为每0.43秒溢出一次,那么只需令P_TimerA_Ctrl的值为0x0032,再令P_TimerA_Data的值为0xC8F6就可以了。第13页,共27页,2023年,2月20日,星期六8.4定时器应用示例设计程序使一个LED发光管以0.6秒为周期闪烁,即发光管每0.3秒点亮或熄灭一次。分析题目要求,主要涉及两方面的操作,即控制LED发光管的亮灭以及定时0.3秒。对于LED发光管,只用一个IO就可以控制了(例如使用IOA0);而对于0.3秒定时,我们可以利用TimerA定时器轻易地实现。第14页,共27页,2023年,2月20日,星期六首先设置P_TimerA_Ctrl寄存器。从《SPCE061A编程手册》或《SPCE061A单片机教材书》中可以查到,当P_TimerA_Ctrl设置为0x0032时,定时器的计数频率将被设置为32768Hz。也就是说,CPU每1/32768秒向TimerA发出一次计数信号。我们需要定时0.3秒,也就是每次要等CPU发出0.3/(1/32768)=9830个计数信号之后对LED发光管进行一次点亮或熄灭操作。第15页,共27页,2023年,2月20日,星期六怎样才能知道CPU已经发出了9830个计数信号?大体上有两种做法:方法一:给定时器一个初始计数值0,开始定时后,程序不断查询P_TimerA_Data的值,当P_TimerA_Data达到9830时,表示0.3秒已经到了,再通过程序把P_TimerA_Data的值恢复为0,进行下一轮定时。这种方法比较简洁易懂,但缺点是明显的:程序需要不停地判断计数值是否达到了9830,一方面难以“集中精力”完成其他工作(本例题只需完成一项工作,因此这一点在本例中体现得并不明显),另一方面也浪费了大量的CPU时间。第16页,共27页,2023年,2月20日,星期六方法二:与方法一相比,方法二的效率将大大提高,但是要利用“中断”了。给TimerA设定一个初始计数值,让它在这个初始值的基础上开始计数,在9830个计数信号之后刚好发生溢出,进入中断,第17页,共27页,2023年,2月20日,星期六在中断服务程序中处理LED灯的点亮或熄灭工作。由于TimerA的最大计数值是65535,所以这个初始计数值就应该是(65536-9830),即55706(想一想为什么要用65536减,而不是65535?)。把55076(相当于16进制的0xD724)赋给P_TimerA_Data,就完成了初始计数值的设定。(这回应该清楚前一节提到的0.43秒定时中,0x0032和0xC8F6是怎么来的了吧?)第18页,共27页,2023年,2月20日,星期六定时器应用示例程序流程图

第19页,共27页,2023年,2月20日,星期六C语言编写程序如下

#defineP_TimerA_Data(unsignedint*)0x700A#defineP_TimerA_Ctrl(unsignedint*)0x700B第20页,共27页,2023年,2月20日,星期六#defineP_IOA_Data(unsignedint*)0x7000#defineP_IOA_Dir(unsignedint*)0x7002#defineP_IOA_Attrib(unsignedint*)0x7003第21页,共27页,2023年,2月20日,星期六#defineP_Watchdog_Clear(unsignedint*)0x7012第22页,共27页,2023年,2月20日,星期六main(){intLED_Flag=0;//LED灯亮灭标志*P_IOA_Dir=0x0001;//设置IOA0为同相输出*P_IOA_Attrib=0x0001;*P_IOA_Data=0x0000;//LED初始状态为熄灭第23页,共27页,2023年,2月20日,星期六*P_TimerA_Ctrl=0x0032;//计数频率32768Hz*P_TimerA_Data=0;//计数器初值设为0while(1){if(*P_TimerA_Data>=9830)//计数达到9830{*P_TimerA_Data=0;//计数清0if(LED_Flag==0)//如果LED的状态是熄灭的{*P_IOA_Data=0x0001;//点亮LEDLED_Flag=1;//改变状态标志}第24页,共27页,2023年,2月20日,星期六else//如果LED的状态是点亮的{*P_IOA_Data=0x0000;//熄灭LEDLED_Flag=0;//改变状态标志}}*P_Watchdog_Clear=0x0001;//清看门狗}}第25页,共27页,2023年,2月20日,星期六程序的1~6行对程序中用到的几个寄存器名称进行了定义,这样在程序中就不必出现晦涩难懂寄存器地址了。第10行设计了一个标志变量LED_Flag,用来反映LED的亮灭状态。第16和17行设置了定时器的计数频率和初始值。第19~36行是一个循环,它任务是不断检测P_TimerA_Data的值,如果发现这个计数值达到了9830,说明0.3秒已经到来,于是改变LED灯的亮灭状态,并把计数值清零,准备迎接下一个0.3秒。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论