0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

手把手教你写单片机定时器中断程序

NJ90_gh_bee81f8 来源:未知 作者:李建兵 2018-03-12 16:02 次阅读

我们在学单片机时我们第一个例程就是灯的闪烁,那是用延时程序做的,现在回想起来,这样做不很恰当,为什么呢?我们的主程序做了灯的闪烁,就不能再干其它的事了,难道单片机只能这样工作吗?当然不是,我们能用定时器来实现灯的闪烁的功能。

例1:查询方式

ORG 0000H

AJMP START

ORG 30H

START:

MOV P1,#0FFH ;关所 灯

MOV TMOD,#00000001B ;定时/计数器0工作于方式1

MOV TH0,#15H

MOV TL0,#0A0H ;即数5536

SETB TR0 ;定时/计数器0开始运行

LOOP:JBC TF0,NEXT ;如果TF0等于1,则清TF0并转NEXT处

AJMP LOOP ;不然跳转到LOOP处运行

NEXT:CPL P1.0

MOV TH0,#15H

MOV TL0,#9FH;重置定时/计数器的初值

AJMP LOOP

END AJMP LOOP

END

键入程序,看到了什么?灯在闪烁了,这可是用定时器做的,不再是主程序的循环了。简单地分析一下程序,为什么用JBC呢?TF0是定时/计数器0的溢出标记位,当定时器产生溢出后,该位由0变1,所以查询该位
就可知宇时时间是否已到。该位为1后,要用软件将标记位清0,以便下一次定时是间到时该位由0变1,所以用了JBC指令,该指位在判1转移的同时,还将该位清0。




以上程序是能实现灯的闪烁了,可是主程序除了让灯闪烁外,还是不能做其他的事啊!不,不对,我们能在LOOP:……和AJMP LOOP指令之间插入一些指令来做其他的事情,只要保证执行这些指令的时间少于定时时间就行了。那我们在用软件延时程序的时候不是也能用一些指令来替代DJNZ吗?是的,但是那就要求你精确计算所用指令的时间,然后再减去对应的DJNZ循环次数,很不方便,而现在只要求所用指令的时间少于定时时间就行,显然要求低了。当然,这样的办法还是不好,所以我们常用以下的办法来实现。

程序2:用中断实现

ORG 0000H,

AJMP START

ORG 000BH ;定时器0的中断向量地址

AJMP TIME0 ;跳转到真正的定时器程序处

ORG 30H

START:

MOV P1,#0FFH ;关所 灯

MOV TMOD,#00000001B ;定时/计数器0工作于方式1

MOV TH0,#15H

MOV TL0,#0A0H ;即数5536

SETB EA ;开总中断允许

SETB ET0 ;开定时/计数器0允许

SETB TR0 ;定时/计数器0开始运行

LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

TIME0: ;定时器0的中断处理程序

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

CPL P1.0

MOV TH0,#15H

MOV TL0,#0A0H ;重置定时常数

POP PSW

POP ACC

RETI

END

上面的例程中,定时时间一到,TF0由0变1,就会引发中断,CPU将自动转至000B处寻找程序并执行,由于留给定时器中断的空间只有8个字节,显然不足以写下所有有中断处理程序,所以在000B处安排一条跳转指令,转到实际处理中断的程序处,这样,中断程序能写在任意地方,也能写任意长度了。进入定时中断后,首先要保存当前的一些状态,程序中只演示了保存存ACC和PSW,实际工作中应该根据需要将可能会改变的单元的值都推入堆栈进行保护(本程序中实际不需保存护任何值,这里只作个演示)。

上面的两个单片机程序运行后,我们发现灯的闪烁非常快,根本分辨不出来,只是视觉上感到灯有些晃动而已,为什么呢?我们能计算一下,定时器中预置的数是5536,所以每计60000个脉冲就是定时时间到,这60000个脉冲的时间是多少呢?我们的晶体震荡器是12M,所以就是60000微秒,即60毫秒,因此速度是非常快的。如果我想实现一个1S的定时,该怎么办呢?下面给出一个例程。

ORG 0000H

AJMP START

ORG 000BH ;定时器0的中断向量地址

AJMP TIME0 ;跳转到真正的定时器程序处

ORG 30H

START:

MOV P1,#0FFH ;关所 灯

MOV 30H,#00H ;软件计数器预清0

MOV TMOD,#00000001B ;定时/计数器0工作于方式1

MOV TH0,#3CH

MOV TL0,#0B0H ;即数15536

SETB EA ;开总中断允许

SETB ET0 ;开定时/计数器0允许

SETB TR0 ;定时/计数器0开始运行

LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

TIME0: ;定时器0的中断处理程序

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

INC 30H

MOV A,30H

CJNE A,#20,T_RET ;30H单元中的值到了20了吗?

T_L1: CPL P1.0 ;到了,取反P10

MOV 30H,#0 ;清软件计数器

T_RET:

MOV TH0,#15H

MOV TL0,#9FH ;重置定时常数

POP PSW

POP ACC

RETI

END

先自己分析一下,看看是怎么实现的?这里采用了软件计数器的概念,思路是这样的,先用定时/计数器0做一个50毫秒的定时器,定时是间到了以后并不是立即取反P10,而是将软件计数器中的值加1,如果软件计数器计到了20,就取反P10,并清掉软件计数器中的值,不然直接返回,这样,就变成了20次定时中断才取反一次P10,因此定时时间就延长了成了20*50即1000毫秒了。

这个思路在工程中是非常有用的,有的时候我们需要若干个定时器,可51中总共才有2个,怎么办呢?其实,只要这几个定时的时间有一定的公约数,我们就能用软件定时器加以实现,如我要实现P10口所接灯按1S每次,而P11口所接灯按2S每次闪烁,怎么实现呢?对了我们用两个计数器,一个在它计到20时,取反P10,并清零,就如上面所示,另一个计到40取反P11,然后清0,不就行了吗?这部份的程序如下

ORG 0000H

AJMP START

ORG 000BH ;定时器0的中断向量地址

AJMP TIME0 ;跳转到真正的定时器程序处

ORG 30H

START:

MOV P1,#0FFH ;关所 灯

MOV 30H,#00H ;软件计数器预清0

MOV TMOD,#00000001B ;定时/计数器0工作于方式1

MOV TH0,#3CH

MOV TL0,#0B0H ;即数15536

SETB EA ;开总中断允许

SETB ET0 ;开定时/计数器0允许

SETB TR0 ;定时/计数器0开始运行

LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

TIME0: ;定时器0的中断处理程序

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

INC 30H

INC 31H ;两个计数器都加1

MOV A,30H

CJNE A,#20,T_NEXT ;30H单元中的值到了20了吗?

T_L1: CPL P1.0 ;到了,取反P10

MOV 30H,#0 ;清软件计数器

T_NEXT:

MOV A,31H

CJNE A,#40,T_RET ;31h单元中的值到40了吗?

T_L2:

CPL P1.1

MOV 31H,#0 ;到了,取反P11,清计数器,返回

T_RET:

MOV TH0,#15H

MOV TL0,#9FH ;重置定时常数

POP PSW

POP ACC

RETI

END

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6037

    文章

    44558

    浏览量

    635362
  • 中断
    +关注

    关注

    5

    文章

    898

    浏览量

    41502
  • 定时器
    +关注

    关注

    23

    文章

    3248

    浏览量

    114824

原文标题:手把手教你使用单片机定时器、中断试验

文章出处:【微信号:gh_bee81f890fc1,微信公众号:面包板社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Air780E模组LuatOS开发实战 —— 手把手教你搞定数据打包解包

    本文要说的是低功耗4G模组Air780E的LuatOS开发实战,我将手把手教你搞定数据打包解包。
    的头像 发表于 12-03 11:17 175次阅读
    Air780E模组LuatOS开发实战 —— <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>搞定数据打包解包

    单片机有哪些中断类型

    单片机中断是指在单片机执行程序的过程中,当外部设备或内部条件发生某个特定事件时,能够暂停当前正在执行的程序,转而去执行一个特定的服务
    的头像 发表于 10-17 18:12 707次阅读

    单片机中断机制

    单片机中断机制是一种重要的处理方式,它允许单片机在执行主程序的过程中,能够暂停当前任务,转而处理外部或内部紧急事件。这种机制极大地提高了系统的响应速度和处理能力,使得
    的头像 发表于 10-17 18:03 698次阅读

    单片机中断有哪些?各类型中断有什么作用?

    )时触发。常用于周期性任务的执行。 比较中断:当定时器计数值与预设的比较值匹配时触发。常用于PWM信号的生成和精确计时。 3. 通信中断 通信中断用于处理
    发表于 09-24 16:22

    简述单片机定时器的工作原理

    单片机定时器的工作原理是一个复杂而精细的过程,它涉及到单片机内部的多个组件和机制。
    的头像 发表于 08-19 18:20 1392次阅读

    手把手教你通过宏集物联网工控屏&amp;网关进行协议转换,将底层PLC/传感的数据转换为TCP协议并传输到用户

    手把手教你通过宏集物联网工控屏&网关进行协议转换,将底层PLC/传感的数据转换为TCP协议并传输到用户终端
    的头像 发表于 08-15 13:29 519次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>通过宏集物联网工控屏&amp;网关进行协议转换,将底层PLC/传感<b class='flag-5'>器</b>的数据转换为TCP协议并传输到用户

    手把手教你排序算法怎么

    今天以直接插入排序算法,给大家分享一下排序算法的实现思路,主要包含以下部分内容:插入排序介绍插入排序算法实现手把手教你排序算法怎么写在添加新的记录时,使用顺序查找的方式找到其要插入的位置,然后将
    的头像 发表于 06-04 08:03 694次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>排序算法怎么<b class='flag-5'>写</b>

    stm8s003开启定时器中断时出现非常操作复位的原因?

    stm8s003k3单片机,使用的是TIM4 8位定时器,当开启定时器中断功能时,用仿真仿真,可以进入
    发表于 05-15 07:08

    开启定时器中断定时后,单片机无法启动或者复位是怎么回事?

    开启定时器中断定时后,在主程序中我在某处中断使能位置零(TIMx_IER=0X00)正常来说应该返回到主程序中,但是出现
    发表于 05-08 07:59

    HAL库开启定时器中断时会卡死程序的原因?

    当开启定时器中断时候,开启定时器时会卡死程序,调试,全速运行卡死在-HAL_TIM_Base_Start_IT函数,单步调试发现卡死在程序
    发表于 04-16 07:12

    8031单片机定时器和计数是怎么工作的

    8031单片机定时器和计数是通过内部的时钟源来工作的。具体来说,定时器/计数T0和T1的输入端都接到了机器周期信号上,因此它们的计数初
    发表于 02-02 17:13 1261次阅读

    单片机中断功能及其应用

    单片机中断功能及其应用  单片机中断是指在程序执行过程中,根据特定的条件或事件自动暂时中断当前
    的头像 发表于 01-30 14:45 5398次阅读

    单片机外部中断定时器中断的区别和用法

    单片机外部中断定时器中断在触发来源、应用场景以及功能特点上存在明显差异** **。
    的头像 发表于 01-28 17:35 3131次阅读

    工程送样!手把手教你用好广和通RedCap模组FG131&amp;amp;FG132系列

    工程送样!手把手教你用好广和通RedCap模组FG131&FG132系列
    的头像 发表于 01-11 18:22 705次阅读
    工程送样!<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>用好广和通RedCap模组FG131&amp;amp;FG132系列

    单片机定时器的用法

    本章以CW32通用定时器为例介绍单片机定时器的用法。
    的头像 发表于 01-04 10:37 1414次阅读
    <b class='flag-5'>单片机</b><b class='flag-5'>定时器</b>的用法