汇编延时程序算法详解
单片机延时500ms程序汇编
单片机延时500ms程序汇编一、概述在单片机编程中,延时操作是非常常见且重要的一部分。
延时可以使程序在执行过程中暂停一段时间,以确保输入输出设备能够正常工作,或者是为了保护其他设备。
本文将介绍如何使用汇编语言编写单片机延时500ms的程序。
二、延时原理在单片机中,延时操作通常通过循环来实现。
每个循环需要一定的时间,通过控制循环次数和循环体内的指令数量,可以实现不同长度的延时。
在汇编语言中,可以使用计数器来控制循环次数,从而实现精确的延时操作。
三、汇编语言编写延时程序接下来,我们将使用汇编语言编写延时500ms的程序。
1. 设置计数器初值在程序的开头我们需要设置计数器的初值,这个初值需要根据单片机的工作频率和所需的延时时间来计算。
假设单片机的工作频率为1MHz,那么在循环500次后,就能够达到500ms的延时。
我们需要将计数器的初值设为500。
2. 循环计数接下来,我们进入一个循环,在循环中进行计数操作。
每次循环结束时,都需要检查计数器的值,当计数器减至0时,表示已经达到了500ms的延时时间,可以退出循环。
3. 优化程序为了提高程序的执行效率,可以对计数器进行优化。
例如可以通过嵌套循环的方式,减少循环的次数,从而提高延时的精度和稳定性。
四、程序示例下面是一个简单的示例程序,演示了如何使用汇编语言编写延时500ms的程序。
```org 0x00mov r2, #500 ; 设置计数器初值为500delay_loop:djnz r2, delay_loop ; 进行计数ret ; 延时结束,退出程序```五、结语通过以上的示例程序,我们可以看到如何使用汇编语言编写单片机延时500ms的程序。
当然,实际的延时程序可能会更加复杂,需要根据具体的单片机型号和工作频率进行调整,但是思路是相似的。
在实际的编程中,需要根据具体的需求和硬件环境来进行调整和优化,以实现更加稳定和精确的延时操作。
希望本文对单片机延时程序的编写有所帮助,也欢迎大家在评论区提出宝贵意见和建议。
汇编延时程序算法详解
汇编延时程序算法详解计算机反复执行一段程序以达到延时的目的称为软件延时,单片机应用程序中经常需要短时间延时。
有时要求很高的精度,网上或书中虽然有现成的公式可以套用,但在部分算法讲解中发现有错误之处,而且延时的具体算法讲得并不清楚,相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。
指令周期、机器周期与时钟周期指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。
时钟周期:也称为振荡周期,一个时钟周期=晶振的倒数。
MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。
MCS-51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1μs。
程序分析例1 50ms 延时子程序:DEL:MOV R7,#200 ①DEL1:MOV R6,#125 ②DEL2:DJNZ R6,DEL2 ③DJNZ R7,DEL1 ④RET ⑤精确延时时间为:1+(1*200)+(2*125*200)+(2*200)+2=(2*125+3)*200+3 ⑥=50603μs≈50ms由⑥整理出公式(只限上述写法)延时时间=(2*内循环+3)*外循环+3 ⑦详解:DEL这个子程序共有五条指令,现在分别就每一条指令被执行的次数和所耗时间进行分析。
第一句:MOV R7,#200 在整个子程序中只被执行一次,且为单周期指令,所以耗时1μs第二句:MOV R6,#125 从②看到④只要R7-1不为0,就会返回到这句,共执行了R7次,共耗时200μs第三句:DJNZ R6,DEL2 只要R6-1不为0,就反复执行此句(内循环R6次),又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*R6*R7μs。
各种汇编延时程序大集合
MOV TL0,#0B0H
MOV R4, #10
SETB ET0
SETB EA
SETB TR0
SJMP $ ;
RET
DELAY: ;延时子程序(1秒)
MOV R0,#0AH
DELAY1: MOV R1,#00H
DELAY2: MOV R2,#0B2H
DJNZ ห้องสมุดไป่ตู้2,$
DJNZ R1,DELAY2
DJNZ R0,DELAY1
RET
MOV R2,#10 ;延时1秒
LCALL DELAY
*r5+5
DEL : MOV R5,#08H
DEL1: MOV R6,#0FFH
DEL2: MOV R7,#0FFH
DJNZ R7,$
DJNZ R6,DEL2
DJNZ R5,DEL1
RET
;1秒延时子程序是以12MHz晶振
POP R0
POP R1
POP R2
RET
1:DEL: MOV R7, #200
DEL1: MOV R6, #123
NOP
DEL2: DJNZ R6, DEL2
D52: NOP
NOP
NOP
NOP
DJNZ R6,D52
DJNZ R7,D51
POP PSW
RET
DELAY: ;延时1毫秒
PUSH PSW
SETB RS0
MOV R7,#50
D1: MOV R6,#10
D2: DJNZ R6,$
DJNZ R7,D1
51单片机汇编延时程序算法详解
51 单片机汇编延时程序算法详解
51 单片机汇编延时程序算法详解
将以12MHZ 晶振为例,详细讲解MCS-51 单片机中汇编程序延时的精确
算法。
指令周期、机器周期与时钟周期
指令周期:CPU 执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。
时钟周期:也称为振荡周期,一个时钟周期=晶振的倒数。
MCS-51 单片机的一个机器周期=6 个状态周期=12 个时钟周期。
MCS-51 单片机的指令有单字节、双字节和三字节的,它们的指令周期不
尽相同,一个单周期指令包含一个机器周期,即12 个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1μs。
扩展阅读:单片机有
哪些延时方法详细介绍
程序分析
例1 50ms 延时子程序:。
单片机汇编延时程序的理解
单片机汇编延时程序的理解
单片机汇编实现延迟的程序代码:
DELAY:MOV R7,#250 ;
D1:MOV R6,#250 ;
D2:DJNZ R6,D2 ;
DJNZ R7,D1 ;
RET
如果用高级语言编程,只需要简单地调用延时函数就可以实现,但是计算机具体是怎么实现的呢?要想知其所以然,还得从汇编开始学起。
冒号前面的DELAY、D1、D2 为语句行的名字,是为了程序的条件语句跳转用的,分号后面为注释,计算机执行时将过滤掉这些信息,最大限度减少代码长度,提高效率。
DELAY:MOV R7,#250 ;名字为DELAY 的语句:意思是将CPU 内部内存RAM 的R7 位置填写为250(原来为0,为什么是0 呢?因为任何程序开始执行前都要复位,就像我们打算盘要将算子复位一样,或者我们用沙盘写字,要将沙盘抹平类似)
D1:MOV R6,#250 ;名字为D1 的语句:将R6 位置填写为250
D2:DJNZ R6,D2 ;名字为D2 的语句:将R6 位置的250 减1,如果为0 就继续执行下一条,不为0 就继续执行D2 这一句,因为R6=250,所以这个语句要原地踏步执行250 次!
DJNZ R7,D1 ;这句没有名字,因为没有别的语句要跳到这里,所以就省略了。
R7 同样等于250,但它不是原地踏步,而是跳回了D1,这么干,
D!、D2 和本句将被循环执行250 遍,需要强调的是:D2 语句自身每次都要执。
mcs-51单片机中汇编程序延时的精确算法。
MCS-51单片机中汇编程序延时的精确算法一、引言MCS-51单片机是一种常用的微控制器,其汇编程序编写对于工程师来说是极为重要的。
在MCS-51单片机中,延时是一种常见的需求,通过延时可以控制程序的执行速度和时间间隔。
而对于汇编程序中的延时算法,精确度的要求往往较高,特别是在一些实时系统中。
本文将针对MCS-51单片机中汇编程序延时的精确算法展开论述。
二、延时的需求在MCS-51单片机中,实现一定时间的延时是非常常见的需求。
在控制LED灯的闪烁过程中,需要一定的时间间隔来控制LED的亮灭频率;在读取传感器数据的过程中,需要一定的时间延时以确保传感器数据的准确性。
精确和可控的延时算法对于MCS-51单片机的应用来说是至关重要的。
三、常见的延时算法在MCS-51单片机的汇编程序中,常见的延时算法包括循环延时、定时器延时和脉冲宽度调制(PWM)延时等。
这些延时算法各有优缺点,需要根据具体的应用场景选择合适的算法。
1. 循环延时循环延时是一种简单而粗糙的延时算法,其原理是通过空转循环来消耗一定的CPU周期来实现延时。
这种延时算法的缺点是精度较差,受到CPU主频和编译器优化等因素的影响较大,不适合对延时精度有较高要求的场景。
2. 定时器延时定时器延时是一种利用MCS-51单片机内部定时器来实现延时的算法。
通过设置定时器的初值和计数方式,可以实现一定范围内的精确延时。
定时器延时的优点是精度高,不受CPU主频影响,适用于对延时精度要求较高的场景。
3. 脉冲宽度调制(PWM)延时脉冲宽度调制(PWM)延时是一种通过调节脉冲信号的宽度来实现延时的算法。
这种延时算法在一些特定的应用场景中具有较高的灵活性和精度。
例如在直流电机的速度调节过程中常常会采用PWM延时算法来实现精确的速度控制。
四、精确延时算法针对MCS-51单片机中汇编程序延时的精确算法,我们可以结合定时器延时和脉冲宽度调制(PWM)延时的优点,设计一种精确度较高的延时算法。
C及汇编延时程序讲解
有个好帖,从精度考虑,它得研究结果是:void delay2(unsigned char i){while(--i);}为最佳方法。
分析:假设外挂12M(之后都是在这基础上讨论)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay2(0):延时518us 518-2*256=6delay2(1):延时7us(原帖写“5us”是错的,^_^)delay2(10):延时25us 25-20=5delay2(20):延时45us 45-40=5delay2(100):延时205us 205-200=5delay2(200):延时405us 405-400=5见上可得可调度为2us,而最大误差为6us。
精度是很高了!但这个程序的最大延时是为518us 显然不能满足实际需要,因为很多时候需要延迟比较长的时间。
那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。
void delay8(uint t){while(--t);}我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay8(0):延时524551us 524551-8*65536=263delay8(1):延时15usdelay8(10):延时85us 85-80=5delay8(100):延时806us 806-800=6delay8(1000):延时8009us 8009-8000=9delay8(10000):延时80045us 80045-8000=45delay8(65535):延时524542us 524542-524280=262如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序还是不能满足要求的,因为延时最大为524.551ms。
那么用ulong t呢?一定很恐怖,不用看编译后的汇编代码了。
那么如何得到比较小的可调度,可调范围大,并占用比较少得RAM呢?请看下面的程序:/*--------------------------------------------------------------------程序名称:50us 延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77、W78系列对应3M晶振例子提示:调用delay_50us(20),得到1ms延时全局变量:无返回:无--------------------------------------------------------------------*/void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50us(1):延时63us 63-50=13delay_50us(10):延时513us 503-500=13delay_50us(100):延时5013us 5013-5000=13delay_50us(1000):延时50022us 50022-50000=22赫赫,延时50ms,误差仅仅22us,作为C语言已经是可以接受了。
单片机汇编语言设计软件延时程序
单片机汇编语言设计软件延时程序引言:在单片机编程中,经常需要使用延时函数来控制程序的执行时间,例如等待外设初始化完成、延迟发送数据等。
本文将介绍使用汇编语言设计的延时函数。
一、延时原理在单片机中,延时的实现主要通过定时器或循环计数的方式来实现。
定时器通常会使用内部时钟源来产生时钟信号,然后通过预设的计数值来控制定时时间。
循环计数方式则是通过程序在指定循环内部执行空操作的次数来实现延时。
二、定时器延时定时器延时的实现比较简单,只需要设置定时器的计数值和相关控制寄存器即可。
1.使用定时器0延时定时器0是一种常用的定时器,可通过T0计数器、定时器控制寄存器TCON和定时器模式控制寄存器TMOD来实现。
例如,以下是一个使用定时器0的延时函数的实现示例:```assemblydelay_us PROCMOV R4,16 ; 假设使用的是12MHz的晶振,所以每个机器周期为1/12MHz=83.33ns,16个机器周期为1.33usMOVR5,FFH;设置循环的次数delay_usroutine:NOP;执行空操作,延时一个机器周期DJNZ R5,delay_usroutine ;循环R5次RETdelay_us ENDPdelay_ms PROCMOV R7,4 ; 延时1ms需要延时四次1usLOOP:CALL delay_usDJNZR7,LOOPRETdelay_ms ENDP```在上述代码中,delay_us过程使用了16次空操作进行延时,该延时约为1.33us。
delay_ms过程通过循环调用delay_us过程实现了1ms的延时。
2.使用定时器1延时定时器1是使用T1计数器、定时器控制寄存器TCON和定时器模式控制寄存器TMOD来实现的。
例如,以下是一个使用定时器1的延时函数的实现示例:```assemblydelay_us PROCMOV R4,16 ; 假设使用的是12MHz的晶振,所以每个机器周期为1/12MHz=83.33ns,16个机器周期为1.33usMOVR5,FFH;设置循环的次数delay_usroutine:NOP;执行空操作,延时一个机器周期DJNZ R5,delay_usroutine ;循环R5次RETdelay_us ENDPdelay_ms PROCMOV R7,4 ; 延时1ms需要延时四次1usLOOP:CALL delay_usDJNZR7,LOOPRETdelay_ms ENDP```在上述代码中,delay_us过程使用了16次空操作进行延时,该延时约为1.33us。
mcs-51单片机中汇编程序延时的精确算法。 -回复
mcs-51单片机中汇编程序延时的精确算法。
-回复MCs51单片机中的汇编程序延时是一种非常重要的功能,它可以用于控制程序的执行速度,并保证特定操作之间的时间间隔。
在本文中,我们将详细介绍MCs51单片机中汇编程序延时的精确算法,并一步一步回答与此主题相关的问题。
首先,让我们了解一下MCs51单片机的基本原理。
MCs51是一种8位微控制器,广泛应用于各种嵌入式系统中。
它的工作原理是通过读取和执行存储在其内部存储器中的指令来完成各种任务。
延时指令是一种特殊的指令,用于使程序在一定时间内暂停执行。
1. 什么是MCs51单片机中的延时?在MCs51单片机中,延时是指在程序执行过程中暂停一段时间。
这段时间可以是固定的,也可以根据不同的需求和算法进行动态调整。
延时指令是通过向计时器/计数器寄存器写入特定的数值来实现的。
2. MCs51单片机中的延时精确性有多高?MCs51单片机可以实现非常高精度的延时,通常可以达到微秒级别。
这种高精度是由于MCs51单片机的工作频率相对较高,并且可以使用精确的定时器/计数器来控制延时。
3. MCs51单片机中的延时算法是如何工作的?MCs51单片机中的延时算法基于定时器/计数器的工作原理。
定时器/计数器是一种特殊的寄存器,可以产生固定频率的时钟信号。
通过调整寄存器的初值,可以控制定时器/计数器产生的时钟脉冲的数量。
4. 常用的基本延时算法是什么?MCs51单片机中常用的基本延时算法是利用循环来实现的。
具体而言,通过实现一个循环,使程序重复执行一定次数,从而产生延时效果。
循环的次数可以根据不同的算法和需求进行调整。
5. 延时的时间是如何计算的?在MCs51单片机中,延时的时间是通过调整循环次数来实现的。
通常情况下,每次循环的执行时间是固定的,可以根据单片机的工作频率和循环次数进行计算。
例如,如果单片机的工作频率为10MHz,每次循环需要10个时钟周期,那么延时1ms就需要执行10000次循环。
汇编延时1s的延时子程序
汇编延时1s的延时子程序1. 引言在计算机中,延时操作是指暂停程序的执行一段时间。
在某些应用中,需要通过延时来控制程序的执行速度或实现特定的时间间隔。
本文将介绍如何使用汇编语言编写一个延时1秒的延时子程序。
2. 延时原理在汇编语言中,我们可以使用计数器来实现延时操作。
计数器是一个特殊的寄存器,可以用来保存一个定时值,并在每个时钟周期递减。
当计数器的值为零时,表示经过了一段时间,可以继续执行后面的指令。
为了实现1秒钟的延时,我们需要知道CPU的主频(也称为振荡频率),即每秒钟振荡多少次。
假设CPU主频为f,则每个振荡周期为1/f秒。
因此,要实现1秒钟的延时,需要经过f个振荡周期。
3. 编写延时子程序步骤一:初始化计数器首先,我们需要将计数器初始化为CPU主频-1(因为计数器从0开始计数)。
假设CPU主频为f,则初始化计数器的值为f-1。
MOV CX, f-1 ; 初始化计数器为CPU主频-1步骤二:循环减计数器接下来,我们需要使用一个循环来递减计数器的值,直到它变为零。
在每次循环中,我们可以执行一些无关紧要的操作,以消耗一定的时间。
DELAY_LOOP:NOP ; 无操作指令,用于消耗时间LOOP DELAY_LOOP ; 循环减计数器并判断是否为零步骤三:调用延时子程序在我们的主程序中,可以通过调用延时子程序来实现1秒钟的延时。
在调用之前,需要将CPU主频f的值传递给延时子程序。
PUSH f ; 将CPU主频压入栈中CALL DELAY ; 调用延时子程序完整代码示例下面是一个完整的汇编代码示例:DELAY PROC NEARPUSH CX ; 保存寄存器CX的值MOV CX, [BP+4] ; 获取传入的CPU主频值DELAY_LOOP:NOP ; 无操作指令,用于消耗时间LOOP DELAY_LOOP ; 循环减计数器并判断是否为零POP CX ; 恢复寄存器CX的值RET ; 返回到调用者处DELAY ENDPMAIN PROC NEAR; 初始化堆栈等操作省略MOV AX, CPU_FREQUENCY ; 将CPU主频值赋给AX寄存器PUSH AX ; 将AX寄存器的值压入栈中CALL DELAY ; 调用延时子程序; 其他指令省略MAIN ENDP4. 总结通过使用汇编语言编写延时子程序,我们可以实现在程序中添加延时操作。
延时子程序算法详解[]
x延时子程序算法详解在利用MCS-51汇编语言编写单片机应用程序的时候,经常会用延时子程序来配合主程序功能的实现.大部分的延时子程序采用由MOV、NOP、DJNZ指令构成的多重循环程序来实现,然而由于个人编程思路的不同,表现出延时子程序的多样性,使得延时子程序的计算呈现出不定性和复杂性.尤其对于初学者来说,编制一段易于扩展、易于移植的延时程序,掌握延时程序延时长度的计算有一定的困难,因此,研究软件延时程序的模块化、时间长度计算的公式化显得十分必要.笔者在教学过程中,总结出延时程序编写模式(模块)和计算方法,以供广大读者参考.所举的例子全部假设晶振频率为12MHz ,机器周期为1μS.例1、单重循环延时程序该延时程序总的延迟时间为t =R7 *2 +3=100 * 2 +3= 203 μS≈ 200 μS例2、两重循环延时程序该延时程序总的延迟时间为t(R7 =*2 + 3)* R6 + 3=(125*2+3)* 200 + 3= 50603 μS≈ 50 mS例3、三重延时程序该延时程序总的延迟时间t =[(R7 * 2+ 3)* R6+ 3 ] *R5 + 3=[(125 *2 +3) * 200 + 3 )] * 100 + 3=5060.303 mS≈5 S由上面例子我们可概括出一般循环延时程序的结构:上述程序的计算公式没有考虑调用延时程序的指令所占用的机器周期,在对于时间精度要求较高的情况下,必须将该调用指令所占用的时间考虑进去.ACALL、L CALL都占用2个机器周期,所以上述公式最后需加上2 μS .若对时间精度要求不高,可以将上述公式简化如下:t = 循环1次数* 循环2次数* 循环3次数* … * 循环n次数* 2 μS .设计循环次数时,尽可能使内循环次数大,外循环次数小,这样采用简化公式计算时,可减小定时误差.。
51单片机汇编延时程序的设计方法
MOV 为1个机器周期,DNJZ 为2个机器周期,RET 为2个机器周期。
例1:
MAIN: AJMP DELAY1MS
DELAY1MS: ;误差 0us,包含调用时间
MOV R6,#0C7H 1个机器周期 0C7H=199
DL0:
MOV R5,#01H 1个机器周期
例3:
DELAY1MS: ;误差 0us,不包含调用时间
MOV R7,#01H
DL1:
MOV R6,#8EH
DL0:
MOV R5,#02H
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
RET
ห้องสมุดไป่ตู้
例4:
以此为基本的计时单位。如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:
DELAY200MS: MOV R5,#20
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:
石英晶体为12MHz,因此,1个机器周期为1微秒,如果石英晶体为24MHz,1个机器周期为0.5微妙。
MOV R7,#05H
DL1:
MOV R6,#04H
DL0:
MOV R5,#0F8H
DJNZ R5,$
各种汇编延时程序大集合
各种汇编延时程序大集合标签:51单片机汇编延时在论坛上看到不少不错的延时程序,整理如下共同分享:精确延时计算公式:延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+5;延时5秒左右DELAY5S:PUSH 04HPUSH 05HPUSH 06HMOV R4,#50DELAY5S_0:MOV R5,#200 DELAY5S_1:MOV R6,#245 DJNZ R6,$DJNZ R5,DELAY5S_1DJNZ R4,DELAY5S_0POP 06HPOP 05HPOP 04HRET;513微秒延时程序DELAY: MOV R2,#0FEHDELAY1: DJNZ R2,DELAY1RET;10毫秒延时程序DL10MS: MOV R3,#14HDL10MS1:LCALL DELAYDJNZ R3,DL10MS1RET;0.1s延时程序12mhzDELAY: MOV R6,#250DL1: MOV R7,#200DL2: DJNZ R6,DL2DJNZ R7,DL1RET;延时1046549微秒(12mhz);具体的计算公式是:;((((r7*2+1)+2)*r6+1)+2)*r5+1+4 = ((r7*2+3)*r6+3)*r5+5DEL : MOV R5,#08HDEL1: MOV R6,#0FFHDEL2: MOV R7,#0FFHDJNZ R7,$DJNZ R6,DEL2DJNZ R5,DEL1RET;1秒延时子程序是以12MHz晶振Delay1S:mov r1,#50del0: mov r2,#91del1: mov r3,#100djnz r3,$djnz r2,del1djnz r1,del0Ret;1秒延时子程序是以12MHz晶振为例算指令周期耗时KK: MOV R5,#10 ;1指令周期1K1: MOV R6,#0FFH ;1指令周期10K2: MOV R7,#80H ;1指令周期256*10=2560K3: NOP ;1指令周期128*256*10=327680DJNZ R7,K3 ;2指令周期2*128*256*10=655360DJNZ R6,K2 ;2指令周期2*256*10=5120DJNZ R5,K1 ;2指令周期2*10=20RET;2指令周期21+10+2560+327680+655360+5120+20+2=990753 ;约等于1秒1秒=1000000微秒;这个算下来也只有0.998抄T_0: MOV R7,#10;D1: MOV R6,#200;D2: MOV R5,#248;DJNZ R5,$DJNZ R6,D2;DJNZ R7,D1;RET;这样算下来应该是1.000011秒T_0: MOV R7,#10;D1: MOV R6,#200;D2: NOPMOV R5,#248;DJNZ R5,$DJNZ R6,D2;DJNZ R7,D1;RETDELAY_2S: ;10MS(11.0592mhz) MOV R3,#200JMP DELAY10MSDELAY_100MS: ;100MS(11.0592mhz) MOV R3,#10JMP DELAY10MSDELAY_10MS:MOV R3,#1DELAY10MS: ;去抖动10MS(11.0592mhz)MOV R4,#20DELAY10MSA:MOV R5,#247DJNZ R5,$DJNZ R4,DELAY10MSADJNZ R3,DELAY10MSRETDELAY_500MS: ;500500MS MOV R2,#208JMP DELAY_MSDELAY_175MS: ;175MSMOV R2,#73JMP DELAY_MSdelaY_120MS: ;120MSMOV R2,#50JMP DELAY_MSdelay_60ms: ;60msMOV R2,#25JMP DELAY_MSdelay_30ms: ;30msMOV R2,#12JMP DELAY_MSDELAY_5MS: ;5MSMOV R2,#2;=================================== DELAY_MS:CALL DELAY2400DJNZ R2,DELAY_MSRET;=================================== DELAY2400: ;10x244+4=2447/1.024=2390MOV R0,#244 ;1DELAY24001:MUL AB ;4MUL AB ;4DJNZ R0,DELAY24001 ;2RETDELAY: ;延时子程序(1秒)MOV R0,#0AHDELAY1: MOV R1,#00HDELAY2: MOV R2,#0B2HDJNZ R2,$DJNZ R1,DELAY2DJNZ R0,DELAY1RETMOV R2,#10 ;延时1秒LCALL DELAYMOV R2,#50 ;延时5秒LCALL DELAYDELAY: ;延时子程序PUSH R2PUSH R1PUSH R0DELAY1: MOV R1,#00HDELAY2: MOV R0,#0B2HDJNZ R0,$DJNZ R1,DELAY2 ;延时 100 mSDJNZ R2,DELAY1POP R0POP R1POP R2RET1:DEL: MOV R7, #200DEL1: MOV R6, #123NOPDEL2: DJNZ R6, DEL2DJNZ R7, DEL1RET是50.001ms 算法是:0.001ms+200*0.001ms+200*0.001ms+200*123*0.002ms+200*0.002ms ;(123*2+4)*200+12: DEL: MOV R7, #200DEL1: MOV R6, #123DEL2:NOPDJNZ R6,DEL2DJNZ R7,DEL1RETD500MS:PUSH PSWSETB RS0MOV R7,#200D51: MOV R6,#250D52: NOPNOPNOPNOPDJNZ R6,D52DJNZ R7,D51POP PSWRETDELAY: ;延时1毫秒PUSH PSWSETB RS0MOV R7,#50D1: MOV R6,#10D2: DJNZ R6,$DJNZ R7,D1POP PSWRETORG 0LJMP MAINORG 000BHLJMP CTC0MAIN: MOV SP, #50H CLR EAMOV TMOD, #01HMOV TH0,#3CHMOV TL0,#0B0HMOV R4, #10SETB ET0SETB EASETB TR0SJMP $ ;CTC0: MOV TH0, #3CH MOV TL0, #0B0HDJNZ R4, LPCPL P1.0MOV R4, #10LP: RETIEND。
汇编延时程序的原理
汇编延时程序的原理
汇编延时程序的原理是通过循环执行一定数量的指令来使程序暂停一段时间,实现延时的效果。
具体原理如下:
1. 计算机的时钟频率决定了处理器的工作速度,即每秒钟可以执行的指令数量。
假设时钟频率为f,则每个时钟周期的持续时间为1/f秒。
2. 要实现延时,首先需要确定延时的时间长度,假设为T秒。
3. 根据时钟周期的持续时间,可以计算出T所对应的时钟周期数量,即N = T * f。
4. 编写一个循环程序,通过循环执行一定数量的指令来模拟延时。
循环的次数即为N。
5. 循环中的指令可以是任意有效的汇编指令,比如空指令nop、加载/存储指令等,重要的是确保循环次数为N,以实现精确的延时。
延时程序的具体实现方式可能会根据不同的处理器架构和编程环境而有所不同,但基本原理是一致的。
通过循环执行一定数量的指令,可以实现精确的延时效果。
不过需要注意的是,由于现代处理器多核多线程的特性,延时程序的精确性可能受到一些因素的影响,比如其他运行中的线程、中断等。
因此,在编写延时程序时需要考虑这些影响因素,以便获得更加可靠的延时效果。
汇编语言程序设计3
五.子程序
在实际应用中,经常会遇到一些带有通用性的问 题,例如:数值转换、数值计算等,在一个程序中 可能要使用多次。这时可以将其设计成通用的子程 序供随时调用。 子程序主要特点是,在执行过程中需要由其它程 序来调用,执行完后又需要把执行流程返回到调用 该子程序的主程序。 子程序调用时要注意两点: 一是现场的保护和恢复; 二是主程序与子程序的参数传递。
实现程序: NADD:MOV R2,#3 ;三字节加法 CLR C ; NADD1:MOV A,@R0 ;取加数低字节 ADDC A,@R1 ;被加数低字节加A MOV @R0,A ; DEC R0 DEC R1 DJNZ R2,NADD1 INC R0 RET
3.利用堆栈
利用堆栈传递参数是在子程序嵌套中常采用 的一种方法。在调用子程序前,用PUSH指令 将子程序中所需数据压入堆栈,进入执行子程 序时,再用POP指令从堆栈中弹出数据。 例4-11、4-12
一般说来: •当相互传递的数据较少时,采用寄存器或累 加器传递方式可以获得较快的传递速度; •当相互传递的数据较多时,宜采用存储器或
堆栈方式传递;
•如果是子程序嵌套时,最好是采用堆栈方式。
练习: 1.试编程将片内RAM20H~2FH与片内RAM30H~3FH各 自对应单元交换数据。 2.试编程将片内RAM22H单元存放的以ASCII码表示的数, 转换为十六进制数后,存于片内RAM21H单元中。 3.分析下段程序实现的功能。 MOV R0,#35H MOV R1,#3AH CLR C LP1:MOV A,@R0 ADDC A,@R1 MOV @R0,A INC R0 INC R1 DJNZ R3,LP1 LP2:SJMP LP2 END
【例2】 用查表程序求0~40之间整数的立方。已知该整数 存在内RAM30H中,查得立方数存内RAM30H31H中。已知立方 表(双字节)首地址为TAB。 解: MOV DPTR,#TAB ;置立方表首址 MOV A,30H ;读数据 ADD A,30H ;数据×2→A MOV 30H,A ;暂存立方表数据序号 MOVC A, @A+DPTR;读立方数据高8位 XCH A,30H ;存立方数据高8位,立方表数据序号→A INC A ;指向立方数据低8位 MOVC A,@A+DPTR ;读立方数据低8位 MOV 31H,A ;存立方数据低8位 RET TAB: DW 0,0,0,1,0,8,0,27,0,64 DW 0,125,0,216,…,0FAH,00H; 0~40立方表
汇编延时1s的延时子程序
汇编延时1s的延时子程序一、延时子程序的概念延时子程序是指在程序中设置一个时间延迟,使得程序在执行到该子程序时暂停一段时间后再继续执行下一条指令。
在汇编语言中,常用的延时子程序有软件延时和硬件延时两种。
二、软件延时的实现方法1. 循环计数法循环计数法是一种简单而常用的软件延时方法。
其原理是利用CPU进行循环计数,当计数器达到设定值后,即完成了指定的时间延迟。
2. 空循环法空循环法是在循环体内不执行任何有意义的操作,只进行空转等待的方法。
其原理是利用CPU进行忙等待,当指定的时间到达后再继续执行下一条指令。
三、硬件延时的实现方法硬件延时是通过外部电路或芯片来实现的。
常用的硬件延时器有555定时器和8254可编程定时器等。
四、汇编语言实现1s延时子程序以下以循环计数法为例,介绍如何使用汇编语言实现1s延时子程序。
1. 程序思路:(1)将需要等待的时间转换为机器周期;(2)循环计数,当计数器达到指定值时,跳出循环。
2. 程序代码:delay:mov cx, 0FFFFh ;将计数器初始化为最大值mov dx, 0FFFFhdelay1:loop delay1 ;循环计数dec dx ;减少dx的值jnz delay1 ;如果dx不为0,则继续循环dec cx ;减少cx的值jnz delay1 ;如果cx不为0,则继续循环ret ;延时结束,返回3. 程序说明:(1)mov cx, 0FFFFh:将CX寄存器初始化为最大值,即65535;(2)mov dx, 0FFFFh:将DX寄存器初始化为最大值,即65535;(3)loop delay1:循环计数,每次减少CX的值,当CX的值为0时跳出循环;(4)dec dx:每次减少DX的值;(5)jnz delay1:如果DX的值不为0,则跳转到delay1标号处继续执行循环;(6)dec cx:每次减少CX的值;(7)jnz delay1:如果CX的值不为0,则跳转到delay1标号处继续执行循环;(8)ret:延时结束,返回。
汇编延时程序
机器周期微秒
MOV R6,#20 2 个机器周期 2
D1: MOV R7,#248 2 个机器周期 2 2+2×248=498
由以上可知,当R6=10、R7=248 时,延时5ms,R6=20、R7=248 时,
延时10ms,以此为基本的计时单位。如本实验要求0.2 秒=200ms,
10ms×R5=200ms,则R5=20,20*10002=200004us.
延时子程序如下:
即P1.0=0 时,发光二极管L1 亮;我们可以使用SETB P1.0 指令使P1.0
端口输出高电平,使用CLR P1.0 指Y: MOV R5,#20
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
(2). 输出控制
如图1 所示,当P1.0 端口输出高电平,即P1.0=1 时,根据发光二极管
的单向导电性可知,这时发光二极管L1 熄灭;当P1.0 端口输出低电平,
DJNZ R7,$ 2 个机器周期 2+ 2×248= 498
DJNZ R6,D1 2 个机器周期 2+20(2+498)=10002
因此,上面的延时程序时间为10.002ms。
汇编语言延时时间的计算
MOV R0,#0FFH ;1 周期
DJNZ R1,DLY_LP ;2 周期
;外循环延时时间=[内循环延时时间+1+2]255
RET
晶振为12MHz时:
延时时间=[(1+1+2)255+1+2]255×12/12=260.865ms
晶振为11.0592MHz时:
延时时间=[(1+1+2)255+1+2]255×12/11.0592=283.056ms
一个机器周期共有个振荡器周期。
如果振荡器的频率为12MHz,一个振荡器周期为1/12微秒,一个机器周期为12/12=1微秒。
如果振荡器的频率为11.0592MHz,一个振荡器周期为1/11.0592微秒,一个机器周期为12/11.0592=1.085微秒。
如果振荡器的频率为12mhz一个振荡器周期为112微秒一个机器周期为12121微秒
汇编语言延时时间的计算
汇编语言延时时间的计算:
DELAY:
MOV R0,#0FFH ;当晶振为12MHz时
MOV R1,#0FFH ;一个机器周期为1微秒
DLY_LP:
NOP ;1 周期
NOP ;1 周期
DJNZ R0,DLY_LP ;2 周期
C及汇编延时程序讲解
有个好帖,从精度考虑,它得研究结果是:void delay2(unsigned char i){while(--i);}为最佳方法。
分析:假设外挂12M(之后都是在这基础上讨论)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay2(0):延时518us 518-2*256=6delay2(1):延时7us(原帖写“5us”是错的,^_^)delay2(10):延时25us 25-20=5delay2(20):延时45us 45-40=5delay2(100):延时205us 205-200=5delay2(200):延时405us 405-400=5见上可得可调度为2us,而最大误差为6us。
精度是很高了!但这个程序的最大延时是为518us 显然不能满足实际需要,因为很多时候需要延迟比较长的时间。
那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。
void delay8(uint t){while(--t);}我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay8(0):延时524551us 524551-8*65536=263delay8(1):延时15usdelay8(10):延时85us 85-80=5delay8(100):延时806us 806-800=6delay8(1000):延时8009us 8009-8000=9delay8(10000):延时80045us 80045-8000=45delay8(65535):延时524542us 524542-524280=262如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序还是不能满足要求的,因为延时最大为524.551ms。
那么用ulong t呢?一定很恐怖,不用看编译后的汇编代码了。
那么如何得到比较小的可调度,可调范围大,并占用比较少得RAM呢?请看下面的程序:/*--------------------------------------------------------------------程序名称:50us 延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77、W78系列对应3M晶振例子提示:调用delay_50us(20),得到1ms延时全局变量:无返回:无--------------------------------------------------------------------*/void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50us(1):延时63us 63-50=13delay_50us(10):延时513us 503-500=13delay_50us(100):延时5013us 5013-5000=13delay_50us(1000):延时50022us 50022-50000=22赫赫,延时50ms,误差仅仅22us,作为C语言已经是可以接受了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汇编延时程序算法详解
摘要计算机反复执行一段程序以达到延时的目的称为软件延时,单片机应用程序中经常需要短时间延时,有时要求很高的精度,网上或书中虽然有现成的公式可以套用,但在部分算法讲解中发现有错误之处,而且延时的具体算法讲得并不清楚,相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。
关键词 51单片机汇编延时算法
指令周期、机器周期与时钟周期
指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。
时钟周期:也称为振荡周期,一个时钟周期=晶振的倒数。
MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。
MCS-51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1µs。
程序分析
例1 50ms 延时子程序:
DEL:MOV R7,#200 ①
DEL1:MOV R6,#125 ②
DEL2:DJNZ R6,DEL2 ③
DJNZ R7,DEL1 ④
RET ⑤
精确延时时间为:1+(1*200)+(2*125*200)+(2*200)+2
=(2*125+3)*200+3 ⑥
=50603µs
≈50ms
由⑥整理出公式(只限上述写法)延时时间=(2*内循环+3)*外循环+3 ⑦
详解:DEL这个子程序共有五条指令,现在分别就每一条指令被执行的次数和所耗时间进行分析。
第一句:MOV R7,#200 在整个子程序中只被执行一次,且为单周期指令,所以耗时1µs
第二句:MOV R6,#125 从②看到④只要R7-1不为0,就会返回到这句,共执行了R7次,共耗时200µs 第三句:DJNZ R6,DEL2 只要R6-1不为0,就反复执行此句(内循环R6次),又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*R6*R7µs。
例2 1秒延时子程序:
DEL:MOV R7,#10 ①
DEL1:MOV R6,#200 ②
DEL2:MOV R5,#248 ③
DJNZ R5,$ ④
DJNZ R6,DEL2 ⑤
DJNZ R7,DEL1 ⑥
RET ⑦
对每条指令进行计算得出精确延时时间为:
1+(1*10)+(1*200*10)+(2*248*200*10)+(2*200*10)+(2*10)+2
=[(2*248+3)*200+3]*10+3 ⑧
=998033µs≈1s
由⑧整理得:延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑨
此式适用三层循环以内的程序,也验证了例1中式⑦(第三层循环相当于1)的成立。
注意,要实现较长时间的延时,一般采用多重循环,有时会在程式序里加入NOP指令,这时公式⑨不再适用,下面举例分析。
例3仍以1秒延时为例
DEL:MOV R7,#10 1指令周期1
DEL1:MOV R6,#0FFH 1指令周期10
DEL2:MOV R5,#80H 1指令周期255*10=2550
KONG:NOP 1指令周期128*255*10=326400
DJNZ R5,$ 2指令周期2*128*255*10=652800
DJNZ R6,DEL2 2指令周期2*255*10=5110
DJNZ R7,DEL1 2指令周期2*10=20
RET 2
延时时间=1+10+2550+326400+652800+5110+20+2 =986893µs约为1s
整理得:延时时间=[(3*第一层循环+3)*第二层循环+3]*第三层循环+3 ⑩
结论:论文针对初学者的困惑,对汇编程序的延时算法进行了分步讲解,并就几种不同写法分别总结出相应的计算公式,只要仔细阅读例1中的详解,并用例2、例3来加深理解,一定会掌握各种类型程序的算法并加以运用。