[经验分享]

定时器的理解与编程思路

[复制链接]
1909|55
手机看帖
扫描二维码
随时随地手机跟帖
timfordlare|  楼主 | 2024-1-21 20:47 | 显示全部楼层 |阅读模式
定时器其实就是个计数器,我们用得最多的是用于计时,计时这个东西我们应该都明白是个什么东西,手机里的秒表就属于这个东西。手机上是怎么用的?一,调出手机的秒表功能,二归零,三按下开始,四盯着看看到没到我们预定的时间值。
  单片机里是一样的流程,先将其设置成计时功能,然后呃不是归零而是设置起始值(初始值),三给个信号让其开始,四不停地查询看其是否计数满值了。这样一说,计时器是不是在你眼中变得很低级?
  知道了计时器的工作原理,编程时具体怎么做?查芯片说明书啊,管它什么芯片,都一个查字:计时器功能设置在哪个单元,找地址嘛;初始值要放在哪个单元,启动信号在哪个单元,计满信号(溢出信号)在哪个单元,还是个查字。查到之后,就是修改,怎么修改,还是查说明书啊。
  说说为什么要弄个初始值,对于十六位的计时器来说,计时最大值就是65535,再加1就漫出了(溢出)。51单片机的设计上,计数方式是加加加,也就是计数单元中的值是增加方式,如果我们想计数100,从0开始也不是不行,但你要去不断地判断其值是否到了99,这个也不是不行,但有更好的方法,那就是从65436开始,计到溢出,而计数器本身设计了一个功能,就是溢出后就给出一个溢出信号,这个信号存在某一个单元之中(称之为溢出标志,51单片机存在某个单元的某一位上,称之为溢出标志位),程序运行中只需要盯着这个标志位的值就行了,用不着盯计数值。
  谈点芯片设计人员的思路,上面说的是计数值加加加,那采用计数值减减减的方式可以不可以实现呢?这个问题并不复杂,我在这里就不罗嗦了。
  可以说,这个溢出标志的设计,是很好的设计,定时器的中断功能,也是在这个基础上弄出来的。
  有了以上的知识,那我们在应用定时器进行编程时,思路也就很清楚了,首先使用前别忘了标志位应该是零啊,启动位当然也要是零,然后把初始值送进去,然后设置(也可以说是调出)其计时功能(十六位的或八位的,按你的需要),然后把启动位设置成开始(启动),然后不停查询标志位的值。哦还有一点,单片机的定时器不止一个,以上这些动作,只对你所选择的那个定时器进行编程。再有一点,计时完成之后,启动位、溢出标志位等是否需要人工处理,这个要看说明书。
吐槽一下:现有的教材都是告诉你有这些特殊功能寄存器、如何设置这些寄存器,却没怎么讲解为什么机器中存在这些寄存器、为什么需要设置这些项目,这样的结果,自然是让人不容易理解掌握,不能理解的结果,就只能是死记硬背,反正本人特烦死记硬背,没法,记性比别人差,于是只能逼着自己去理解原理,理解了原理,编程就是心中长了竹子。
好了,下面我们就查表,首先是计时功能设置的单元,教材中称之为定时器工作方式寄存器,俗名TMOD,设计在片内数据存储单元中,归于特殊功能寄存器,对这类单元只能直接寻址,不能间接寻址,该单元没有设计位寻址功能,其地址编号为89H,这个单元控制两个定时器的工作模式(标准的51机有两个定时器),高四位控制定时器1,低四位控制定时器0。这四个位的功能在一般的教材上都有讲解,反正如果你想使用十六位计时功能时,将四位设成0001就行了。因为不能位寻址,那一次就得送入一整个字节,所以如果你若让定时器1闲着而用定时器0,那就得把00000001B送入89H单元中,可以用MOV命令将00000001B作为立即数送入89H中(当然你也可以将其先存于某个单元之中再送入),前面说了对于特殊功能寄存器89H这个单元只能直接寻址,那么这个单元的地址就必须直接写在这条语句中,所以这条命令是这样写的:MOV   89H,#00000001B,当然,89H这个单元你可以不用数据地址,而是用其俗名来代替,这个俗名,程序编辑器中已经有了一个,就是“TMOD”,于是,这条命令就可以这样写:MOV  TMOD,#00000001B。也当然,如果你不喜欢TMOD这个俗名,你自己取一个自己喜欢自己好记的名字也行。
再就是计数数据单元了,它是十六位,就是两个字节,51机是每个单元里面存的是一个字节的数据,那十六位就得两个字节,就得占用两个单元;51机每个单元都有一个地址编号,那两个单元就得两个地址编号。查说明书,这两个计数单元也属于“特殊功能寄存器”的范畴,不可位寻址,只能直接寻址,所以可以同上面一样的格式编写语句将初始值送入。定时器0的高字节地址编号为8CH,俗名TH0;低字节为8AH,俗名TL0。
再接下来就是启动设置,还有溢出标志,这两个放在一起讲,是因为51机芯片设计中将这两个放在了同一个单元中,只是在不同的位。查说明书,仍属于“特殊功能寄存器”,只能直接寻址,可位寻址,单元地址编号88H,俗名TCON,这一个单元控制两个定时器,其中的第5位(注意,现有教材中的规定是最低位编号为第0位,最高位编号为第7位)是定时器0的启动设置位,这一位的地址编号为8CH,俗名TR0;第6位是定时器0的溢出标志位,这一位的地址编号为8DH,俗名TF0。所以,对这两个位的操作,我们既可以一次送入一个字节到TCON中去,也可以直接操作位。位的操作蛮简单,在51机中,所有的位寻址是只能直接寻址(即在任何时候编写程序时,都只能将其地址直接写在语句中),不具有任何其它的寻址方式。对位的操作51机设计的动作比较少,常用的有两种动作:清零和置位(置位就是置1),51机对位的清零操作码是C2H,汇编助记符CLR;置位的操作码是D3H,汇编助记符为SETB。前面说了,写程序时,只能直接在语句中写它的位地址,所以,编写时,在操作码后面直接写上其位地址就行了,即SETB   8CH(SETB  TR0)启动定时器0,CLR  8DH(SETB  TF0)清零定时器0的溢出标志。
解释一下51机芯片的位寻址设计。51机的片内数据存储单元中,有一部分单元的位,是统一编有地址的,这个地址是8位地址,编号从0开始,最大255,所以其最多只能对256个位给予地址编号(即最多只有32个单元能有位寻址功能),有了这个地址编号,我们就可以依据这个地址编号,直接找到这个位并进行操作。接下来我们就有了一个疑惑,片内数据存储单元的编号也是从0到255,那么机器是怎么区分这两者而不会弄混的?答案就在操作码上,51机的操作码本身就暗含了接下来的操作的对象是单元还是位,可以这样理解:对单元进行操作的操作码打开的是一道门,门后通向单元;对位进行操作的操作码打开的是另一道门,门后通向位。另外说一句,其它种类的单片机不一定是这样设计的,如stm32的设计,它是统一编号,不管是单元还是位,它们的地址全在0到4G的编号之内。

使用特权

评论回复
elsaflower| | 2024-2-3 20:31 | 显示全部楼层
单片机定时器是嵌入式编程中极为重要的部分,它用于产生定时中断,实现精确的时间控制。

使用特权

评论回复
wwppd| | 2024-2-6 10:17 | 显示全部楼层
在编写单片机定时器相关的C语言代码时,通常会包含如下步骤:

包含对应的头文件,获取硬件资源定义和库函数。
初始化定时器,在主函数或单独的初始化函数中配置。
编写中断服务程序并在合适的位置注册该中断服务函数。
启动定时器,并根据需要等待中断或者轮询定时器的状态。

使用特权

评论回复
robincotton| | 2024-2-6 22:09 | 显示全部楼层
定时器的初始化设置是非常关键的步骤,包括工作模式的选择、初始值的计算等。

使用特权

评论回复
tabmone| | 2024-2-6 22:57 | 显示全部楼层
选择合适的定时器:不同的单片机芯片可能有多个定时器,需要根据实际需求选择合适的定时器。
设置计数器初始值:根据需要设置计数器的初始值,以产生所需的中断周期或计时时间。
配置定时器模式:根据需要配置定时器的工作模式,如周期性中断、计时、PWM等。
编写中断处理函数:如果使用定时器产生中断,需要编写相应的中断处理函数,以处理中断事件。

使用特权

评论回复
pmp| | 2024-2-7 00:12 | 显示全部楼层
在复杂的系统中,需要避免定时器的中断服务程序与其他任务或中断服务程序发生资源冲突。

使用特权

评论回复
timfordlare|  楼主 | 2024-2-7 00:46 | 显示全部楼层
定时器是单片机内部的一个计数部件,它按照特定的时钟源进行计数。
计数器在每个时钟周期递增,当达到预设值时产生溢出,并可能触发中断。

使用特权

评论回复
mattlincoln| | 2024-2-7 13:43 | 显示全部楼层
在使用定时器之前,需要对其进行初始化,包括设置定时器的工作模式、计数初值、中断触发条件等。初始化代码的正确性直接影响到定时器的工作效果。

使用特权

评论回复
wengh2016| | 2024-2-7 17:07 | 显示全部楼层
单片机定时器是单片机中的一个重要功能模块,它可以用来定时或者计数,广泛应用于各种需要定时功能的场景。

使用特权

评论回复
i1mcu| | 2024-2-7 17:18 | 显示全部楼层
定时器通常由一个计数器和一个比较器组成,计数器在单片机时钟信号的作用下不断累加计数,当计数器的值达到预设的值时,比较器会输出一个信号,触发相应的中断或事件。

使用特权

评论回复
pmp| | 2024-2-7 18:17 | 显示全部楼层
当定时器的计数器达到预设的值时,会触发相应的中断。在中断服务程序中,可以执行一些需要定时执行的任务,如LED闪烁、数据采集等。中断服务程序的编写需要注意中断的优先级、中断的嵌套、中断的响应时间等问题。

使用特权

评论回复
qiufengsd| | 2024-2-7 18:44 | 显示全部楼层
常见的有定时模式(自由运行,计数到最大值后从0开始重新计数)和脉宽调制(PWM)模式等。

使用特权

评论回复
backlugin| | 2024-2-7 19:34 | 显示全部楼层
不同的单片机芯片和定时器模式下,定时器的精度可能有所不同。在选择定时器时,需要考虑定时器的精度是否满足需求。

使用特权

评论回复
biechedan| | 2024-2-7 20:28 | 显示全部楼层
定时器的计数器可能会受到外部噪声和温度漂移的影响,导致计时不准确。在选择定时器时,需要考虑这些因素。

使用特权

评论回复
abotomson| | 2024-2-8 09:23 | 显示全部楼层
单片机定时器本质上是一个计数器,它会根据单片机内部时钟信号进行计数。当计数到达预设值时,会产生溢出,触发中断或重置计数

使用特权

评论回复
uiint| | 2024-2-8 09:56 | 显示全部楼层
设置TMOD寄存器选择工作模式,设置THx和TLx寄存器为计算出的初值,并启用定时器中断(如果需要)。

使用特权

评论回复
weifeng90| | 2024-2-8 14:19 | 显示全部楼层
定时器的作用很广,也是单片机不可或缺的外设资源。

使用特权

评论回复
wwppd| | 2024-2-9 12:28 | 显示全部楼层
许多单片机定时器支持中断功能。当定时器达到设定的计数值时,可以触发中断请求。在中断服务程序中,可以处理定时事件,例如更新计数值、执行特定任务等。在使用中断功能时,需要注意中断使能和优先级设置。

使用特权

评论回复
rosemoore| | 2024-2-9 14:46 | 显示全部楼层
定时器在单片机应用中有着广泛的应用场景,如实现定时控制、延时处理、PWM波形生成、通信协议处理等。

使用特权

评论回复
lzbf| | 2024-2-9 15:29 | 显示全部楼层
单片机定时器是单片机内部的一个重要功能模块,它可以用来实现定时、延时、计数等功能。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

1111

帖子

1

粉丝