1、8.5 定时器/计数器TMR0模块的应用举例,由于定时器/计数器模块是一种应用比较灵活的外设模块,因此我 们在本节中充分利用ICD配套演示版上很有限的硬件资源,通过精心 安排和巧妙构思,尽可能多的设计了几个试验范例,以便充分展示 定时器/计数器TMR0模块的各种应用方法和设计技巧。 8.5.1 TMR0用作硬件定时器能否以查询方式利用可编程定时器TMR0模块产生延时?这与采 用软件手段产生延时的方法相比有什么好处?在下面的试验范例中 将得到验证。可以看到硬件方式延时,使得程序更精练。实际上, 如果以中断方式利用TMR0延时还会节省CPU的时间。不过中断功能 暂时还没有讲到。例8.1队列灯实验项
2、目实现的功能把演示版上的8只LED发光二极管,设计为轮流发光。也就是在图8.6所示的16个现实状态之间轮流切换,并且在各个状态之间切换时,插入一个256ms的延时。, ,图8.6 队列灯,硬件电路规划队列灯电路如图8.7所示。途中的电路元件标号尽量与MPLAB ICD用户指南中的电路图保持一致,其他试验范例的电路图中元件 标号的标法也是如此。,D0,D0,图8.7 队列灯电路,软件设计思路我们以前在“PIC汇编语言程序设计基础”一节中,曾经学习利用软 件手段,在程序执行过程中插入一段延时的方法。现在我们来看看 硬件手段延时具体是如何实现的。在本例中,将分频器配置给TMR0 使用,并且分频比设定
3、为最大(1:256)。利用TMR0编制一段64ms的延 时子程序。LED显示驱动码的获取采用了查表法,在表中预先存储 了设定好的编码。并列摆放的8只LED的亮灭规律符合“最先移入队 列的亮灯,最先移出队列”。这很像人们生活中购物排队一样,先进 入队列的人,最先离开队列。与计算机理论中被称为队列的一种数 据结构的操作规则“先进先出(FIFO)”也十分相似,所以我们就给它起 一个雅致的名字叫“队列灯”。程序流程图如图8.8所示,包含主程序和子程序的流程图。,图8.8 程序流程图,程序清单;*;队列灯;程序文件名为“TMR0EXP1.ASM”;*tmr0 equ 01h ;定义定时器/计数器0寄存器
4、地址pcl equ 02h ;定义程序计数器低字节寄存器地址status equ 3h ;定义状态寄存器地址 option_reg equ 81h ;定义选项寄存器地址intcon equ 0bh ;定义中断控制寄存器地址portc equ 7h ;定义端口C的数据寄存器地址trisc equ 87h ;定义端口C的方向控制寄存器地址tmer0b equ 6 ;定义TMR0寄存器初始值(250=256-6)count equ 20h ;定义一个计数器变量寄存器rp0 equ 5h ;定义状态寄存器中的页选位RP0;* 主程序 *org 000h ;定义程序存放区域的启示地址mainnop ;设
5、置一条ICD必需的控操作指令bsf status, rp0 ;设置文件寄存器的体1movlw 00h ;将端口C的方向控制码00h先送W,movwf trisc ;再转到方向寄存器,RC全部设为输出movlw 07h ;设置选项寄存器内容,分频器给TMR0movwf option_reg ;分频比值设为“1:256”bcf status, rp0 ;恢复到文件寄存器的体0clrf count ;计数器清0loop movf count, 0 ;count作为查表地址偏移量送入Wcall read ;调用读取显示信息子程序movwf portc ;将查表得到的驱动码送显incf count, 1
6、 ;计数器加1movlw 0fh ;屏蔽掉高4位(count等效为4位计数器)andwf count, 1 ;以免偏移量超出表格范围call delay ;调用延时子程序call delay ;调用延时子程序call delay ;调用延时子程序call delay ;调用延时子程序goto loop ;跳转;*TMR0延时子程序*delaybcf intcon, 2 ;清除TMR0溢出标志位,movlw tmr0b ;TMR0赋初值movwf tmr0 ;并重新启动定时计数loop1btfss intcon, 2 ;检测TMR0溢出标志位 goto loop1 ;没有溢出,循环检测retur
7、n ;子程序返回 ;*读取显示信息的查表子程序*addwf pcl, 1 :地址偏移量加当前PC值retlw b00000001 ;显示信息码,下同retlw b00000011retlw b00000111retlw b00001111retlw b00011111retlw b00111111retlw b01111111retlw b11111111retlw b11111110retlw b11111100retlw b11111000,retlw b11110000retlw b11100000retlw b11000000retlw b10000000 retlw b0000000
8、0 end ;通知汇编器源程序结束 小结在本例中,旨在让读者学习以下主要内容:(1) 程序中“movwf tmr0”语句一旦被执行,将同时完成3个任务,向TMR0写入初始值;将分频器清0(请注意:分频比并不改变);重新启动TMR0计数器开始工作。(2) 分频器的使用方法。(3) 硬件方法延时同软件延时方法一样,延时时间的计算结果与 单片机时钟晶体振荡器的工作频率有着密切的关系。在下面的延时 计算式中,假设的是时钟频率为4MHz,这样假设的理由是,在ICD 套件中提供的演示板上,方便可用的时钟振荡方式为RC振荡方式, 并且电阻选的是4.7k,电容选的是22pF.RC振荡器工作频率范围在 3.5M
9、Hz到6MHz之间,会在一定程度上受工作电压和环境温度的影响。 在本例中就按4MHz来计算,因此,一个指令周期就是一个微秒(s) 的时间。,(4) 延时时长的计算方法。延时计算式为256(256-6)指令周期=640 00周期=64000 s=64ms。其中,前面的256是分频比;括号内的256 是TMR0产生溢出是累加计数的最大值;6是每次循环累加计数开始 时需要向TMR0填写的初始值。也就是TMR0初始值应为6,即在6的 基础上开始递增,直到计数到256时产生溢出。 (5) 查表程序的应用方法。(6)常数标号的定义和引用方法。例如,程序中的“tmr0b equ 6” 为定义语句;“movlw tmr0b”为引用语句。如果同一个常数标号,在 程序中多处被引用,这种做法会给计数值的修改带来极大的方便。 8.5.2 TMR0多次被引用如果事先在同一用户程序中的不同地方,利用同一可编程定时 器TMR0模块,来差生不同市场的演示,并且避免发生冲突?在下面 的实验范例中,试图为解决这类问题提供一条可行途径。 例8.2单键循环切换访波信号发生器,