汇编延时小程序

汇编延时小程序
汇编延时小程序

汇编延时程序算法详解

电子设计资料2010-05-07 15:28:10 阅读26 评论0 字号:大中小订阅

汇编延时程序算法详解

摘要计算机反复执行一段程序以达到延时的目的称为软件延时,单片机应用程序中经常需要短时间延时,有时要求很高的精度,网上或书中虽然有现成的公式可以套用,但在部分算法讲解中发现有错误之处,而且延时的具体算法讲得并不清楚,相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以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+65280 0+5110+20+2 =986893μs约为

1s

整理得:延时时间=[(3*第一层循环+3)*第二层循环+3]*第三层循

环+3 ⑩

结论:论文针对初学者的困惑,对汇编程序的延时算法进行了分步讲解,并就几种不同写法分别总结出相应的计算公式,只要仔细阅读例1中的详解,并用例2、例3来加深理解,一定会掌握各种类型程序的算法并加以运用。

汇编语言比较准确延时程序

便于初学者,较为精确的延时程序 ;***************************************************************** ;延时10uS ;***************************************************************** time10us: mov r5,#05h ;11us djnz r5,$ ret ;***************************************************************** ;延时50uS ;***************************************************************** time50us: mov r5,#19h ;51us djnz r5,$ ret ;***************************************************************** ;延时100uS ;***************************************************************** time100us: mov r5,#31h ;99.6us djnz r5,$ ret ;***************************************************************** ;延时200uS ;***************************************************************** time200us: mov r5,#64h ;201us djnz r5,$ ret ;***************************************************************** ;延时250uS ;***************************************************************** time250us: mov r5,#7ch ;249.6us djnz r5,$ ret ;***************************************************************** ;延时350uS

KeilC51程序设计中几种精确延时方法

Keil C51程序设计中几种精确延时方法 2008-04-03 08:48 实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。 1 使用定时器/计数器实现精确延时 单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。 在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。 2 软件延时与时间计算 在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。 2.1 短暂延时 可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs 的延时函数可编写如下: void Delay10us( ) { _NOP_( ); _NOP_( ); _NOP_( ) _NOP_( );

汇编延时程序算法详解

汇编延时程序算法详解 摘要计算机反复执行一段程序以达到延时的目的称为软件延时,单片机应用程序中经常需要短时间延时,有时要求很高的精度,网上或书中虽然有现成的公式可以套用,但在部分算法讲解中发现有错误之处,而且延时的具体算法讲得并不清楚,相当一部分人对此仍很模糊,授人鱼,不如授之以渔,本文将以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

51汇编语言程序设计

第四章MCS-51汇编语言程序设计 重点及难点: 单片机汇编语言程序设计的基本概念、伪指令、单片机汇编语言程序的三种基本结构形式、常用汇编语言程序设计。 教学基本要求: 1、掌握汇编语言程序设计的基本概念; 2、掌握伪指令的格式、功能和使用方法; 3、掌握顺序结构、分支结构和循环结构程序设计的步骤和方法; 4、掌握常用汇编语言程序设计步骤和方法。 教学内容 §4.1汇编语言程序设计概述 一、汇编语言的特点 (1)助记符指令和机器指令一一对应,所以用汇编语言编写的程序效率高,占用存储空间小,运行速度快,因此汇编语言能编写出最优化的程序。 (2)使用汇编语言编程比使用高级语言困难,因为汇编语言是面向计算机的,汇编语言的程序设计人员必须对计算机硬件有相当深入的了解。 (3)汇编语言能直接访问存储器及接口电路,也能处理中断,因此汇编语言程序能够直接管理和控制硬件设备。 (4)汇编语言缺乏通用性,程序不易移植,各种计算机都有自己的汇编语言,不同计算机的汇编语言之间不能通用;但是掌握了一种计算机系统的汇编语言后,学习其他的汇编语言就不太困难了。 二、汇编语言的语句格式 [<标号>]:<操作码> [<操作数>];[<注释>] 三、汇编语言程序设计的步骤与特点 (1)建立数学模型 (2)确定算法 (3)制定程序流程图 (4)确定数据结构 (5)写出源程序 (6)上机调试程序 §4.2伪指令 伪指令是程序员发给汇编程序的命令,也称为汇编命令或汇编程序控制指令。 MCS- 51常见汇编语言程序中常用的伪指令:

第四章MCS-51汇编语言程序设计91 1.ORG (ORiGin)汇编起始地址命令 [<标号:>] ORG <地址> 2.END (END of assembly)汇编终止命令 [<标号:>] END [<表达式>] 3.EQU (EQUate)赋值命令 <字符名称> EQU <赋值项> 4.DB (Define Byte)定义字节命令 [<标号:>] DB <8位数表> 5.DW (Define Word)定义数据字命令 [<标号:>] DW <16位数表> 6.DS (Define Stonage )定义存储区命令 [<标号:>] DW <16位数表> 7.BIT位定义命令 <字符名称> BIT <位地址> 8.DA TA数据地址赋值命令 <字符名称> DATA <表达式> §4.3单片机汇编语言程序的基本结构形式 一、顺序程序 [例4-1]三字节无符号数相加,其中被加数在内部RAM的50H、51H和52H单元中;加数在内部RAM的53H、5414和55H单元中;要求把相加之和存放在50H、51H和52H单元中,进位存放在位寻址区的00H位中。 MOV R0 ,# 52H ;被加数的低字节地址 MOV R1 ,# 55H ;加数的低字节地址 MOV A ,@ R0 ADD A ,@ R1 ;低字节相加 MOV @ R0 , A ;存低字节相加结果 DEC R0 DEC R1 MOV A ,@ R0 ADDC A ,@ R1 ;中间字节带进位相加 MOV @ R0 , A ;存中间字节相加结果 DEC R0 DEC R1 MOV A ,@ R0 ADDC A ,@ R1 ;高字节带进位相加 MOV @ R0 , A ;存高字节相加结果 CLR A

多种延时汇编程序集合

;延时5秒左右 DELAY5S:PUSH 04H PUSH 05H PUSH 06H MOV R4,#50 DELAY5S_0:MOV R5,#20 DELAY5S_1:MOV R6,#24 5 DJNZ R6,$ DJNZ R5,DELAY5S_1 DJNZ R4,DELAY5S_ POP 06H POP 05H POP 04H RE T ;513微秒延时程序 DELAY: MOV R2,#0FEH DELAY1: DJNZ R2,DELAY1 RET ;10毫秒延时程序 DL10MS: MOV R3,#14H DL10MS1:LCALL DELAY DJNZ R3,DL10MS1 RET ;0.1s延时程序12mhz DELAY: MOV R6,#250 DL1: MOV R7,#200 DL2: DJNZ R6,DL2 DJNZ R7,DL1 RET ;延时1046549微秒(12mhz) ;具体的计算公式是: ;((((r7*2+1)+2)*r6+1)+2)*r5+1+4 = ((r7*2+3)*r6+3) *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晶振 Delay1S:mov r1,#50 del0: mov r2,#91 del1: mov r3,#100 djnz r3,$ djnz r2,del1 djnz r1,del0 Ret ;1秒延时子程序是以12MHz晶振为例算指令周期耗时KK: MOV R5,#10 ;1指令周期1 K1: MOV R6,#0FFH ;1指令周期10 K2: MOV R7,#80H ;1指令周期256*10=2560 K3: NOP ;1指令周期 128*256*10=327680 DJNZ R7,K3 ;2指令周期 2*128*256*10=655360 DJNZ R6,K2 ;2指令周期 2*256*10=5120 DJNZ R5,K1 ;2指令周期2*10=20 RET ;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: NOP MOV R5,#248; DJNZ R5,$ DJNZ R6,D2;

51单片机精确延时源程序

51单片机精确延时源程序 一、晶振为 11.0592MHz,12T 1、延时 1ms: (1)汇编语言: 代码如下: DELAY1MS: ;误差 -0.651041666667us MOV R6,#04H DL0: MOV R5,#71H DJNZ R5,$ DJNZ R6,DL0 RET (2)C语言: void delay1ms(void) //误差 -0.651041666667us { unsigned char a,b; for(b=4;b>0;b--) for(a=113;a>0;a--); } 2、延时 10MS: (1)汇编语言: DELAY10MS: ;误差 -0.000000000002us MOV R6,#97H DL0: MOV R5,#1DH DJNZ R5,$ DJNZ R6,DL0

RET (2)C语言: void delay10ms(void) //误差 -0.000000000002us { unsigned char a,b; for(b=151;b>0;b--) for(a=29;a>0;a--); } 3、延时 100MS: (1)汇编语言: DELAY100MS: ;误差 -0.000000000021us MOV R7,#23H DL1: MOV R6,#0AH I

棋影淘宝店:https://www.360docs.net/doc/3812681083.html,QQ:149034219 DL0: MOV R5,#82H DJNZ R5,$ DJNZ R6,DL0 DJNZ R7,DL1 RET (2)C语言: void delay100ms(void) //误差 -0.000000000021us { unsigned char a,b,c; for(c=35;c>0;c--) for(b=10;b>0;b--) for(a=130;a>0;a--); } 4、延时 1S: (1)汇编语言: DELAY1S: ;误差 -0.00000000024us MOV R7,#5FH DL1: MOV R6,#1AH DL0: MOV R5,#0B9H DJNZ R5,$ DJNZ R6,DL0 DJNZ R7,DL1 RET (2)C语言: void delay1s(void) //误差 -0.00000000024us { unsigned char a,b,c; for(c=95;c>0;c--) for(b=26;b>0;b--)

汇编延时程序讲解

延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器 周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指 令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者 我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如 在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何 实现的呢?下面让我们先来了解一些相关的概念。 一、机器周期和指令周期 1.机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度, 51 单片机的一个机器周期包括12 个时钟振荡周期,也就是说如果51 单片机采用12MHz 晶振,那么执行 一个机器周期就只需要1μs;如果采用的是6MHz 的晶振,那么执行一个机器周期就需要2 μs。 2 .指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。 在51 单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个 机器周期),四周期指令(执行这条指令需要四个机器周期)。除了乘、除两条指令是四周期指令,其余均 为单周期或双周期指令。也就是说,如果51 单片机采用的是12MHz 晶振,那么它执行一条指令一般只需 1~2 微秒的时间;如果采用的是6MH 晶振,执行一条指令一般就需2~4 微秒的时间。 现在的单片机有很多种型号,但在每个型号的单片机器件手册中都会详细说明执行各种指令所需的机

器周期,了解以上概念后,那么可以依据单片机器件手册中的指令执行周期和单片机所用晶振频率来完成 需要精确延时时间的延时程序。 二、延时指令 在单片机编程里面并没有真正的延时指令,从上面的概念中我们知道单片机每执行一条指令都需要一 定的时间,所以要达到延时的效果,只须让单片机不断地执行没有具体实际意义的指令,从而达到了延时 的效果。 1.数据传送指令 MOV 数据传送指令功能是将数据从一个地方复制、拷贝到另一个地方。 如:MOV R7,#80H ;将数据80H 送到寄存器R7,这时寄存器R7 里面存放着80H,就单这条 指令而言并没有任何实际意义,而执行该指令则需要一个机器周期。 2.空操作指令 NOP 空操作指令功能只是让单片机执行没有意义的操作,消耗一个机器周期。 3.循环转移指令 DJNZ 循环转移指令功能是将第一个数进行减1 并判断是否为0,不为0 则转移到指定地点;为0 则往下执行。 如:DJNZ R7,KK ;将寄存器R7 的内容减1 并判断寄存器R7 里的内容减完1 后是否为0,如果 不为0 则转移到地址标号为KK 的地方;如果为0 则执行下一条指令。这条指令需要2 个机器周期。 利用以上三条指令的组合就可以比较精确地编写出所需要的延时程序。 三、1 秒延时子程序、流程图及时间计算(以单片机晶振为12MHz 为例, 1 个机器周期需要1μs) 了解了以上的内容,现在让我们来看看

TMS320F2812delay 延时完整程序

TMS320F2812的延时程序(完整) .def _DSP28x_usDelay ;==================================================== ;Delay Function ;The C assembly call will look as follows: ; ; extern void Delay(long time); ; MOV AL,#LowLoopCount ; MOV AH,#HighLoopCount ; LCR _Delay ; ;Or as follows (if count is less then 16-bits): ; ; MOV ACC,#LoopCount ; LCR _Delay .global __DSP28x_usDelay _DSP28x_usDelay: SUB ACC,#1 NOP NOP BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0 LRETR ;There is a 9/10 cycle overhead and each loop ;takes five cycles. The LoopCount is given by ;the following formula: ; DELAY_CPU_CYLES = 9 + 5*LoopCount ; LoopCount = (DELAY_CPU_CYCLES - 9) / 5 ;================================================== --

RE:我是这么调用的(C语言) extern void DSP28x_usDelay(long time); 在需要延时的地方加入 DSP28x_usDelay(0x100000);//根据延迟时间写入参数

延时子程序

汇编延时程序大集合 2009-05-31 19:24 各种汇编延时程序大集合 ;513微秒延时程序 DELAY: MOV R2,#0FEH DELAY1: DJNZ R2,DELAY1 RET ;10毫秒延时程序 DL10MS: MOV R3,#14H DL10MS1:LCALL DELAY DJNZ R3,DL10MS1 RET ;0.1s延时程序12mhz DELAY: MOV R6,#250 DL1: MOV R7,#200 DL2: DJNZ R6,DL2 DJNZ R7,DL1 RET ;延时1046549微秒(12mhz) ;具体的计算公式是: ;((((r7*2+1)+2)*r6+1)+2)*r5+1+4 = ((r7*2+3)*r6+3) *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晶振 Delay1S:mov r1,#50 del0: mov r2,#91

del1: mov r3,#100 djnz r3,$ djnz r2,del1 djnz r1,del0 Ret ;1秒延时子程序是以12MHz晶振为例算指令周期耗时 KK: MOV R5,#10 ;1指令周期1 K1: MOV R6,#0FFH ;1指令周期10 K2: MOV R7,#80H ;1指令周期256*10=2560 K3: NOP ;1指令周期 128*256*10=327680 DJNZ R7,K3 ;2指令周期 2*128*256*10=655360 DJNZ R6,K2 ;2指令周期 2*256*10=5120 DJNZ R5,K1 ;2指令周期2*10=20 RET ;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: NOP MOV R5,#248;

STM32的几种延时方法

STM32的几种延时方法(基于MDK固件库3.0,晶振8M) 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms()。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。 //粗延时函数,微秒 void delay_us(u16 time) { u16 i=0; while(time--) { i=10; //自己定义 while(i--) ; } } //毫秒级的延时 void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; //自己定义 while(i--) ; } } 2.SysTick 定时器延时 CM3 内核的处理器,内部包含了一个SysTick定时器,SysTick是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。SysTick 在STM32 的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3 权威指南》。 这里面也有两种方式实现: a.中断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。 volatile unsigned long time_delay; // 延时时间,注意定义为全局变量 //延时n_ms void delay_ms(volatile unsigned long nms) { //SYSTICK分频--1ms的系统时钟中断 if (SysTick_Config(SystemFrequency/1000))

delay延时教程

delay延时教程(用的是12MHz晶振的MCS-51) 一、 1)NOP指令为单周期指令 2)DJNZ指令为双周期指令 3)mov指令为单周期指令 4)子程序调用(即LCALL指令)为双周期指令 5)ret为双周期指令 states是指令周期数, sec是时间,=指令周期×states,设置好晶振频率就是准确的了 调试>设置/取消断点”设置或移除断点,也可以用鼠标在该行双击实现同样的功能 二、编程最好: 1.尽量使用unsigned型的数据结构。 2.尽量使用char型,实在不够用再用int,然后才是long。 3.如果有可能,不要用浮点型。 4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。 5.在do…while,while语句中,循环体内变量也采用减减方法。 三、编辑注意: 1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。 2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。 3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。 四、a:delaytime为us级 直接调用库函数: #include// 声明了void _nop_(void); _nop_(); // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。 eg:可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C 文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下: void Delay10us( ) { _NOP_( ); _NOP_( );

用汇编语言编写1ms延时程序

用汇编语言编写1ms延时程序 实验题目:设计延时时间1ms的程序 实验目的:通过该延时时间程序的实验设计,了解运行程序时的我们可以通过该程序进行程序的延时操作,以便达到我们的操作目的。 实验设备:计算机一台。 实验程序:参考附录A 实验内容: 题目分析:题目是让计算机做一些无用的操作,来拖延时间。可以根据一条指令执行时间需要几个时钟周期,即几个微妙,来编程延时程序,也就可以利用循环程序结构。 由查表可得,我们可以用PUSHF和POPF指令来进行编程。而延时的时间主要取决于循环体及循环次数。而PUSHF和POPF指令分别为10和8个时钟节拍,LOOP BX指令为3.4个时钟节拍,即此循环体需要用10+8+3.4=21.4拍,而每个时钟节拍是根据此系统的晶振频率而定的。假设系统用的是8Mhz的晶振,则每个时钟节拍需要0.125μs,因此我们可以根据下列公 式算出循环次数: 换算成十六进制数为176H。下图为程序流程图:

六、实验总结:此程序中内循环是1ms时间,而在外循环中的两条控制指令DEC和JNZ所对应的时钟节拍分别为2个和4个,一共只需0.75μs,与1ms比较极短,所以我们在外循环里忽略不计了,外循环的循环初值为1000次,对应的十六进制为3E8H。有时候我们需要计算机为我们“空”一点时间来进行空操作,即什么也不用做,我们可以通过上述的延时时间子程序来达到目的。 附录A 延时1ms的程序如下: START: MOV CX,176H ;初始化,设定循环次数CX=376 LP1:PUSHF ;循环体 POPF LOOP LP1 ; CX CX-1,若CX0转LP1 HLT ;暂停 延时1s的程序如下: MOV BX,3E8H ; BX 1000 LP2:MOV CX,176H LP1: PUSHF POPF 延时1ms程序段 LOOP LP1 DEC BX DEC BX ; BX BX-1 JNZ LP2 ;ZF=0时,转至LP2,即BX0时转 HLT ;暂停 参考文献 郑学坚,周斌编著.微型计算机原理及应用(第三版).清华大学出版社.2001

实验三 DSP汇编语言基本程序设计1

实验三 DSP 汇编语言基本程序设计(二) 一、实验目的 1. 掌握小数运算和数据块传送指令及程序设计方法。 2. 熟悉长字运算和并行运算指令及程序设计方法。 二、实验环境 1.奔腾IV 计算机 2.Code Composer Studio (CCS)软件 三、实验内容 1.小数运算 C54x’采用2的补码表示小数,一个十进制小数乘以32768,再将其十进制整数部分转换 成十六进制数,即可得到该十进制小数的2的补码表示。 1) 汇编语言中不能直接写入十进制小数,若要定义0.707,则应写成 .word 32768*707/1000 2) 消除两个带符号数相乘时产生的冗余符号位命令: SSBX FRCT 已知:a1=0.1,a2=0.2,a3=-0.3,a4=0.4,x1=0.8,x2=0.6,x3=-0.4,x4=-0.2求:y=∑=41i i i x a ;源程序 ch3p1.asm .mmregs STACK .usect "STACK",10H .bss a,4 .bss x,4 .bss y,1 .def aa .data table: .word 1*32768/10 .word 2*32768/10 .word -3*32768/10 .word 4*32768/10 .word 8*32768/10 .word 6*32768/10 .word -4*32768/10 .word -2*32768/10 .text aa: SSBX FRCT STM #a,AR1 RPT #7 MVPD table,*AR1+ ; 将程序存储空间中标号为”table ”的地址里的数据存入AR1所 指向的数据存储空间,且地址AR1加1--------属于绝对寻址 STM #x,AR2 ; (AR2)=x STM #a,AR3 RPTZ A,#3 MAC *AR2+,*AR3+,A ; (A)=(A)+(AR2)*(AR3),AR2、AR3地址+1 STH A,@y ; (y)=(A)

C及汇编延时程序讲解

有个好帖,从精度考虑,它得研究结果是: void delay2(unsigned char i) { while(--i); } 为最佳方法。 分析:假设外挂12M(之后都是在这基础上讨论) 我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据: delay2(0):延时518us 518-2*256=6 delay2(1):延时7us(原帖写“5us”是错的,^_^) delay2(10):延时25us 25-20=5 delay2(20):延时45us 45-40=5 delay2(100):延时205us 205-200=5 delay2(200):延时405us 405-400=5 见上可得可调度为2us,而最大误差为6us。 精度是很高了! 但这个程序的最大延时是为518us 显然不 能满足实际需要,因为很多时候需要延迟比较长的时间。 那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。 void delay8(uint t) { while(--t); } 我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据: delay8(0):延时524551us 524551-8*65536=263 delay8(1):延时15us delay8(10):延时85us 85-80=5 delay8(100):延时806us 806-800=6 delay8(1000):延时8009us 8009-8000=9 delay8(10000):延时80045us 80045-8000=45 delay8(65535):延时524542us 524542-524280=262 如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序还是不能满足要求的,因为延时最大为524.551ms。 那么用ulong t呢? 一定很恐怖,不用看编译后的汇编代码了。。。

单片机汇编延时系统

51单片机延时程序 2012-09-19 11:28:59| 分类:技术|字号订阅 延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器 周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指 令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者 我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如 在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何 实现的呢?下面让我们先来了解一些相关的概念。 一、机器周期和指令周期 1.机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度, 51 单片机的一个机器周期包括12 个时钟振荡周期,也就是说如果51 单片机采用12MHz 晶振,那么执行 一个机器周期就只需要1μs;如果采用的是6MHz 的晶振,那么执行一个机器周期就需要2 μs。 2 .指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。 在51 单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个 机器周期),四周期指令(执行这条指令需要四个机器周期)。除了乘、除两条指令是四周期指令,其余均

为单周期或双周期指令。也就是说,如果51 单片机采用的是12MHz 晶振,那么它执行一条指令一般只需 1~2 微秒的时间;如果采用的是6MH 晶振,执行一条指令一般就需2~4 微秒的时间。 现在的单片机有很多种型号,但在每个型号的单片机器件手册中都会详细说明执行各种指令所需的机 器周期,了解以上概念后,那么可以依据单片机器件手册中的指令执行周期和单片机所用晶振频率来完成 需要精确延时时间的延时程序。 二、延时指令 在单片机编程里面并没有真正的延时指令,从上面的概念中我们知道单片机每执行一条指令都需要一 定的时间,所以要达到延时的效果,只须让单片机不断地执行没有具体实际意义的指令,从而达到了延时 的效果。 1.数据传送指令 MOV 数据传送指令功能是将数据从一个地方复制、拷贝到另一个地方。 如:MOV R7,#80H ;将数据80H 送到寄存器R7,这时寄存器R7 里面存放着80H,就单这条 指令而言并没有任何实际意义,而执行该指令则需要一个机器周期。 2.空操作指令 NOP 空操作指令功能只是让单片机执行没有意义的操作,消耗一个机器周期。 3.循环转移指令 DJNZ 循环转移指令功能是将第一个数进行减1 并判断是否为0,不为0 则转移到指定地点;为0 则往下执行。 如:DJNZ R7,KK ;将寄存器R7 的内容减1 并判断寄存器R7 里的内容减完1 后是否为0,如果

七段码显示汇编语言程序设计

课程设计任务书 学生姓名专业班级 指导教师黄珍工作单位自动化学院 课程设计题目七段码显示汇编语言程序设计 初始条件: 采用16位微处理器8086 CPU以及86系列微型计算机的指令系统; 软件设计平台为多功能微型计算机实验软件MFS中的微机原理实验集成环境MF2KP。 要求完成的主要任务: 设计汇编语言程序,实现七段码显示效果,具体功能要求如下:(1)数字0~9或A~F中的每个数字、字母用“¦”和“—”字符组成的“七段”码图形表示; (2)运行程序后,要求数字0~9或字母A~F依次循环显示; (3)单击“Q”或“q”键退出程序。。 根据功能要求绘制程序流程图、编写完整的汇编语言程序并上机调试: 撰写课程设计说明书。课程设计说明书的撰写格式如下: (1)设计说明书包括封面、任务书(指导老师提供)、正文、参考文献(3~5篇)、附录(程序清单,要求有注释)、成绩评定表(指导老师提供)。 (2)说明书正文包含总体方案论证(算法说明);程序流程图设计及其说明; 软件设计关键问题或程序段落的说明;程序调试说明、结果记录及分析; 课程设计收获及心得体会。 (3)同一选题若为合作完成,设计说明书中需注明本人承担的设计部分。 (本次课程设计时间:2011年1月10日-21日,历时两周) 指导教师签名:年月日 系主任(或责任教师)签名:年月日

目录 1 总体方案论证 (1) 1.1 七段数码管显示功能分析 (1) 1.2 算法说明 (1) 2 程序流程图设计及其说明 (3) 2.1 程序流程图 (3) 2.2 程序流程图说明 (4) 3程序段落的说明 (5) 3.1 数据段定义 (5) 3.2 程序初始化 (5) 3.3 清空显示屏 (5) 3.4 重置光标 (6) 3.5 数码显示处理工作 (6) 3.6 取得计数并为下次循环准备 (6) 3.7 一个数字的数码管显示 (6) 3.8 显示程序 (7) 3.9 程序延时部分 (7) 3.10 判断键盘输入部分 (7) 3.11 结束DOS以及跳出语句 (8) 4 程序调试说明、结果记录及分析 (9) 5 课程设计收获及心得体会 (13) 参考文献 (14) 附录 (15)

STM32的几种延时方法

STM32的几种延时方法(基于MDK固件库,晶振8M)单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。 断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。 volatile unsigned long time_delay; 中断方式 主要仿照原子的《STM32不完全手册》。SYSTICK 的时钟固定为HCLK 时钟的1/8,在这里我们选用内部时钟源72M,所以SYSTICK的时钟为9M,即SYSTICK 定时器以9M的频率递减。SysTick 主要包含CTRL、LOAD、VAL、CALIB 等4 个寄存器, 程序如下,相当于查询法。 //仿原子延时,不进入systic中断

void delay_us(u32 nus) { u32 temp; SysTick->LOAD = 9*nus; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void delay_ms(u16 nms) { u32 temp; SysTick->LOAD = 9000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } 三种方式各有利弊,第一种方式容易理解,但不太精准。第二种方式采用库函数,编写简单,由于中断的存在,不利于在其他中断中调用此延时函数。第三种方式直接操作寄存器,看起来比较繁琐,其实也不难,同时克服了以上两种方式的缺点,个人感觉比较好用。

单片机延时汇编语言计算方法

单片机延时汇编语言计算方法 我们用汇编语言写单片机延时10ms 的程序(用的是12MHz 晶振的MCS- 51),可以编写下面的程序来实现:MOV R5,#5 ①D1: MOV R6,#4 ②D2: MOV R7,#248 ③DJNZ R7,$ ④DJNZ R6,D2 ⑤DJNZ R5,D1 ⑥RET ⑦这个延时程序共有七条指令,现在就每一条指令执行的次数和所耗时间进行分析:第一条,MOV R5,#5 在整个程 序中只执行一次,且为单周期指令,所以耗时1μs,第二条, MOV R6,#4 看⑥的指令可知,只要R5-1 不为0,就会返回执行这条指令,共执行了R5 次,共耗时5μs,第三条,MOV R7,#248 同第二条类似,只要R6-1 不为0,就会返回执行这条指令,同时受到外部循环R5 的控制,共耗时R5*R6*1=20μs,第四条,DJNZ R7,$ 只要R7-1 不为0,就执行这条指令,同时受到外部循环的控制,由于该指令是双周期指令,共耗时为R7*R6*R5*2=9920μs,第五条,DJNZ R6,D2 只要R6-1 不为0,就反复执行此条指令(内循环R6 次),又受外循环R7 的控制, 共耗时R6*R5*2=40μs,第六条,DJNZ R5,D1 只要R5-1 不为0,就反复执行此条指令,耗时为R5*2=10μs,第七条,RET 此指令为双周期指令,耗时为2μs,我们也要考虑在调用子程序时用到 LCALL 指令,耗时2μs,最后可以得到总的延时为: 1+5+20+9920+40+10+2=9998μs=10ms 我们可以总结延时总时间的公式:延时总时间=[(2*一层循环次数+3)*二层循环次数+3]*三层循环次数+3 注意此公式 只适用于三层以内的循环tips:感谢大家的阅读,本文由我司收集整编。仅供参阅!

相关文档
最新文档