延时子程序计算方法

合集下载

HT单片机延时子程序设计

HT单片机延时子程序设计

HT单片机延时子程序设计单片机延时子程序设计是一种常用的程序设计技术,可以通过编程实现对系统的延时控制,实现各种功能需求。

一、延时原理在单片机中,延时的实现原理主要是基于时钟脉冲的计数器计时。

单片机的时钟频率是固定的,通常为一个定值,通过控制时钟脉冲的频率,我们可以实现不同的延时功能。

二、延时程序设计延时子程序设计通常分为两种情况:固定延时和可调延时。

下面我们将分别介绍这两种情况的延时程序设计。

1.固定延时固定延时是指延时时间是固定不变的,不受外部条件的影响。

为了实现固定延时,可以通过编程设置一个计时器,每次进行固定次数的循环,从而达到延时的目的。

下面是一个实现固定延时的示例代码:```unsigned int i, j;// do nothing, just wait}}```2.可调延时可调延时是指延时时间可以根据需要进行调整的情况。

为了实现可调延时,可以利用系统的定时器模块,设置一个定时器中断,在定时器中断服务子程序中进行延时控制。

下面是一个实现可调延时的示例代码:```#include <8051.h>#define TIMER0_H_BYTE (*((unsigned char volatile xdata *)0xFFC0))#define TIMER0_L_BYTE (*((unsigned char volatile xdata *)0xFFC1))}EA = 1; // enable interruptTH0=TIMER0_H_BYTE=0xFF;TL0=TIMER0_L_BYTE=0xFF;// do nothing, just wait for interrupt}EA = 0; // disable interrupt```在上面的例子中,通过设置定时器0的定时时间为50us,然后将延时时间转换为中断次数进行控制。

通过改变调用delay_adjustable函数时设置的延时时间,可以实现可调延时功能。

实验三流水灯实验(io口和定时器实验)

实验三流水灯实验(io口和定时器实验)

实验三流水灯实验(I/O口和定时器实验)一、实验目的1.学会单片机I/O口的使用方法和定时器的使用方法;2.掌握延时子程序的编程方法、内部中断服务子程序的编程方法;3.学会使用I/O口控制LED灯的应用程序设计。

二、实验内容1.控制单片机P1口输出,使LED1~LED8右循环轮流点亮(即右流水),间隔时间为100毫秒。

2.控制单片机P1口输出,使LED1~LED8左循环轮流点亮(即左流水),间隔时间为100毫秒。

3.使用K1开关控制上面LED灯的两种循环状态交替进行;4. 用定时器使P1口输出周期为100ms的方波,使LED闪烁。

5.使用定时器定时,使LED灯的两种循环状态自动交替,每一种状态持续1.6秒钟(选作)。

三、实验方法和步骤1.硬件电路设计使用实验仪上的E1、E5和E7模块电路,把E1区的JP1(单片机的P1口)和E5区的8针接口L1~L8(LED的驱动芯片74HC245的输入端)连接起来,P1口就可以控制LED 灯了。

当P1口上输出低电平“0”时,LED灯亮,反之,LED灯灭。

E7区的K1开关可以接单片机P3.0口,用P3.0口读取K1开关的控制信号,根据K1开关的状态(置“1”还是置“0”),来决定LED进行左流水还是右流水。

综上,画出实验电路原理图。

2.程序设计实验1和实验2程序流程图如图3-1实验3程序流程图如图3-2所示。

图3-1 实验1,2程序流程图图3-2 实验3程序流程图实验4程序流程图如图3-3,3-4所示。

实验5程序流程图如图3-5,3-6所示。

图3-5 实验5主程序流程图图3-6 定时器中断服务子程序流程图图3-4 定时器中断服务子程序流程图图3-3 实验4主程序流程图编程要点:(1)Pl,P3口为准双向口,每一位都可独立地定义为输入或输出,在作输入线使用前,必须向锁存器相应位写入“1”,该位才能作为输入。

例如:MOV P1,A; P1口做输出MOV P1,#0FFHMOV A,P1;P1口做输入SETB P3.0MOV C,P3.1;从P3.1口读入数据(2)每个端口对应着一个寄存器,例:P1→90H(P1寄存器地址);P3→B0H(P3寄存器地址);寄存器的每一位对应着一个引脚,例:B0H.0→P3.0(3)对寄存器写入“0”、“1”,对应的外部引脚则输出“低电平”、“高电平”。

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

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

Keil C51程序设计中几种精确延时方法摘要实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。

本文从实际应用出发,讨论几种实用的编制精确延时程序和计算程序执行时间的方法,并给出各种方法使用的详细步骤,以便读者能够很好地掌握理解。

关键词Keil C51 精确延时程序执行时间引言单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域[1]。

单片机开发者在编制各种应用程序时经常会遇到实现精确延时的问题,比如按键去抖、数据传输等操作都要在程序中插入一段或几段延时,时间从几十微秒到几秒。

有时还要求有很高的精度,如使用单总线芯片DS18B20时,允许误差范围在十几微秒以内[2],否则,芯片无法工作。

用51汇编语言写程序时,这种问题很容易得到解决,而目前开发嵌入式系统软件的主流工具为C语言,用C51写延时程序时需要一些技巧[3]。

因此,在多年单片机开发经验的基础上,介绍几种实用的编制精确延时程序和计算程序执行时间的方法。

实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。

1 使用定时器/计数器实现精确延时单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。

第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。

本程序中假设使用频率为12 MHz的晶振。

最长的延时时间可达216=65 536 μs。

若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。

在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。

单片机课程实验报告-延时子程序

单片机课程实验报告-延时子程序

单片机实验报告实验报告单片机实验报告一、实验目的:学习P1口的使用方法,学习延时子程序的编写二、实验要求:以P1口作为输出口,控制6个发光二极管,模拟交通信号灯的管理。

在实验仪上选择两组红、黄、绿指示灯,代表交通信号灯。

设有一个十字路口为东西南北方向,其中东西方向为支路,南北方向为主路。

初始状态为4个路口的红灯全亮。

之后,南北路口的绿灯亮,东西路口的红灯亮。

南北路口方向通车,延时20秒后,南北路口绿灯熄灭,黄灯开始闪烁,闪烁5次后红灯亮。

而同时东西方向路口的绿灯亮,东西方向开始通车,延时10秒后,东西路口的绿灯熄灭,而黄灯开始闪烁。

闪烁5次后,在切换到南北路口的绿灯亮,东西路口的红灯亮。

之后重复上述过程。

三、实验电路:四、程序框图:五、程序清单:ORG 4000H ;定义程序存放区域的起始地址START: CLR P1.0 ;红灯亮LOOP: SETB P1.1SETB P1.2CLR P1.5SETB P1.6SETB P1.7ACALL DELAYSSETB P1.0 ;南北绿灯亮,东西红灯亮CLR P1.2ACALL DELAYL2 ;长延时20sMOV R3,#5 ;南北黄灯闪烁5次,东西红灯亮YELLOW1: ;南北黄灯亮,东西红灯亮CLR P1.1SETB P1.2ACALL DELAYS ;短延时;南北黄灯灭,东西红灯亮SETB P1.1ACALL DELAYS ;短延时DJNZ R3,YELLOW1;南北红灯亮,东西绿灯亮CLR P1.0SETB P1.5CLR P1.7ACALL DELAYL1 ;长延时10sMOV R3,#5 ;南北红灯亮,东西黄灯闪烁五次YELLOW2:CLR P1.6 ;东西黄灯亮SETB P1.7ACALL DELAYS ;短延时SETB P1.6 ;南北红灯灭,东西黄灯亮ACALL DELAYS ;短延时DJNZ R3,YELLOW2AJMP LOOP ;循环DELAYL2:MOV R4,#200 ;长延迟20sDELAY1: MOV R5,#200DELAY2: MOV R6,#250DELAY3: DJNZ R6,DELAY3DJNZ R5,DELAY2DJNZ R4,DELAY1RETDELAYS: MOV R4,#10 ;短延迟1sDELAY4: MOV R5,#200DELAY5: MOV R6,#250DELAY6: DJNZ R6,DELAY6DJNZ R5,DELAY5DJNZ R4,DELAY4RETDELAYL1:MOV R4,#100 ;长延迟10sDELAY7: MOV R5,#200DELAY8: MOV R6,#250DELAY9: DJNZ R6,DELAY9DJNZ R5,DELAY8DJNZ R4,DELAY7六、LST文件A51 MACRO ASSEMBLER LED04/21/2010 16:50:30 PAGE 1MACRO ASSEMBLER A51 V7.01OBJECT MODULE PLACED IN LED.OBJASSEMBLER INVOKED BY: C:\Keil\C51\BIN\A51.EXE LED.asm SET(SMALL) DEBUG EPLOC OBJ LINE SOURCE0000 1 ORG 0000H230000 7590DE 4 START: MOV P1,#11011110B0003 1155 5 CALL DALY1 ;0.5S0005 7590DB 6 MOV P1,#11011011B0008 1133 7 CALL DALY ;20S000A 7805 8 MOV R0,#5H000C 74DD 9 LOOP1: MOV A,#11011101B000E F590 10 MOV P1,A0010 1155 11 CALL DALY1 ;0.-5S0012 74DF 12 MOV A,#11011111B0014 F590 13 MOV P1,A0016 1155 14 CALL DALY10018 D8F2 15 DJNZ R0,LOOP1001A 747E 16 MOV A,#01111110B001C F590 17 MOV P1,A001E 1144 18 CALL DALY2 ;10S0020 7805 19 MOV R0,#5H0022 74BE 20 LOOP2: MOV A,#10111110B0024 F590 21 MOV P1,A0026 1155 22 CALL DALY10028 74FE 23 MOV A,#11111110B002A F590 24 MOV P1,A002C 1155 25 CALL DALY1002E D8F2 26 DJNZ R0,LOOP20030 020000 27 LJMP START2829 ;20S0033 7C64 30 DALY:MOV R4,#1000035 7B64 31 DELAY1:MOV R3,#1000037 7A14 32 DELAY2:MOV R2,#200039 792D 33 DELAY3:MOV R1,#45003B D9FE 34 DELAY4:DJNZ R1,DELAY4003D DAFA 35 DJNZ R2,DELAY3003F DBF6 36 DJNZ R3,DELAY20041 DCF2 37 DJNZ R4,DELAY10043 22 38 RET3940 ;10S0044 7C64 41 DALY2:MOV R4,#1000046 7B64 42 DEAY1:MOV R3,#1000048 7A0A 43 DEAY2:MOV R2,#10004A 792D 44 DEAY3:MOV R1,#45004C D9FE 45 DEAY4:DJNZ R1,DEAY4004E DAFA 46 DJNZ R2,DEAY30050 DBF6 47 DJNZ R3,DEAY20052 DCF2 48 DJNZ R4,DEAY10054 22 49 RET5051 ;0.5S0055 7C64 52 DALY1:MOV R4,#1000057 7B64 53 DEY1:MOV R3,#1000059 7A19 54 DEY2:MOV R2,#25005B DAFE 55 DEY3: DJNZ R2,DEY3005D DBFA 56 DJNZ R3,DEY2005F DCF6 57 DJNZ R4,DEY10061 22 58 RETA51 MACRO ASSEMBLER LED 04/22/2010 16:20:30 PAGE 25960 ENDA51 MACRO ASSEMBLER LED 04/21/2010 16:50:30 PAGE 3SYMBOL TABLE LISTING------ ----- -------N A M E T Y P E V A L U E ATTRIBUTESDALY . . . . . . . C ADDR 0033H ADALY1. . . . . . . C ADDR 0055H ADALY2. . . . . . . C ADDR 0044H ADEAY1. . . . . . . C ADDR 0046H ADEAY2. . . . . . . C ADDR 0048H ADEAY3. . . . . . . C ADDR 004AH ADEAY4. . . . . . . C ADDR 004CH ADELAY1 . . . . . . C ADDR 0035H ADELAY2 . . . . . . C ADDR 0037H ADELAY3 . . . . . . C ADDR 0039H ADELAY4 . . . . . . C ADDR 003BH ADEY1 . . . . . . . C ADDR 0057H ADEY2 . . . . . . . C ADDR 0059H ADEY3 . . . . . . . C ADDR 005BH ALOOP1. . . . . . . C ADDR 000CH ALOOP2. . . . . . . C ADDR 0022H AP1 . . . . . . . . D ADDR 0090H ASTART. . . . . . . C ADDR 0000H AREGISTER BANK(S) USED: 0ASSEMBLY COMPLETE. 0 WARNING(S), 0 ERROR(S) 七、实验步骤:(1)根据书中设计流程图编写源程序(见实验程序)(2)用keil软件仿真:(3)更改参数:(4)下载:1.正确连接实验仪与主机的RS-232通信电缆和电源2.把实验仪的工作模式选择开关切换到LOAD处,复位系统使实验仪工作于下载状态3.运行DPFlash下载软件4.把实验仪的工作模式选择开关切换到RUN处,复位系统使实验仪工作观察发光二极管的运行情况。

P1口输入、输出实验

P1口输入、输出实验

实验一 P1口输入、输出实验一、实验要求1. P1口做输出口,接八只发光二极管,编写程序,使发光二极管循环点亮。

2. P1.0、P1.1作输入口接两个拨动开关,P1.2、P1.3作输出口,接两个发光二极管,编写程序读取开关状态,将此状态,在发光二极管上显示出来。

编程时应注意P1.0、P1.1作为输入口时应先置1,才能正确读入值。

二、实验目的1. 学习P1口的使用方法。

2. 学习延时子程序的编写和使用。

三、实验连线实验1: P1口循环点亮 实验2: P1口输入输出四、实验说明1. 8051延时子程序的计算延时程序的实现常用两种方法,一种用定时器中断来实现,另一种是用指令循环实现。

在系统时间允许的情况下可以采用后一种方法。

本实验系统晶振频率为6MHz ,执行一个机器周期时间为12/6MHZ=2µS,现在写一个延时0.1S 的程序如下:查指令表可知MOV 需要一个机器周期,DJNZ 指令需用两个机器周期,所以执行该段程序所需时间是:[ 1 + ( 1 + 2 × 200 + 2 ) X ] × 2×10-6= 0.1S 指令(1) (2) (3) (4) 所需时间 所需时间 所需时间 所需时间求出X =124,将X =124代入上式可知实际延时约0.099946≈0.1S 。

2. P1口准双向口它作为输出口时与一般的双向口使用方法相同。

由准双向口结构可知当P1口用为Delay :MOV R6,#X (1) DE1: MOV R7, #200 (2) DE2: DJNZ R7,DE2 (3)DJNZ R6,DE1 (4)输入口时,必须先对它置“1”。

若不先对它置“1”,读入的数据是不正确的。

六、硬件电路1、LED电平显示电路图1:LED电平显示电路2、逻辑电平开关电路实验仪上有8只开关K0―K7,并有与之相对应的K0―K7引线孔为逻辑电平输出端。

开关向上拨相应插孔输出高电平“1”,向下拨相应插孔输出低电平“0”。

51单片机延时函数

51单片机延时函数

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 DJNZ2us + 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延时子程序程序:{unsigned char i,j,k;for(i=5;i>0;i--)for(j=132;j>0;j --)for(k=150;k>0;k --);}三. 10ms延时子程序程序:{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语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。

单片机的延时计算

单片机的延时计算
译器用下面的指令组合来完成的
MOVR7,#0FFH
LOOP2:MOVR6,#0FFH
LOOP1:DJNZR6,LOOP1
DJNZR7,LOOP2
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初
值为m,变量j的初值为n,则总延时时间为:m×(n×T+T),
{unsigned char b,c;
b="j";
c="k";
do{
do{
do{k--};
while(k);
k="c";
j--;};
while(j);
j=b;
i--;};
while(i);
}
这精确延时子程序就被C51编译为有下面的指令组合完成
delay延时子程序如下:
MOV R6,05H
MOV R4,03H
一. 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
刚刚又学了一条,用_nop_();时记得加上#include <intrins.h>头文件
如:
//==================
#include <intrins.h> //包含库函数

单片机汇编延时程序的理解

单片机汇编延时程序的理解

单片机汇编延时程序的理解单片机汇编实现延迟的程序代码:DELAY: MOV R7,#250 ;D1: MOV R6,#250 ;D2: DJNZ R6,D2 ;DJNZ R7,D1 ;RET如果用高级语言编程,只需要简单地调用延时函数就可以实现,但是计算机具体是怎么实现的呢?要想知其所以然,还得从汇编开始学起。

冒号前面的&ldquo;DELAY&rdquo;、&ldquo;D1&rdquo;、&ldquo;D2&rdquo;为语句行的名字,是为了程序的条件语句跳转用的,分号后面为注释,计算机执行时将过滤掉这些信息,最大限度减少代码长度,提高效率。

DELAY: MOV R7,#250 ;名字为&ldquo;DELAY&rdquo;的语句:意思是将CPU内部内存RAM的R7位置填写为250(原来为0,为什么是0呢?因为任何程序开始执行前都要复位,就像我们打算盘要将算子复位一样,或者我们用沙盘写字,要将沙盘抹平类似)D1: MOV R6,#250 ;名字为&ldquo;D1&rdquo;的语句:将R6位置填写为250D2: DJNZ R6,D2 ;名字为&ldquo;D2&rdquo;的语句:将R6位置的250减1,如果为0就继续执行下一条,不为0就继续执行D2这一句,因为R6=250,所以这个语句要原地踏步执行250次!DJNZ R7,D1 ;这句没有名字,因为没有别的语句要跳到这里,所以就省略了。

R7同样等于250,但它不是原地踏步,而是跳回了D1,这么干,D!、D2和本句将被循环执行250遍,需要强调的是:D2语句自身每次都要执行250遍,也就是执行了250*250=62500遍!RET ;子程序结束(因为延时程序一般不作为独立程序存在,它只是一个子程序,也就是高级语言中的一个函数,看到这个字符,子程序将跳回到母程序,进行下一步)。

延时子程序计算方法

延时子程序计算方法

学习MCS-51单片机,如果用软件延时实现时钟,会接触到如下形式的延时子程序:delay:mov R5,#data1d1:mov R6,#data2d2:mov R7,#data3d3:djnz R7,d3djnz R6,d2djnz R5,d1Ret其精确延时时间公式: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,999e=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,#167d1:mov R6,#171d2:mov R7,#16d3:djnz R7,d3djnz R6,d2djnz R5,d1nop ;注意不要遗漏这一句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="<<e<<" "<<"R5="<<a<<" "<<"R6="<<b<<" "<<"R7="<<c<<""<<"f="<<f<<endl<<endl;};if(d==1){e=d;a=x;b=y;c=z;g++;cout<<"e="<<e<<" "<<"R5="<<a<<" "<<"R6="<<b<<" "<<"R7="<<c<<" "<<"g="<<g<<endl<<endl;};x++;}x=1;y++;}y=1;z++;}}。

HT单片机延时子程序设计

HT单片机延时子程序设计

HT单片机延时子程序设计
(一)概述
延时指的是控制系统中,在触发开关发出开关信号之后,时间处于一定的状态之前,系统处于延时期,这段时间内不进行任何有效的操作。

延时编程是单片机应用程序的常用编程,它可以根据用户的需求在一定时间段内控制系统的动作。

AVR单片机定时器硬件的可编程功能可以满足用户的大多数延时要求,但是有时需要用户自己编写延时程序。

延时子程序的设计,结合ATmega 128单片机定时器的主要寄存器和定时/计数功能,以及定时/计数具体原理,提出了一种延时子程序设计的思路。

1、延时子程序的思路
延时子程序的思路是在确定定时/计数功能的基础上,利用单片机的定时器功能,通过计算预设时间内的CPU循环次数来实现延时操作。

具体步骤如下:
(1)定义延时时间t;
(2)使用定时/计数功能来实现定时/计数;
(3)计算CPU需要循环的次数;
(4)根据CPU循环的次数,写出延时子程序;
(5)通过程序运行来调试延时子程序,实现延时操作。

2、延时子程序的具体设计
延时子程序的设计基于ATmega 128单片机定时器0的特性,主要参考以下指标:
(1)主频:16MHz;。

单片机延时子程序

单片机延时子程序

单片机延时子程序单片机延时是指在程序运行过程中,程序须要暂停一段时间,以便执行下一个任务。

延时所耗费的时间必须是可靠的,否则将导致程序运行出错。

单片机延时分为软件延时和硬件延时两种,其中软件延时是指在程序运行过程中使用延时程序实现延时,而硬件延时则是利用定时器等硬件设备来实现延时。

软件延时子程序是指在程序中使用循环语句实现延迟。

程序中使用循环语句,通过循环次数来控制延迟时间,这种延迟实现方法简单易用,但由于循环次数的不同,延迟时间精度也难以保证。

下面介绍一种常用的软件延时子程序,可以实现毫秒级的精度。

软件延时子程序的实现方法软件延时子程序是利用单片机内部的计时器来实现延时,计时器的计数值越大,延时的时间越长。

方法如下:(1)首先,需要定义计时器要计数的时钟周期。

(2)然后,选定一个比较合适的计数次数。

(3)计算出计数器的计数值。

(4)在程序中使用循环语句来实现延时。

;-----------------------------------------;软件延迟程序;入口:X--DelayCnt(需要延时时间);出口:none;-----------------------------------------Delay1ms: mov R2,#13 ;初始化计数值Delay_Loop1: mov R1,#32 ;初始化计数值Delay_Loop2: djnz R1,$ ;32次循环耗费 4.56usdjnz R2,Delay_Loop2djnz R0,Delay_Loop1ret ;延时结束,退出;-----------------------------------------该代码在STC89C52单片机上进行实验,延迟时间为1毫秒,计数值为13。

代码中使用两个循环语句,根据计数值进行循环次数限制,循环次数越多,延时时间越长。

由于不同单片机的晶振频率不同,计算计数值时需要考虑晶振频率。

例如,若晶振频率为11.0592MHz,则计数值应为153。

汇编延时1s的延时子程序

汇编延时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:延时结束,返回。

单片机延时子程序

单片机延时子程序

精确延时计算公式:延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+5;延时5秒左右DELAY5S:PUSH 04H;2个机器周期PUSH 05H;2个机器周期PUSH 06H;2个机器周期MOV R4,#50;1个机器周期DELAY5S_0:MOV R5,#200;1个机器周期DELAY5S_1:MOV R6,#245;1个机器周期DJNZ R6,$;2×245=490个机器周期DJNZ R5,DELAY5S_1;这条2个机器周期,这层循环包含R5×(490+1)+2×R5=98600个机器周期DJNZ R4,DELAY5S_0;这条2个机器周期,这层循环包含R4×(98600+1)+2×R4=4930150个机器周期POP 06H;2个机器周期POP 05H;2个机器周期POP 04H;2个机器周期RET;2个机器周期;(共2+2+2+1+4930150+2+2+2+2=4930165个机器周期);513微秒延时程序DELAY: MOV R2,#0FEH;1个机器周期JUZINAIYOU: DJNZ R2,JUZINAIYOU;2×R21即2×245RET;2个机器周期;(实际上是493个机器周期);10毫秒延时程序DL10MS: MOV R3,#14HDL10MS1:LCALL DELAYDJNZ R3,DL10MS1RET;(缺DELAY);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+5 DEL : 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秒=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: ;500MS 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=2390 MOV R0,#244 ;1DELAY24001:MUL AB ;4MUL AB ;4DJNZ R0,DELAY24001 ;2RETDELAY: ;延时子程序(1秒)MOV R0,#0AHDELAY1: MOV R1,#00HJUZINAIYOU: MOV R2,#0B2HDJNZ R2,$DJNZ R1,JUZINAIYOUDJNZ R0,DELAY1RETMOV R2,#10 ;延时1秒LCALL DELAYMOV R2,#50 ;延时5秒LCALL DELAYDELAY: ;延时子程序PUSH R2PUSH R1PUSH R0DELAY1: MOV R1,#00HJUZINAIYOU: MOV R0,#0B2HDJNZ R0,$DJNZ R1,JUZINAIYOU ;延时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, #50HCLR EAMOV TMOD, #01HMOV TH0,#3CHMOV TL0,#0B0HMOV R4, #10SETB ET0SETB EASETB TR0SJMP $ ;CTC0: MOV TH0, #3CHMOV TL0, #0B0HDJNZ R4, LPCPL P1.0MOV R4, #10LP: RETIEND; 定时器中断延时TMOD=0x01; /*定时器0工作在模式1下(16位计数器)*/TH0=0xfd;TL0=0x83;TR0=1; /*启动定时器*/TF0==0;TR0=0;等待中断;100ms定时,11.0592晶振他定时准确啊又不影响程序运行2008-06-10 13:50:46 来源:来于网络,服务大家作者:未知【大中小】点击:9 次下面几个是单片机的延时程序(包括asm和C程序,都是我在学单片机的过程中用到的),在单片机延时程序中应考虑所使用的晶振的频率,在51系列的单片机中我们常用的是11.0592MHz和12.0000MHz的晶振,而在A VR单片机上常用的有8.000MHz和4.000MH的晶振所以在网上查找程序时如果涉及到精确延时则应该注意晶振的频率是多大。

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

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

延时子程序的延时计算问题
对于程序 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语言延时计算

C语言延时计算

我现在就用两种方法来实现,一种是while()语句,另一种是for()语句,这两种语句均可产生汇编语句中的DJNZ语句,以12MHZ晶振为例(说明:在编写C程序时,变量尽量使用unsigned char,如满足不了才使用unsigned int):1.delay=99;while(--delay);000FH MOV 08H,#63H0012H DJNZ 08H,0012H这样产生的延时时间为:(99+1)×2us。

最小延时时间为2us,若加上对delay赋值语句,则最小为4us。

2.for(i=delay;i>0;i--);产生的汇编代码同while()语句。

下面来举例几个延时函数:一. 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,#0x0FC:0x0802 7ECA MOV R6,#0xCAC:0x0804 7D51 MOV R5,#0x51C:0x0806 DDFE DJNZ R5,C:0806C:0x0808 DEFA DJNZ R6,C:0804C:0x080A DFF6 DJNZ R7,C:0802C: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--); }三. 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--); }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学习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="<<e<<" "<<"R5="<<a<<" "<<"R6="<<b<<" "<<"R7="<<c<<"
"<<"f="<<f<<endl<<endl;
};
if(d==1)
{
e=d;a=x;b=y;c=z;
g++;
cout<<"e="<<e<<" "<<"R5="<<a<<" "<<"R6="<<b<<" "<<"R7="<<c<<" "<<"g="<<g<<endl<<endl;
};
x++;
}
x=1;y++;
}
y=1;z++;
}
}。

相关文档
最新文档