delay延时教程
51单片机delay()延时的用途和用法讲解

{ unsigned int i; for(i=0;i<uiDelayShort;i++) { ; //一个分号相当于执行一条空语句 }
}
/* 注释八: * delay_long(unsigned int uiDelayLong)是大延时函数, * 专门用在上电初始化的大延时, * 此函数的特点是能实现比较长时间的延时,细分度取决于内嵌 for 循环的次数, * uiDelayLong 的数值的大小就代表里面执行了多少次 500 条空指令的时间。 * 数值越大,延时越长。时间精度不要刻意去计算,感觉差不多就行。 */ void delay_long(unsigned int uiDelayLong) {
unsigned int i; unsigned int j; for(i=0;i<uiDelayLong;i++) {
for(j=0;j<500;j++) //内嵌循环的空指令数量 { ; //一个分号相当于执行一条空语句 }
}பைடு நூலகம்}
void initial_myself() //初始化单片机 {
led_dr=0; //LED 灭 } void initial_peripheral() //初始化外围 {
delay()延时的用途讲解
(1)硬件平台:基于朱兆祺 51 单片机学习板。
(2)实现功能:让一个 LED 闪烁。
(3)源代码讲解如下:
#include "REG52.H"
void initial_myself(); void initial_peripheral();
void delay_short(unsigned int uiDelayshort); void delay_long(unsigned int uiDelaylong); void led_flicker();
c语言delay的用法

c语言delay的用法在单片机应用中,经常会遇到需要短时间延时的情况,一般都是几十到几百μs,并且需要很高的精度(比如用单片机驱动DS18B20时,误差容许的范围在十几μs以内,不然很容易出错);而某些情况下延时时间较长,用计时器往往有点小题大做。
另外在特殊情况下,计时器甚至已经全部用于其他方面的定时处理,此时就只能使用软件定时了。
下面小编就和大家分享下c语言delay的用法1 C语言程序延时Keil C51的编程语言常用的有2种:一种是汇编语言;另一种是C 语言。
用汇编语言写单片机程序时,精确时间延时是相对容易解决的。
比如,用的是晶振频率为12 MHz的AT89C51,打算延时20 μs,51单片机的指令周期是晶振频率的1/12,即一个机器周期为1 μs;“MOV R0,#X”需要2个机器周期,DJNZ也需要2个机器周期,单循环延时时间t=2X+3(X为装入寄存器R0的时间常数)[2]。
这样,存入R0里的数初始化为8即可,其精度可以达到1 μs。
用这种方法,可以非常方便地实现512 μs以下时间的延时。
如果需要更长时间,可以使用两层或更多层的嵌套,当然其精度误差会随着嵌套层的增加而成倍增加。
虽然汇编语言的机器代码生成效率很高,但可读性却并不强,复杂一点的程序就更难读懂;而C语言在大多数情况下,其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,且C 语言还可以嵌入汇编程序来解决高时效性的代码编写问题。
就开发周期而言,中大型软件的编写使用C 语言的开发周期通常要比汇编语言短很多,因此研究C语言程序的精确延时性能具有重要的意义。
C程序中可使用不同类型的变量来进行延时设计。
经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。
2 单层循环延时精度分析下面是进行μs级延时的while程序代码。
c语言中delay的用法

c 语言中 delay 的用法C 语言作为一门新型高级编程语言 ,在计算机软件编程中具有较为广泛的应用和实现。
下面小编就跟你们详细介绍下 c 语言中 delay 的用法,希望对你们有用。
c 语言中 delay 的用法如下:假设一个延时函数如下:void delay(){uint i;for(i=0;i<20000;i++);}我们怎么来算呢,先将 20000 转成 16 进制,得到 4E20,然后将高字节 4E 乘以 6 得到 468D,再将 468+2=470,然后将 470D*20HEX (即 32D)=15040;所心这个延时函数总共要执行 15040 个周期,假设所用的晶振为 12MHZ,则该段函数总延时:15.04ms。
有了这个公式我们如果想要设定指定的延时长度就可以用它的己知公式确定。
即:总时间=[(6*i 值的高 8 位)+2]*i 的低 8 位。
例如:设要延时 125ms。
我们将低字节先赋值200D*(即:C8),然后再算高低节的定值,由式中可知 125ms=200*((i 值的高字节*6)+2),又可推算出(高低节*6)+2 的总延迟时间应等于625us,将625/6=104.1666,取整数得到 104,将 104 转成 16 进制得到 68H,再将高字节和低字节组合起来即得到了定值,即:68C8HEX,代入函数即如下:void delay(){uint i;for(i=0;i<0x68C8;i++);}如果写直进行就要将 68C8 转成 10 进制,即:26824,代入后得到:void delay(){uint i;for(i=0;i<0x26824;i++);在 c 语言中嵌入一段汇编的延时程序呀,你自己看看书,很简单的用在单片机里的可以 C 和汇编混合使用,因为用汇编编写延时要准确些,所以你不妨写一个汇编程序,然后再调用它好了,要用C来编精确的延时确实是比较难的哦.呵呵谁说 C 语言不能精确延时,用 51 单片机的定时/计数器一或者用定时/计数器 2 的工作方式 2,自动再装入 8 位计数器,就可以精确延时,别说 1MS 了就是 100um 也能精确做到。
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_( );_NOP_( );_NOP_( );_NOP_( );_NOP_( );}延迟时间=6*1us+2 us+2 us=10usb:delaytime为us级我们用汇编语言写单片机延时10ms的程序,可以编写下面的程序来实现:unsigned char i,jfor(i=255;i>0;i--)for(j=255;j>0;j--);或unsigned char i,ji=255;do{j=255;do{j--}while(j);i--;}while(i);或unsigned char i,ji=255;while(i){j=255;while(j){j--};i--;}这三种方法都是用DJNZ指令嵌套实现循环的,由C51编译器用下面的指令组合来完成的MOV R7,#0FFHLOOP2: MOV R6,#0FFH (1周期)LOOP1: DJNZ R6,LOOP1DJNZ R7,LOOP2 (2周期)这些指令的组合在汇编语言中采用DJNZ指令来做延时用,因此它的时间精确计算也是很简单,假上面变量i的初值为m,变量j的初值为n,则总延时时间为:m×(n×2+2+1),注:DJNZ A,B是一条转移指令,先将A减1,若减后,1)A=0;不转移到B处;2)A!=0;跳到B处;例2:void delay500ms(void){unsigned charR7,R6,R5;for(R7=15;R7>0;R7--)for(R6=202;R6>0;R6--)for(R5=81;R5>0;R5--);}产生的汇编:C:0x0800 7F0F MOV R7,#0x0FC:0x0802 7ECA MOV R6,#0xCAC:0x0804 7D51 MOV R5,#0x51C:0x0806 DDFE DJNZ R5,C:0806 最内层C: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总结:延时时间=((2*内0+3)*内1+3)*内2五、使用示波器确定延时时间利用示波器来测定延时程序执行时间。
单片机中delay延时原理

单片机中delay延时原理延时是指在程序中暂停一段时间来等待一些操作完成或者时间间隔的过程。
在单片机中,常用的延时方法是利用循环来实现。
下面将详细介绍单片机中延时的原理。
1.循环延时循环延时是最简单的延时方法。
单片机中的时钟频率非常高,可以达到几百万或者几千万次每秒。
通过循环执行一定的指令次数,可以实现一定的延时。
每个指令的执行时间是固定的,因此通过控制循环次数可以实现准确的延时。
循环延时的原理非常简单:通过循环执行一段代码,每次循环都进行一个空操作或者简单的循环次数检测,当循环次数达到预设的值时,延时结束。
2.普通延时实现普通延时实现的代码如下:```cunsigned int i, j;for(j=0;j<1000;j++)//空操作,用于延时}}```上述代码中空操作的循环次数是根据实际情况设定的,一般通过试验来确定。
空操作的次数太小会导致延时不准确,次数太大可能会浪费过多的时间。
3.精确延时实现普通延时方法虽然简单,但是有一定的误差,影响了延时的准确性。
为了提高延时的准确性,可以通过精确延时方法来实现。
精确延时方法是使用定时器来实现延时。
利用定时器的计时功能,可以精确地控制延时的时间。
具体步骤如下:3.1设置定时器的工作模式和工作频率。
3.2根据需要延时的时间计算出定时器的初值。
3.3启动定时器。
3.4循环检测定时器的中断标志位,直到定时器计数结束。
3.5关闭定时器。
下面是一个使用定时器实现精确延时的代码示例:```cvoid delay_us(unsigned int n) //精确微秒延时TMOD=0x01;//设置定时器0为工作模式1TL0=0;//设置定时器初值TH0=0;TR0=1;//启动定时器while(n--) //循环检测定时器计时是否结束while(TF0 == 0);TF0=0;//清除定时器中断标志位}TR0=0;//关闭定时器```该代码中使用了定时器0来实现微秒级的延时。
delphi 延时的方法

delphi 延时的方法Delphi是一种流行的编程语言,常用于Windows平台的应用程序开发。
在Delphi中,延时(Delay)是一种常用的操作,用于暂停程序的执行一段时间。
本文将介绍Delphi中常用的延时方法,并探讨其使用场景和注意事项。
一、使用Sleep函数实现延时在Delphi中,可以使用Sleep函数来实现延时效果。
Sleep函数属于Windows API,通过将当前线程挂起一段时间来实现延时。
Sleep函数的参数是以毫秒为单位的时间,表示需要暂停的时间长度。
下面是一个使用Sleep函数实现延时的示例代码:```pascalprocedure Delay(ms: Integer);beginSleep(ms);end;```在上述示例代码中,Delay过程接受一个整数参数ms,表示需要延时的毫秒数。
然后调用Sleep函数,将当前线程挂起指定的时间长度。
使用Sleep函数实现延时的优点是简单易用,代码量少。
但缺点是Sleep函数会阻塞当前线程的执行,导致程序无法响应其他操作。
因此,当需要延时的同时还需要保持程序的响应性时,应考虑其他方法。
二、使用TTimer组件实现延时Delphi中的TTimer组件可以用于实现延时效果,而不阻塞程序的执行。
TTimer组件是一个计时器,可以在指定的时间间隔内触发事件。
下面是一个使用TTimer组件实现延时的示例代码:```pascalprocedure TForm1.Delay(ms: Integer);beginTimer1.Interval := ms;Timer1.Enabled := True;end;procedure TForm1.Timer1Timer(Sender: TObject);beginTimer1.Enabled := False;// 延时结束后要执行的代码end;```在上述示例代码中,Delay过程接受一个整数参数ms,表示需要延时的毫秒数。
PIC单片机Delay10KTCYx(1)延时计算

PIC单片机Delay10KTCYx(1)延时计算概述Delay10KTCYx(1)的延时在PIC 单片机开发中有所贡献。
它是一个用于计算单指令延时的宏,它接受CPU 内部时钟(以千分之一毫秒(KTCYx)为单位)作为参数,然后依据该值进行单指令时间的延时。
使用该宏而不是软件法,可以节省许多的程序空间。
特点1. 能够识别CPU中的内部時鐘,并依据該值進行時間的延遲。
2. Delay10KTCYx(1)接受CPU内部时钟,以千分之一毫秒(KTCYx)为单位,设置延时。
3. 宏调用可以有效的节省程序空间。
4. Delay10KTCYx(1)稳定可靠,使用于实时系统中。
使用方法1. 使用Delay10KTCYx()宏调用延时函数时,需要传入一个参数。
这个参数决定计算机等待的时间,以千分之一毫秒(KTCYx)为单位。
具体参数公式为:参数=等待的延时时间/102. 使用时,需要在每个函数前加上#include <delays.h>,以便编译程序中使用Delay10KTCYx宏。
3. Delay10KTCYx()宏支持两种模式:(1)精度模式:当宏以参数1调用时,即Delay10KTCYx(1),精度模式即可运作,以达到最高精度模式。
(2)容错模式:当宏以其它参数调用时,容错模式即可运作,以达到容错需求。
4. Delay10KTCYx(1)宏在调用延迟指令时,实际上是每空出7个指令ら示实指令,就可以用1个machine cycle的延时单元进行延时操作。
最大的延时设置可以支持最多1KB 的延时调用。
总结Delay10KTCYx(1)是PIC 单片机系统开发中使用的常用宏函数,它接受CPU 内部的时钟作为参数,然后依据该参数来限制单指令执行的时间,以此来达到计算机系统中等待的延时处理。
此宏具有准确度高、节省空间及容错性强等特点,几乎可以在所有PIC 单片机系统开发中使用。
用单片机实现延时(自己经验及网上搜集)

标准的C语言中没有空语句。
但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。
这在汇编语言中很容易实现,写几个nop就行了。
在keil C51中,直接调用库函数:#include<intrins.h> // 声明了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,#0FFHLOOP: 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结构来完成,每个循环体内的变量仍然采用无符号字符变量。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
五、使用示波器确定延时时间
利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个I/O口线如P1.0为高电平,在函数的最后清P1.0为低电平。在主程序中循环调用该延时函数,通过示波器测量P1.0引脚上的高电平时间即可确定延时函数的执行时间。方法如下:
for(i=255;i>0;i--)
for(j=255;j>0;j--);
或
unsigned char i,j
i=255;
do
{
j=255;
do{j--}
while(j);
i--;
}
while(i);
或
unsigned char i,j
i=255;
while(i)
{
j=255;
while(j)
{j--};
void Delay10us( ) {
_NOPቤተ መጻሕፍቲ ባይዱ( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
}
延迟时间=6*1us+2us+2us=10us
b:delaytime为us级
我们用汇编语言写单片机延时10ms的程序,可以编写下面的程序来实现:
unsigned char i,j
四、a:delaytime为us级
直接调用库函数:
#include<intrins.h>//声明了void _nop_(void);
_nop_(); //产生一条NOP指令
作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。
eg:可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:
5.在do…while,while语句中,循环体内变量也采用减减方法。
三、编辑注意:
1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。
2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。
3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。
值为m,变量j的初值为n,则总延时时间为:
m×(n×2+2+1),
注:DJNZ A,B是一条转移指令,先将A减1,若减后,
1)A=0;不转移到B处;
2)A!=0;跳到B处;
例2:void delay500ms(void)
{
unsigned charR7,R6,R5;
for(R7=15;R7>0;R7--)
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
}
}
}
void main (void) {
Dly1ms();
}
把P1.0接入示波器,运行上面的程序,可以看到P1.0输出的波形为周期是3 ms的方波。其中,高电平为2 ms,低电平为1 ms,即for循环结构“for(j=0;j<124;j++) {;}”的执行时间为1 ms。通过改变循环次数,可得到不同时间的延时。当然,也可以不用for循环而用别的语句实现延时。这里讨论的只是确定延时的方法。
sbit T_point = P1^0;
void Dly1ms(void) {
unsigned int i,j;
while (1) {
T_point = 1;
for(i=0;i<2;i++){
for(j=0;j<124;j++){;}
}
T_point = 0;
for(i=0;i<1;i++){
for(j=0;j<124;j++){;}
for(R6=202;R6>0;R6--)
for(R5=81;R5>0;R5--);
}
产生的汇编:
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最内层
调试>设置/取消断点”设置或移除断点,也可以用鼠标在该行双击实现同样的功能
二、编程最好:
1.尽量使用unsigned型的数据结构。
2.尽量使用char型,实在不够用再用int,然后才是long。
3.如果有可能,不要用浮点型。
4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。
delay延时教程(用的是12MHz晶振的MCS-51)
一、
1)NOP指令为单周期指令
2)DJNZ指令为双周期指令
3)mov指令为单周期指令
4)子程序调用(即LCALL指令)为双周期指令
5)ret为双周期指令
states是指令周期数,
sec是时间,=指令周期×states,设置好晶振频率就是准确的了
i--;
}
这三种方法都是用DJNZ指令嵌套实现循环的,由C51编
译器用下面的指令组合来完成的
MOVR7,#0FFH
LOOP2:MOVR6,#0FFH(1周期)
LOOP1:DJNZR6,LOOP1
DJNZR7,LOOP2(2周期)
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初