原创 单片机汇编语言的延时,中断模块设计

2010-5-30 13:36 5172 5 5 分类: MCU/ 嵌入式

单片机的汇编语言设计很重要,其中学习最重要的部分就是延时和中断的设计。这里就把当初自己学习单片机的一个小学习片段,公布出来。若读者有什么建议或者需求可留言与我联系。下面的只是我最初学习单片机的一些知识的笔记。有很多错漏之处是正常的。也希望读者能够在我的错漏之上能够有所收获,能够联想到自己学习单片机的一些缺点和不足。


延时模块<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。但是第二种延时不常用。本实验采取第一种延时的话也很麻烦。在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。C51编写的中断服务程序编译后会自动加上PUSH ACCPUSH PSWPOP PSWPOP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。指令延时无法得到精确时间,只能用中断才可以。


为了降低实验难度和省事,所以采取调用延时程序的方法来实现延时,再利用寄存器R0来实现调用延时的次数便可实现较为准确的延时。下面是设计较为精确是延时程序的程序模块。


DELAY:


MOV  R7,#9        ;1uS


DELAY1:


MOV    R6,#128    ;1uS


DELAY2:


MOV    R5,#215   ;=215*2=430uS


NOP              ;1uS


DJNZ   R5,$


;上一句执行完后用时:215*2=430uS


DJNZ   R6,DELAY2


;执行完上句后用时:[430+2(是上句每次执行时间)+1(执行MOV R5的时间)+1(nop)]*128=55552uS


DJNZ   R7,DELAY1


;执行完上句后用时:[55552+2(本句每次执行时间)+1MOV R6的时间)]*9=499995uS


RET    ;1uS


上面便是精确延时0.5秒的小程序。但是由于交通灯的延时不是0.5秒而是6秒始终或者3秒等,所以利用寄存器R0来设计调用次数时虽然很容易实现6秒等时间的设置。但是细心分析发现,每条指令都有读取的时间虽然读取指令是时间很短只有几个微秒,但是始终不能实现十分精准的时间设置。由于误差实在微秒级的,是在可承受的范围之内,所以就忽略不计这些极小的误差。本实验设计了3个延时小程序,但是基本上都是一致的,只不过略微改变了一下调用循环的次数和传送的数据,这样采用不同的延时程序实现不同时间的设置。


3.中断模块


设计中断模块必须先了解中断的相关知识。中断请求源:(1)外部中断请求源:即外中断01,经由外部引脚引入的,在单片机上有两个引脚,名称为INT0INT1,也就是P3.2P3.3这两个引脚。在内部的TCON中有四位是与外中断有关的。IT0INT0触发方式控制位,可由软件进和置位和复位,IT0=0INT0为低电平触发方式,IT0=1INT0为负跳变触发方式。IE0INT0中断请求标志位。当有外部的中断请求时,这位就会置1(这由硬件来完成),在CPU响应中断后,由硬件将IE00IT1IE1的用途和IT0IE0相同。(2)内部中断请求源TF0:定时器T0的溢出中断标记,当T0计数产生溢出时,由硬件置位TF0。当CPU响应中断后,再由硬件将TF00TF1:与TF0类似。


2、中断允许寄存器IE


MCS51中断系统中,中断的允许或禁止是由片内可进行位寻址的8位中断允许寄存器IE来控制的。见下表



EA


x


x


ES


ET1


EX1


ET0


EX0


如果我们要设置允许外中断0,定时器中断不允许,则IE可以是



EA


x


x


ES


ET1


EX1


ET0


EX0


1


0


0


0


0


0


0


1


采用位寻址方式,利用几条指令便可实现中断允许寄存器IE的设置。


CLR IT0


SETB EX0


SETB EA


便是实现外部中断0的初始化的设计,把中断的初始化设计好,就表示能够执行后面的中断程序了。


由于实验很简单只是设计了一个中断优先级所以不考率中断的优先级。程序开头就有条指令是ORG 0003HLJMP DT0这两句是先开中断服务入口地址。外中断的入口地址是:0003H。程序使用的是外加电平控制中断,所以采用外中断0DT0是中断程序的标号。


本次实验采用的是P3.2外电平触发中断的方式所以在程序中有指令JB P3.2,L1。目的是判断 P3.2口的电平状态来做出相应的动作。这条指令的意思是:指令检测直接位寻址,若P3.2口的电平是高电平,则转到L1位置去执行,否则继续向下执行。


写程序时一般是这样写:


ORG 0000H


LJMP START


ORG 0003H


LJMP DT0


ORG 0050H


START


SETB EA


SETB ET1


SETB EX1


后面就能写交通灯的控制程序了,中断程序一般放在整个程序的最后面。中断程序在程序代码中的位置是0500H,所以程序开始有ORG 0500H


中断服务程序必须做到下面几点:(1)根据要求清除中断请求的标志位。(2)根据需要保护现场和恢复现场。主程序和中断服务程序有可能会用到相同的存储单元和寄存器,当cpu进入中断服务程序用到上述的寄存器时就会破坏原来执行程序的一些数据,不保护的话,中断返回时,会导致主程序的混乱。保护现场是将有关的寄存器和标志位压入堆栈如:PUSH PSWPUSH ACC等。恢复现场是将相应的寄存器弹出堆栈,采用“先如后出”的原则便可,如POP ACCPOP PSW便是弹出堆栈。(3)中断返回指令RETI一定放在中断服务程序的最后。


中断发生后出现了交通灯的第七个状态就是红灯全亮了,因此在中断程序中必须送个交通灯第七个状态编码并延时。MOV P2,# 00100100BCALL DELAY4就是中断时的七个状态发生的交通灯控制语句。MOV P2,A是让中断后能继续返回原状态的语句。这样就基本上实现了中断服务程序的设计如下:


ORG 0500H


DT0:


PUSH PSW


PUSH ACC


JB P3.2,L1


MOV P2,# 00100100B


CALL DELAY4


JMP DT0


L1


POP ACC


POP PSW


MOV P2,A


RETI

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条