搜档网
当前位置:搜档网 › 延时子程序的延时计算问题

延时子程序的延时计算问题

延时子程序的延时计算问题
延时子程序的延时计算问题

延时子程序的延时计算问题

对于程序 DELAY:

MOV R0,#00H

DELAY1: MOV R1,#0B3H

DJNZ R1,$

DJNZ R0,DELAY1

查指令表可知 MOV一个机器周期,DJNZ 指令需用两个机器周期,而一个机器周期时间长度为12/11.0592MHz,所以该段程序执行时间为:

((0B3×2+1+2)×256+1)×12÷11059200=100.2789mS

第一层:DJNZ R1,$:执行了B3H次,一次两个周期,所以为0B3×2;

第二层:MOV R1,#0B3H为一个周期,DJNZ R0,DELAY1为两个周期,这样循环一次就是0B3×2+1+2个周期;第二层的执行次数本来是255次,但因为赋首值为0,而DJNZ是先减1,再比较的,所以就应该是256次。

这样的话,整个循环执行完应该是(0B3×2+1+2)×256+1次。再加上开始赋值这一句,就是((0B3×2+1+2)×256+1)了

不过一些要求不是很高的场合用0B3*256*2就可以了..

单片机C语言(for)延时计算

C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。 一. 500ms延时子程序 程序: void delay500ms(void) { unsigned char i,j,k; for(i=15;i>0;i--) for(j=202;j>0;j--) for(k=81;k>0;k--); } 计算分析: 程序共有三层循环 一层循环n:R5*2 = 81*2 = 162us DJNZ 2us 二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us 三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值1us = 3us 循环外: 5us 子程序调用2us + 子程序返回2us + R7赋值1us = 5us 延时总时间= 三层循环+ 循环外= 499995+5 = 500000us =500ms 计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5 二. 200ms延时子程序 程序: void delay200ms(void) { unsigned char i,j,k;

for(i=5;i>0;i--) for(j=132;j>0;j--) for(k=150;k>0;k--); } 三. 10ms延时子程序程序: void delay10ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } 四. 1s延时子程序 程序: void delay1s(void) { unsigned char h,i,j,k; for(h=5;h>0;h--) for(i=4;i>0;i--) for(j=116;j>0;j--) for(k=214;k>0;k--); }

C语言延时程序

C51精确延时程序 一、、看了网上延时程序的帖子挺多,我也说点。 用keil调试, void yanshi( uint n ) { uchar data i="0"; for(i=0;i<N;I++); return; } 延时时间=12*(n*12+17)/fosc 用keil测时功能很容易得到这个关系,很精确,偏差不过几us. 可以自己编一些延时程序,也可以很方便的得到关系式,只是系数不同. 二、、//我看到的地方也是从别的地方转贴,所以我不知道原作者是谁,但相信这么成熟的东西转一下他也不会见意。看到了个好帖,我在此在它得基础上再抛抛砖! 有个好帖,从精度考虑,它得研究结果是: 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型的时候,会出现什么情况。

延时子程序计算方法

学习MCS-51单片机,如果用软件延时实现时钟,会接触到如下形式的延时子程序:delay:mov R5,#data1 d1:mov R6,#data2 d2:mov R7,#data3 d3:djnz R7,d3 djnz R6,d2 djnz R5,d1 Ret 其精确延时时间公式:t=(2*R5*R6*R7+3*R5*R6+3*R5+3)*T (“*”表示乘法,T表示一个机器周期的时间)近似延时时间公式:t=2*R5*R6*R7 *T 假如data1,data2,data3分别为50,40,248,并假定单片机晶振为12M,一个机器周期为10-6S,则10分钟后,时钟超前量超过1.11秒,24小时后时钟超前159.876秒(约2分40秒)。这都是data1,data2,data3三个数字造成的,精度比较差,建议C描述。

上表中e=-1的行(共11行)满足(2*R5*R6*R7+3*R5*R6+3*R5+3)=999,999 e=1的行(共2行)满足(2*R5*R6*R7+3*R5*R6+3*R5+3)=1,000,001 假如单片机晶振为12M,一个机器周期为10-6S,若要得到精确的延时一秒的子程序,则可以在之程序的Ret返回指令之前加一个机器周期为1的指令(比如nop指令), data1,data2,data3选择e=-1的行。比如选择第一个e=-1行,则精确的延时一秒的子程序可以写成: delay:mov R5,#167 d1:mov R6,#171 d2:mov R7,#16 d3:djnz R7,d3 djnz R6,d2

djnz R5,d1 nop ;注意不要遗漏这一句 Ret 附: #include"iostReam.h" #include"math.h" int x=1,y=1,z=1,a,b,c,d,e(999989),f(0),g(0),i,j,k; void main() { foR(i=1;i<255;i++) { foR(j=1;j<255;j++) { foR(k=1;k<255;k++) { d=x*y*z*2+3*x*y+3*x+3-1000000; if(d==-1) { e=d;a=x;b=y;c=z; f++; cout<<"e="<

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

汇编延时程序算法详解

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

一、关于单片机周期的几个概念 ●时钟周期 时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12MHz的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。 在一个时钟周期内,CPU仅完成一个最基本的动作。 ●机器周期 完成一个基本操作所需要的时间称为机器周期。 以51为例,晶振12M,时钟周期(晶振周期)就是(1/12)μs,一个机器周期包 执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。 对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。 1.指令含义 DJNZ:减1条件转移指令 这是一组把减1与条件转移两种功能结合在一起的指令,共2条。 DJNZ Rn,rel ;Rn←(Rn)-1 ;若(Rn)=0,则PC←(PC)+2 ;顺序执行 ;若(Rn)≠0,则PC←(PC)+2+rel,转移到rel所在位置DJNZ direct,rel ;direct←(direct)-1 ;若(direct)= 0,则PC←(PC)+3;顺序执行 ;若(direct)≠0,则PC←(PC)+3+rel,转移到rel 所在位置 2.DJNZ Rn,rel指令详解 例:

MOV R7,#5 DEL:DJNZ R7,DEL; rel在本例中指标号DEL 1.单层循环 由上例可知,当Rn赋值为几,循环就执行几次,上例执行5次,因此本例执行的机器周期个数=1(MOV R7,#5)+2(DJNZ R7,DEL)×5=11,以12MHz的晶振为例,执行时间(延时时间)=机器周期个数×1μs=11μs,当设定立即数为0时,循环程序最多执行256次,即延时时间最多256μs。 2.双层循环 1)格式: DELL:MOV R7,#bb DELL1:MOV R6,#aa DELL2:DJNZ R6,DELL2; rel在本句中指标号DELL2 DJNZ R7,DELL1; rel在本句中指标号DELL1 注意:循环的格式,写错很容易变成死循环,格式中的Rn和标号可随意指定。 2)执行过程

单片机延时计算

单片机C51延时时间怎样计算? C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int 更优化的代码,在使用时应该使用unsigned char作为延时变量。以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。 一. 500ms延时子程序 程序: void delay500ms(void) { unsigned char i,j,k; for(i=15;i>0;i--) for(j=202;j>0;j--) for(k=81;k>0;k--); } 计算分析: 程序共有三层循环 一层循环n:R5*2 = 81*2 = 162us DJNZ 2us 二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值 1us = 3us 三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值 1us = 3us 循环外: 5us 子程序调用 2us + 子程序返回 2us + R7赋值 1us = 5us 延时总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms 计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5 二. 200ms延时子程序

程序: void delay200ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=132;j>0;j--) for(k=150;k>0;k--); } 三. 10ms延时子程序 程序: void delay10ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } 四. 1s延时子程序 程序: void delay1s(void) { unsigned char h,i,j,k;

多种延时汇编程序集合

;延时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;

延时计算

t=n*(分频/f) t:是你所需的延时时间 f:是你的系统时钟(SYSCLK) n:是你所求,用于设计延时函数的 程序如下: void myDelay30s() reentrant { unsigned inti,k; for(i=0;i<4000;i++) /*系统时钟我用的是24.576MHZ,分频是12分频,达到大约10s延时*/ for(k=0;k<8000;k++); } //n=i*k |评论 2012-2-18 20:03 47okey|十四级 debu(g调试),左侧有运行时间。在你要测试的延时子函数外设一断点,全速运行到此断点。记下时间,再单步运行一步,跳到下一步。再看左侧的运行时间,将这时间减去上一个时间,就是延时子函数的延时时间了。不知能不能上图。 追问 在delayms处设置断点,那么对应的汇编语言LCALL是否被执行呢?还有,问问您,在C8051F020单片机中,MOV指令都是多少指令周期呢?我在KEIL下仿真得出的结果,与我通过相应的汇编语言分析的时间,总是差了很多。 回答 C编译时,编译器都要先变成汇编。只想知道延时时间,汇编的你可以不去理会。只要看运行时间就好了。 at8051单片机12m晶振下,机器周期为1us,而c8051 2m晶振下为1us。keil 调试里频率默认为24m,你要设好晶振频率。

|评论 2012-2-23 11:17 kingranran|一级 参考C8051单片机内部计时器的工作模式,选用合适的计时器进行中断,可获得较高精度的延时 |评论 2012-2-29 20:56 衣鱼ccd1000|一级 要是精确延时的话就要用定时器,但定的时间不能太长,长了就要设一个变量累加来实现了; 要是不要求精确的话就用嵌套for函数延时,比较简单,但是程序复杂了就会增添不稳定因素,所以不推荐。 |评论

用单片机实现延时(自己经验及网上搜集).

标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。这在汇编语言中很容易实现,写几个nop就行了。 在keil C51中,直接调用库函数: #include // 声明了void _nop_(void; _nop_(; // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。 在选择C51中循环语句时,要注意以下几个问题 第一、定义的C51中循环变量,尽量采用无符号字符型变量。 第二、在FOR循环语句中,尽量采用变量减减来做循环。 第三、在do…while,while语句中,循环体内变量也采用减减方法。 这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。 下面举例说明: unsigned char i; for(i=0;i<255;i++; unsigned char i; for(i=255;i>0;i--;

其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令: MOV 09H,#0FFH LOOP: DJNZ 09H,LOOP 指令相当简洁,也很好计算精确的延时时间。 同样对do…while,while循环语句中,也是如此 例: unsigned char n; n=255; do{n--} while(n; 或 n=255; while(n {n--}; 这两个循环语句经过C51编译之后,形成DJNZ来完成的方法, 故其精确时间的计算也很方便。 其三:对于要求精确延时时间更长,这时就要采用循环嵌套的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。对于循环语句同样可以采用for,do…while,while结构来完成,每个循环体内的变量仍然采用无符号字符变量。 unsigned char i,j for(i=255;i>0;i--

单片机延时计算

单片机延时计算 1.10ms延时程序(for循环嵌套) ********************************************************************* 文件名称:void delay_10ms()功能:10ms延时参数:单片机晶振12MHz ********************************************************************* void delay_10ms() { unsigned inti,j; for(i=0;i<10;i++) { for(j=0;j<124;j++); } } **i和j定义为int整型时,for循环执行时间为8个机器周期,当i和j定义为char 字符型时,for循环执行时间3个机器周期。“;”一个机器周 期,每次调用for循环2个机器周期。 **则执行本段延时程序是内循环时间t1=8*124+3个机器周期,其中“8”执行for 循环指令时间;“124”为for循环次数;“3”为每次调用 for循环指令的时间。外循环t2=t1*10+8*10+3其中“10”为for循环次数;“8”为一次for循环指令调用和执行时间;“10”为调用for循环 次数,3为调用for循环指令时间。 **所以本程序延时t=((8*124)+3)*10+8*10+3=10033=10.033ms≈10ms。 注意:变量为整型时,每次调用for循环需要3个机器周期的调用时间,执行for 循环判断需要8个机器周期的执行时间;字符型变量时,每次调用for循环需要2个机器周期的调用时间,执行for循环判断需要3个机器周期的执行时间。

c语言中的精确延时程序举例

c语言中的精确延时程序举例 我在网上到看了一些关于延时的讨论,其中有篇文章51单片机Keil C 延时程序的简单研究,作者:InfiniteSpace Studio/isjfk 写得不错,他是用while(--i);产生DJNZ 来实现精确延时,后来有人说如果while里面不能放其它语句,否则也不行,用do-while就可以,具体怎样我没有去试.所有这些都没有给出具体的实例程序来.还看到一些延时的例子多多少少总有点 延时差.为此我用for循环写了几个延时的子程序贴上来,希望能对初学者有所帮助.(晶振12 MHz,一个机器周期1us.) 一. 500ms延时子程序程序: void delay500ms(void) { unsigned char i,j,k; for(i=15;i>0;i--) for(j=202;j>0; j--) for(k=81;k>0;k--); } 产生的汇编: C:0x0800 7F0F MOV R7,#0x0F C:0x0802 7ECA MOV R6,#0xCA C:0x0804 7D51 MOV R5,#0x51 C:0x0806 DDFE DJNZ R5,C:0806 C:0x0808 DEFA DJNZ R6,C:0804 C:0x080A DFF6 DJNZ R7,C:0802 C:0x080C 22 RET 计算分析: 程序共有三层循环一层循环n:R5*2 = 81*2 = 162us DJNZ 2us 二层循环m: R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us 三层循环: R7*(m +3) = 15*33333 = 499995us DJNZ 2us + R6赋值1us = 3us 循环外: 5us 子程序调用2us + 子程序返回2us + R7赋值1us = 5us 延时总时间= 三层循环+ 循环外= 499995+5 = 500000us =500ms 计算公式:延时时间= [(2*R5+3)*R6+3]*R7+5 二. 200ms延时子程序程序: void delay200ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=132;j>0;j--) for(k=150;k>0;k--); } 产生的汇编

51单片机延时时间计算和延时程序设计

一、关于单片机周期的几个概念 时钟周期 时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12MHz 的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。 在一个时钟周期内,CPU仅完成一个最基本的动作。 机器周期 完成一个基本操作所需要的时间称为机器周期。 以51 为例,晶振12M,时钟周期(晶振周期)就是(1/12) μs,一个机器周期包 含12 个时钟周期,一个机器周期就是1μ s。 指令周期: 执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需 的机器周期也不同。 对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。 2.延时常用指令的机器周期 1.指令含义 DJNZ:减 1 条件转移指令这是一组把减 1 与条件转移两种功能结合在一起的指令,共2条。DJNZ Rn,rel ;Rn←(Rn)-1 ;若(Rn)=0,则PC←(PC)+2 ;顺序执行; 若(Rn)≠ 0,则PC←(PC)+2+rel,转移到rel 所在位置 DJNZ direct,rel ;direct ←(direct )-1 ;若(direct)= 0,则PC←(PC)+3;顺序执行;若(direct)≠ 0,则PC←(PC)+3+rel,转移到rel 所

在位置 2.DJNZ Rn,rel 指令详解例:

MOV R7,#5 DEL:DJNZ R7,DEL; r在el本例中指标号DEL 三、51 单片机延时时间的计算方法和延时程序设计 1.单层循环 由上例可知,当Rn赋值为几,循环就执行几次,上例执行 5 次,因此本例执行的机器周期个数=1(MOV R7,#5)+2(DJNZ R7,DE)L ×5=11,以12MHz的晶振为例,执行时间(延时时间)=机器周期个数×1μs=11μ s,当设定立即数为0 时,循环程序最多执行256 次,即延时时间最多256μ s。 2.双层循环 1)格式: DELL:MOV R,7 #bb DELL1:MOV R6,#aa DELL2:DJNZ R6,DELL2; 在rel本句中指标号DELL2 DJNZ R7,DELL1; re在l 本句中指标号DELL1 注意:循环的格式,写错很容易变成死循环,格式中的Rn 和标号可随意指定。 2)执行过程

汇编延时程序讲解

延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器 周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指 令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者 我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如 在交通灯的控制程序中,需要控制红灯亮的时间持续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) 了解了以上的内容,现在让我们来看看

实验三 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)

单片机延时程序分析#(优选.)

上一次课中,我们已经知道,程序中的符号R7、R6是代表了一个个的RAM单元,是用来放一些数据的,下面我们再来看一下其它符号的含义。 DELAY:MOV R7,#250;(6) D1:MOV R6,#250 ;(7) D2:DJNZ R6,D2 ;(8) DJNZ R7,D1;(9) RET ;(10) 〈单片机延时程序〉 MOV:这是一条指令,意思是传递数据。说到传递,我们都很清楚,传东西要从一本人的手上传到另一本人的手上,也就是说要有一个接受者,一个传递者和一样东西。从指令M OV R7,#250中来分析,R7是一个接受者,250是被传递的数,传递者在这条指令中被省略了(注意:并不是每一条传递指令都会省的,事实上大部份数据传递指令都会有传递者)。它的意义也很明显:将数据250送到R7中去,因此执行完这条指令后,R7单元中的值就应当是250。在250前面有个#号,这又是什么意思呢?这个#就是用来说明250就是一个被传递的东西本身,而不是传递者。那么MOV R6,#250是什么意思,应当不用分析了吧。 DJNZ:这是另一条指令,我们来看一下这条指令后面跟着的两个东西,一个是R6,一个是D2,R6我们当然已知是什么了,查一下D2是什么。D2在本行的前面,我们已学过,这称之为标号。标号的用途是什么呢?就是给本行起一个名字。DJNZ指令的执行过程是这样的,它将其后面的第一个参数中的值减1,然后看一下,这个值是否等于0,如果等于0,就往下执行,如果不等于0,就转移,转到什么地方去呢?可能大家已猜到了,转到第二个参数所指定的地方去(请大家用自已的话讲一下这条语句是怎样执行的)。本条指令的最终执行结果就是,在原地转圈250次。

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

课程设计任务书 学生姓名专业班级 指导教师黄珍工作单位自动化学院 课程设计题目七段码显示汇编语言程序设计 初始条件: 采用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)

单片机延时程序

实验一单片机延时程序实验 一、实验目的与要求: 在使用4MH在外部晶体振荡器的PIC16F877A上用软件设计一个20ms的软件延时子程序。另外,还要求用MPLAB的软件模拟器及其附带的软件工具窗口stopwatch观测延时程序执行的时间。 二、实验内容: 1.硬件电路设计: 本实验中用的是软件延时,利用循环来实现延时功能。电路就用了单片机的原本电路。没有用到其他的功能模块,单片机与ICD3相连接。 2.软件设计思路: 单片机软件延时的前提和基础是每条指令的执行时间是固定的,且大部分指令的执行时间是相同的。这要求对每条指令所花费的指令周期(Tcy)做到心中有数。指令集中5条无条件跳转指令GOTO,CALL.RETURN,RETLW和RETFIE,由于它们必然引起程序跳转,造成流水线中断,因此肯定将占用2个指令周期。而其他4条有可能引起程序跳转的条件跳转指令DECFSZ,INCFSZ,BTFSC和,BTFSS的执行时间,需要占用2个指令周期,当条件为假不发生跳转时,仅占用1个指令周期。其余所有指令都只用1个指令周期。

每个指令周期Tcy的时间长度,计算方法:如果采用4MHz 的外部晶体(fosc=4 MHz),则PIC中档单片机的指令周期Tcy 为1us,这是一个整数。而采用其他频率的外部晶体时,指令周期时间将反比于外部晶体频率。 至于软件延时的结构和实现方法,其实可以采用任何指令和结构,因为只是通过执行指令耗费时间。但通常情况下有两个选择延时程序结构的原则: (1)执行指令周期数计算方便。如果含有太多复杂的条件跳转循环等结构势必会造成指令周期的计算困难,甚至可 能造成执行所造成的软件延时时间不等。 (2)不能占用太多的程序空间。试想用20000个NOP指令来实现20ms的延时,显然是可以的,但是这样做浪费了 整整一个页的程序存储器,得不偿失,而通过适当的循 环结构,重复执行某些相同的程序是比较合理的方法。 因此,软件延时程序一般采用下列方法:如果延时时间 短(微妙级别),可以连续插入几条NOP指令;如果延 时时间长(几个毫秒级别),则可以使用双嵌套循环的 方法来实现。 实验的流程图:

延时子程序

汇编延时程序大集合 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;

相关主题