比较精确的延时小程序

比较精确的延时小程序
比较精确的延时小程序

#ifndef _DELAY_H

#define _DELAY_H

// mcu:avr crystal=8MHz 适用于A VR Mega系列单片机

// 该头文件中延时1us,10us,50us,1ms,5ms四个子程序已经A VRstudio4.16验证,是包含调用时间在内的很精确的延时

void Delay_1us(void);

void Delay_10us(void);

void Delay_50us(void);

void Delay_1ms(void);

void Delay_5ms(void);

void Delay_Ms(unsigned int xms);

void Delay10us(unsigned int x10us);

void Delay_1us(void)

{

NOP();

}

void Delay_10us(void)

{

unsigned char i;

for(i=0;i<17;i++);

}

void Delay_50us(void)

{

unsigned char i;

for(i=0;i<97;i++);

}

void Delay_1ms(void)

{

unsigned int i;

for(i=0;i<988;i++); //1141

}

void Delay_5ms(void)

{

unsigned int i;

for(i=0; i<2177;i++)

{

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

}

}

void Delay_Ms(unsigned int xms) //crystal=8MHz {

unsigned int i,j; //variable:declare Word

for(i=0; i

for(j=0; j<498;j++)

{

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

NOP();

}

}

#endif

单片机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--); }

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

便于初学者,较为精确的延时程序 ;***************************************************************** ;延时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

延时子程序计算方法

学习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="<

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;

单片机延时计算

单片机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;

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/1815251471.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))

单片机延时计算

单片机延时计算 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个机器周期的执行时间。

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_( );

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)执行过程

用汇编语言编写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)

相关文档
最新文档