延时子程序计算方法
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口和定时器实验)

实验三流水灯实验(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程序设计中几种精确延时方法摘要实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多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口输入、输出实验一、实验要求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单片机延时函数

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如果用高级语言编程,只需要简单地调用延时函数就可以实现,但是计算机具体是怎么实现的呢?要想知其所以然,还得从汇编开始学起。
冒号前面的“DELAY”、“D1”、“D2”为语句行的名字,是为了程序的条件语句跳转用的,分号后面为注释,计算机执行时将过滤掉这些信息,最大限度减少代码长度,提高效率。
DELAY: MOV R7,#250 ;名字为“DELAY”的语句:意思是将CPU内部内存RAM的R7位置填写为250(原来为0,为什么是0呢?因为任何程序开始执行前都要复位,就像我们打算盘要将算子复位一样,或者我们用沙盘写字,要将沙盘抹平类似)D1: MOV R6,#250 ;名字为“D1”的语句:将R6位置填写为250D2: DJNZ R6,D2 ;名字为“D2”的语句:将R6位置的250减1,如果为0就继续执行下一条,不为0就继续执行D2这一句,因为R6=250,所以这个语句要原地踏步执行250次!DJNZ R7,D1 ;这句没有名字,因为没有别的语句要跳到这里,所以就省略了。
R7同样等于250,但它不是原地踏步,而是跳回了D1,这么干,D!、D2和本句将被循环执行250遍,需要强调的是:D2语句自身每次都要执行250遍,也就是执行了250*250=62500遍!RET ;子程序结束(因为延时程序一般不作为独立程序存在,它只是一个子程序,也就是高级语言中的一个函数,看到这个字符,子程序将跳回到母程序,进行下一步)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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++;
}
}。