找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2170|回复: 9
打印 上一主题 下一主题
收起左侧

汇编很容易之说说对定时器的理解与编程思路

  [复制链接]
跳转到指定楼层
楼主
ID:266429 发表于 2023-3-20 22:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这里说一说定时器的理解学习思路。
  定时器其实就是个计数器,我们用得最多的是用于计时,计时这个东西我们应该都明白是个什么东西,手机里的秒表就属于这个东西。手机上是怎么用的?一,调出手机的秒表功能,二归零,三按下开始,四盯着看看到没到我们预定的时间值。
  单片机里是一样的流程,先将其设置成计时功能,然后呃不是归零而是设置起始值(初始值),三给个信号让其开始,四不停地查询看其是否计数满值了。这样一说,计时器是不是在你眼中变得很低级?
  知道了计时器的工作原理,编程时具体怎么做?查芯片说明书啊,管它什么芯片,都一个查字:计时器功能设置在哪个单元,找地址嘛;初始值要放在哪个单元,启动信号在哪个单元,计满信号(溢出信号)在哪个单元,还是个查字。查到之后,就是修改,怎么修改,还是查说明书啊。
  说说为什么要弄个初始值,对于十六位的计时器来说,计时最大值就是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的编号之内。
写得好辛苦啊,没想到会写出这么多。定时器的自动重载和中断,就不写了,有了以上的知识,自己应该可以推理出来吧?

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:149799 发表于 2023-3-21 07:37 | 只看该作者
辛苦楼主了,看你讲解能看懂,不像有些资料讲解的云里雾里的,谢谢分享。
回复

使用道具 举报

板凳
ID:266429 发表于 2023-3-21 08:09 | 只看该作者
王秋冬 发表于 2023-3-21 07:37
辛苦楼主了,看你讲解能看懂,不像有些资料讲解的云里雾里的,谢谢分享。

谢谢鼓励。
回复

使用道具 举报

地板
ID:266429 发表于 2023-3-21 09:05 | 只看该作者
    昨天忘了说在启动计时器之后如何盯溢出标志位了。
这个问题,我们先不看书,而是自己先思考,把自己放在芯片设计者的位置,思考如何设计这个机器指令。
    方法是多种多样的,既然51机的这个标志位可以直接寻址,那我们可以把这个位值取出来,看看是不是1,如果还是零,那就回去再取,直到其变成1,就表示时间到了,这个方法,取值与判断都耽误了些时间,对于精度自然有了影响,也让程序变长了。
    另一种方法,那就是直接看着这个标志位,直到其变成1。
    我们自己有了两种方法(当然你可能还会想到别的方法),接下来就是看看51机是怎么设计相关的指令的,怎么做,还是查说明书查表啊。51机的指令,按机器操作码分,总数是256个;按汇编指令分,有111条,分为数据传送类、算术运算类、逻辑运算类、自加自减类、控制转移类、位操作类这几类指令(当然也有其它的分类法),我们要用到的这个指令,初步判断应该属于对位进行操作的控制转移类,然后我们就在这两个分类里面找,看操作功能栏,然后发现里面有两条与位值有关的条件转移指令,一个是直接寻址位为1则转移,一个是直接寻址位不为1则转移,这两条指令,其汇编指令格式一个是JB  bit,rel,一个是JNB  bit,rel。这里的bit就是被操作的位的位地址编号,而rel这个东西说起来稍微复杂点,它的实质,是程序接下来要执行的命令的首地址,这个地址不是指数据存储器的地址,而是程序存储器的地址,这个首地址里面存储的数据,单片机在运行时,是当作操作码的。
    “rel”其实只是个指令格式代号,在编程过程中,如果你知道这个首地址的地址值,你可以直接写成这个地址,如果你不知道,你就在这个条件转移语句中的条件成立后接下来要执行的那条语句的前面加一个英文标号作为标记(别忘了标号后面必须得有冒号),然后你在编写那条转移语句时用这个标号代替rel就行了,编译器在编译时,会记住标号标记处该语句存在程序存储器中的地址值,然后在编译这条条件转移语句时,将语句中的标号用这个地址值替换。
    好了,接下来我们该怎么编程就很清楚了。
    你看,其实我们并不需要死记硬背什么指令,你只需要清楚你想干什么,然后查指令表就行了,这样的学习方法是不是很容易就能着手编程实践?至于记住指令,实践多了自然就记住了。所以说你只要懂了其原理,汇编不过是顺手的事。
回复

使用道具 举报

5#
ID:149799 发表于 2023-4-1 19:09 | 只看该作者
谢谢楼主,有机会整理一下,俺次序从头开始讲解一下,在做成PDF文档,时最好不过的了。
回复

使用道具 举报

6#
ID:996773 发表于 2023-4-14 09:05 | 只看该作者
俺天生愚昧,实在没办法通过计时器来计算波形需要的时间,我编程的时候只能用笨办法

,例如,编写红外解码,实在无法知道下一个低电平到达的时间,就反复执行短时间的延时

程序,再读取有没有低电平,直到有低电平了,再看延时程序执行了多少次。就知道了。

我智商太低的人实在不会算,就这样死脑筋凑数
回复

使用道具 举报

7#
ID:689425 发表于 2023-5-4 09:55 | 只看该作者
hi等你 发表于 2023-4-14 09:05
俺天生愚昧,实在没办法通过计时器来计算波形需要的时间,我编程的时候只能用笨办法

,例如,编写红外解 ...

牛X,一力降十会
回复

使用道具 举报

8#
ID:237471 发表于 2023-11-12 08:41 | 只看该作者
赞,大赞,单片机基石文章
回复

使用道具 举报

9#
ID:1111542 发表于 2024-3-2 10:14 | 只看该作者
慢慢思考 发表于 2023-3-21 09:05
昨天忘了说在启动计时器之后如何盯溢出标志位了。
这个问题,我们先不看书,而是自己先思考,把自己放 ...

楼主既分享了知识,又分享了学习方法,赞!
回复

使用道具 举报

10#
ID:908670 发表于 2024-4-20 12:14 | 只看该作者
好资料讲的很明白
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表