单片机C语言(for)延时计算
延时1us程序12mhz晶振c语言,51单片机KeilC延时程序的简单(晶振12MHz,一。。。
延时1us程序12mhz晶振c语⾔,51单⽚机KeilC延时程序的简单(晶振12MHz,⼀。
⼀. 500ms延时⼦程序void delay500ms(void){unsignedchari,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){unsignedchari,j,k;for(i=5;i>0;i--)for(j=132;j>0;j--)for(k=150;k>0;k--);}产⽣的汇编C:0x0800 7F05 MOV R7,#0x05C:0x0802 7E84 MOV R6,#0x84C:0x080C 22 RET三. 10ms延时⼦程序void delay10ms(void){unsignedchari,j,k;for(i=5;i>0;i--)for(j=4;j>0;j--)for(k=248;k>0;k--);}产⽣的汇编C:0x0800 7F05 MOV R7,#0x05C:0x0802 7E04 MOV R6,#0x04C:0x0804 7DF8 MOV R5,#0xF8C:0x0806 DDFE DJNZ R5,C:0806C:0x0808 DEFA DJNZ R6,C:0804C:0x080A DFF6 DJNZ R7,C:0802C:0x080C 22 RET四. 1s延时⼦程序void delay1s(void){unsignedcharh,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--); }对1s延时的验证:1.设置仿真的晶振为12MHz2.在延时函数设置断点3.单步运⾏程序,到达延时函数的⼊⼝4.先记下进⼊延时函数的时间5.step out跳出函数,记下此时时间,两个时间相减即为延时函数运⾏时间函数运⾏时间=1.00041400-0.00041600≈1s产⽣的汇编C:0x0808 DCFE DJNZ R4,C:0808C:0x080A DDFA DJNZ R5,C:0806C:0x080C DEF6 DJNZ R6,C:0804C:0x080E DFF2 DJNZ R7,C:0802C:0x0810 22 RET在精确延时的计算当中,最容易让⼈忽略的是计算循环外的那部分延时,在对时间要求不⾼的场合,这部分对程序不会造成影响. void mDelay(unsigned int Delay) //Delay = 1000 时间为1S{unsignedinti;for(;Delay>0;Delay--){for(i=0;i<124;i ){;}}}void waitms(inti){charm;for( ; i ;i--){for(m = 203; m ; m--){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}}}延时1ms的函数时钟频率12MHzunsigned intsleepTime;unsingedchar inSleep = 0;void sleepService(void)}void isr_timer(void) //假定定时器中断1ms 中断⼀次。
C语言循环语句实现单片机延时函数
C语言循环语句实现单片机延时函数徐雷;孙长智【摘要】延时是单片机教学中最常用的概念之一,因此延时函数是单片机控制程序中的一个重要函数。
分别利用while循环语句、do-while循环语句、for循环语句以及while和for循环语句组合实现t ms延时点亮一个按照一定频率闪烁的LED灯,以此为例,总结了C语言循环语句实现单片机延时函数的方法,帮助学生在掌握C语言知识的基础上,增强了对单片机延时概念的理解,提高了教学效果。
【期刊名称】《安庆师范学院学报(自然科学版)》【年(卷),期】2013(000)004【总页数】4页(P117-120)【关键词】单片机;C语言;延时函数;循环语句【作者】徐雷;孙长智【作者单位】亳州师范高等专科学校理化系,安徽亳州 236800;亳州师范高等专科学校理化系,安徽亳州 236800【正文语种】中文【中图分类】基础科学20131:辛 11 月第 19 卷第 4 期安庆师范学院学报(自然科学版)Nov.2013Vol.19 No.4Journal of Anqing Teachers College( Natural Science Edition) 网络出版时间:20日- 12-19 20:16网络出版地址:http ://ki.neνkcms/detaiν34.1150.N.20131219.2016.030.html C语言循环语句实现单片机延时函数徐雷,孙长智(毫州师范高等专科学校理化系,安徽毫州 236800)摘要:延时是单片机教学中最常用的概念之一.因此延时函数是单片机控制程序中的一个重要函数。
分别利用 while 循环语句、do-while 循环语句、“r 循环语句以及 while 和 for 循环语句组合实现 t ms 延时点亮一个按照一定频率闪烁的 LED 灯,以此为例,总结了 C 语言循环语句实现唯片机延时函数的方法,帮助学生在掌握 C 语言知识的基础上,增强了对单片机延时概念的理解,提高了数学效果。
51单片机延时函数
51单片机延时函数在嵌入式系统开发中,51单片机因其易于学习和使用、成本低廉等优点被广泛使用。
在51单片机的程序设计中,延时函数是一个常见的需求。
通过延时函数,我们可以控制程序的执行速度,实现定时器功能,或者在需要的时候进行延时操作。
本文将介绍51单片机中常见的延时函数及其实现方法。
一、使用for循环延时这种方法不精确,但是对于要求不高的场合,可以用来估算延时。
cvoid delay(unsigned int time){unsigned int i,j;for(i=0;i<time;i++)for(j=0;j<1275;j++);}这个延时函数的原理是:在第一个for循环中,我们循环了指定的时间次数(time次),然后在每一次循环中,我们又循环了1275次。
这样,整个函数的执行时间就是time乘以1275,大致上形成了一个延时效果。
但是需要注意的是,这种方法因为硬件和编译器的不同,延时时间会有很大差异,所以只适用于对延时时间要求不精确的场合。
二、使用while循环延时这种方法比使用for循环延时更精确一些,但是同样因为硬件和编译器的不同,延时时间会有差异。
cvoid delay(unsigned int time){unsigned int i;while(time--)for(i=0;i<1275;i++);}这个延时函数的原理是:我们先进入一个while循环,在这个循环中,我们循环指定的时间次数(time次)。
然后在每一次循环中,我们又循环了1275次。
这样,整个函数的执行时间就是time乘以1275,大致上形成了一个延时效果。
但是需要注意的是,这种方法因为硬件和编译器的不同,延时时间会有差异,所以只适用于对延时时间要求不精确的场合。
三、使用定时器0实现精确延时这种方法需要在单片机中开启定时器0,并设置定时器中断。
在中断服务程序中,我们进行相应的操作来实现精确的延时。
这种方法需要使用到单片机的定时器中断功能,相对复杂一些,但是可以实现精确的延时。
单片机C51延时时间怎样计算
C程序中可使用不同类型的变量来进行延时设计。
经实验测试,使用unsi gned char类型具有比un signe d int更优化的代码,在使用时应该使用unsi gned char作为延时变量。
以某晶振为12MHz的单片机为例,晶振为12MH z即一个机器周期为1us。
一. 500ms延时子程序程序:void delay500ms(void){unsign ed 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 = 162usDJNZ 2us二层循环m:R6*(n+3) = 202*165 = 33330u s 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){unsign ed 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){unsign ed 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){unsign ed 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--);}参考链接:http://www.picav/news/2010-04/2106.htm摘要实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。
单片机延时计算
单片机延时计算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个机器周期的执行时间。
**程序运行到第一个断点所用时间0.00038900s,运行到第二个断点所用时间为0.01042800s,则执行delay_10ms()函数所用时间为0.010428-0.000389=0.010039s=10.039ms≈10ms。
c语言中延时的方法
c语言中延时的方法C语言中实现延时的方法有多种方式。
下面将介绍两种常用的延时方法:方法一:使用循环实现延时使用循环来进行延时是C语言中常用的方法之一。
通过循环次数来控制延时的时间,代码如下:```#include <stdio.h>void delay(int milliseconds) {for (int i = 0; i < milliseconds * 10000; i++) {// 延时}}int main() {printf("开始延时\n");delay(1000); // 延时1秒printf("延时结束\n");return 0;}```在上述代码中,delay函数使用了一个for循环来实现延时,其中循环次数通过乘以10000与延时时间相乘得到。
这种方法的缺点是无法精确控制延时时间,受系统执行速度的影响较大。
方法二:使用<time.h>库函数实现延时另一种常用的延时方法是利用<time.h>头文件中的库函数,如sleep函数。
代码如下:```#include <stdio.h>#include <time.h>void delay(int seconds) {sleep(seconds);}int main() {printf("开始延时\n");delay(1); // 延时1秒printf("延时结束\n");return 0;}```在上述代码中,delay函数通过调用sleep函数来实现延时,参数表示延时的秒数。
这种方法的优点是延时时间较为精确,但缺点是无法实现毫秒级的延时。
以上是C语言中实现延时的两种常用方法。
开发者可以根据具体需求选择合适的延时方法。
51单片机c语言延时
51单片机c语言延时51单片机(8051微控制器)是一种广泛使用的嵌入式系统芯片,其编程语言包括C语言和汇编语言等。
在C语言中,实现51单片机延时的方法有多种,下面介绍其中一种常用的方法。
首先,我们需要了解51单片机的指令周期和机器周期。
指令周期是指单片机执行一条指令所需的时间,而机器周期是指单片机执行一个操作所需的时间,通常以微秒为单位。
在C语言中,我们可以使用循环结构来实现延时。
#include <reg51.h> // 包含51单片机的寄存器定义void delay(unsigned int time) // 延时函数,参数为需要延时的微秒数{unsigned int i, j;for (i = 0; i < time; i++)for (j = 0; j < 1275; j++); // 1275个机器周期,约等于1ms}void main() // 主函数{while (1) // 无限循环{// 在这里添加需要延时的代码P1 = 0x00; // 例如将P1口清零delay(1000); // 延时1秒P1 = 0xFF; // 将P1口清零delay(1000); // 延时1秒}}在上面的代码中,我们定义了一个名为delay的函数,用于实现延时操作。
该函数接受一个无符号整数参数time,表示需要延时的微秒数。
在函数内部,我们使用两个嵌套的循环来计算延时时间,其中外层循环控制需要延时的次数,内层循环控制每个机器周期的时间(约为1微秒)。
具体来说,内层循环执行了约1275次操作(具体数值取决于编译器和单片机的型号),以实现约1毫秒的延时时间。
需要注意的是,由于单片机的指令周期和机器周期不同,因此我们需要根据具体的单片机型号和编译器进行调整。
在主函数中,我们使用一个无限循环来不断执行需要延时的操作。
例如,我们将P1口的所有引脚清零,然后调用delay函数进行1秒钟的延时,再将P1口清零并再次调用delay函数进行1秒钟的延时。
单片机延时计算公式
单片机延时计算公式单片机是一种应用广泛的微型计算机系统,它被广泛应用于嵌入式系统、电子设备等领域。
在单片机的编程过程中,经常需要进行延时操作,以控制系统的运行速度或实现特定的功能。
为了准确地控制延时时间,需要使用延时计算公式。
延时时间与单片机的时钟频率有关,通常以秒、毫秒、微秒等单位来表示。
在单片机中,时钟频率是一个基本参数,它决定了单片机每秒钟所执行的指令数。
延时计算公式可以通过时钟频率和所需延时时间来计算出延时所需的指令数。
延时计算公式的一般形式如下:延时指令数 = 延时时间× 时钟频率其中,延时指令数表示需要延时的指令数目,延时时间表示所需延时的时间,时钟频率表示单片机的时钟频率。
在实际应用中,延时时间一般以毫秒或微秒为单位。
为了方便计算,可以将延时时间转换为秒,再根据单片机的时钟频率进行计算。
假设延时时间为T秒,时钟频率为f Hz,则延时指令数可以表示为:延时指令数= T × f延时指令数一般为整数,表示需要延时的指令数目。
在单片机编程中,可以通过循环执行空操作指令或者通过定时器来实现延时操作。
通过控制循环次数或者定时器的设置,可以实现精确的延时时间。
需要注意的是,延时计算公式中的时钟频率必须与实际使用的时钟频率相一致。
在单片机编程中,时钟频率一般通过设置寄存器来进行配置。
如果延时计算公式中的时钟频率与实际使用的时钟频率不一致,将会导致延时时间的不准确。
延时计算公式在单片机编程中具有重要的作用。
通过合理地计算延时指令数,可以实现精确的延时操作,从而实现系统的稳定运行和功能的正常实现。
在实际应用中,需要根据具体的需求和系统的要求,选择合适的延时时间和时钟频率,以确保系统的性能和功能的准确性。
总结起来,单片机延时计算公式是一种根据延时时间和时钟频率来计算延时指令数的方法。
通过合理地计算延时指令数,可以实现精确的延时操作,保证系统的稳定运行和功能的正常实现。
在单片机编程中,合理地应用延时计算公式,可以提高系统的性能和功能的准确性。
单片机C语言延时程序计算
2 软件延时与时间计算
在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。
2.1 短暂延时
可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延
单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。
80us 1 1 48 0
90us 1 1 55 +0.5
}
延时时间 a的值 b的值 c的值 延时误差(us)
10us 1 1 1 -0.5
1ms 1 3 219 -1.5
2ms 2 3 220 +3
900us
9 1 63 -1.5
60us 1 1 35 +0.5
70us 1 1 42 +1
在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。
300us 3 1 63 +1.5
单片机C语言延时计算
单片机C语言延时计算单片机是一种集成电路芯片,内部集成了微处理器、存储器、输入输出接口等主要部件。
C语言是常用的单片机编程语言,可以通过编写C程序来实现单片机的控制和功能。
在单片机编程中,延时是一种常用的操作,用于控制程序执行过程中的时间间隔。
延时的实现方法有多种,可以使用循环遍历、定时器、外部中断等方式。
在循环遍历的延时方法中,可以通过设定一个循环次数来实现延时。
具体的延时时间与循环的次数成正比关系。
例如,在一个8位单片机中,循环一次大约需要4个机器周期,因此可以通过适当设置循环次数来达到需要的延时时间。
但是,使用循环遍历的延时方法会占用CPU资源,可能会影响其他任务的执行。
另一种常用的延时方法是使用定时器。
单片机内部通常集成了一个或多个定时器,可以通过设置定时器的初值和工作模式来实现精确的延时。
例如,可以通过设置定时器的计数值和工作频率来计算出延时的时间。
在定时器工作期间,单片机可以继续执行其他任务,不会占用过多的CPU资源。
除了循环遍历和定时器方法外,还可以使用外部中断的方式来实现延时。
具体的实现方法是通过外部信号触发中断,并在中断处理程序中实现延时功能。
这种方法可以根据外部信号的频率和工作模式来调整延时时间。
在单片机编程中,为了提高代码的可读性和可重用性,可以将延时操作封装成函数。
例如,可以定义一个名为delay的函数,函数的参数为延时的时间(单位为毫秒),函数内部通过循环遍历、定时器或外部中断的方式实现延时。
延时的时间计算可以考虑单片机的工作频率、机器周期以及延时的时间要求。
单片机的工作频率可以由时钟源来决定,一般可以通过设置分频系数来调整。
机器周期是单片机执行一条指令所需的时间,通过单片机的数据手册可以查到相关的数据。
根据单片机的工作频率和机器周期,可以计算出所需的循环次数或定时器计数值。
在使用延时功能时需要注意延时时间的准确性和可调性。
准确性是指延时的实际时间与预期时间之间的误差,通过调整循环次数或定时器计数值可以实现较高的准确性。
c语言延时程序的计算方法经典
MOV 70H,#48
LOOP4:DJNZ 70H,LOOP4
定时器延时:
晶振12MHZ,延时1s,定时器0工作方式为方式1
DELAY1:MOV R7,#0AH ;;晶振12MHZ,延时0.5秒
AJMP DELAY
DELAY2:MOV R7,#14H ;;晶振12MHZ,延时1秒
TL0=0xa8;
TR0=1; /*启动定时器*/
while(TF0==0);
TR0=0;
}
(2)延时1MS
void delay_1ms(void)
{
TMOD=0x01; /*定时器0工作在模式1下(16位计数器)*/
TH0=0xfd;
TL0=0x65;
TR0=1; /*启动定时器*/
while(TF0==0);
TR0=0;
}
(3)延时4.5ms
void delay_4_5ms(void)
{
TMOD=0x01; /*定时器0工作在模式1下(16位计数器)*/
TH0=0xf4;
TL0=0x48;
TR0=1; /*启动定时器*/
while(TF0==0);
TR0=0;
}
}
1s延时子程序(12MHZ)
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--);
}
200ms延时子程序(12MHZ)
void delay200ms(void)
8位单片机微妙延时函数
在单片机编程中,延时函数是非常重要的部分,它可以帮助我们控制程序的执行速度和节奏。
下面是一个基于8位单片机的微妙延时函数的示例。
假设我们使用的是8位单片机,如AT89C51,并且我们使用C语言进行编程。
这个延时函数将使用循环来达到延时的效果。
```c
#include <reg51.h> // 包含单片机特定的头文件
// 延时函数,单位为微秒
void delay(unsigned int time) {
unsigned int i, j;
for (i = 0; i < time; i++) {
for (j = 0; j < 125; j++); // 假设单片机的晶振频率为12.5MHz
}
}
```
这个函数的基本原理是通过循环延迟来达到延时的效果。
在每次循环中,我们使用一个空的for循环来消耗时间,这个循环的次数正好是所需延迟时间的倒数。
这里我们假设单片机的晶振频率为12.5MHz,这是许多8位单片机常见的频率。
需要注意的是,延时函数的具体实现会根据单片机型号、晶振频率、系统时钟等不同而有所差异。
在某些情况下,可能需要更精确或更适合的延时算法。
另外,对于大规模的应用,通常建议使用专门的时间库或者操作系统提供的延时函数,这样可以避免手动编写复杂的延时逻辑。
最后,要注意的是延时函数只是实现时间控制的一个手段,具体的实现需要根据具体的需求和环境来决定。
例如,如果你的应用需要高精度的延时,那么可能需要使用更复杂的方法,如定时器中断等。
单片机C语言的延时计算之欧阳歌谷创编
标准的C语言中没有空语句。
但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。
欧阳歌谷(2021.02.01)这在汇编语言中很容易实现,写几个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指令来完成,相当于如下指令:MOV09H,#0FFHLOOP: DJNZ09H,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结构来完成,每个循环体内的变量仍然采用无符号字符变量。
单片机c5延时时间怎样计算
C程序中可使用不同类型的变量来进行延时设计。
经实验测试,使用unsignedchar类型具有比unsignedint更优化的代码,在使用时应该使用unsignedchar作为延时变量。
以某晶振为12MHz的单片机为例,晶振为12MHz 即一个机器周期为1us。
一.500ms延时子程序程序:voiddelay500ms(void){unsignedchari,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=162usDJNZ2us二层循环m:R6*(n+3)=202*165=33330usDJNZ2us+R5赋值1us=3us三层循环:R7*(m+3)=15*33333=499995usDJNZ2us+R6赋值1us=3us循环外:5us子程序调用2us+子程序返回2us+R7赋值1us=5us延时总时间=三层循环+循环外=499995+5=500000us=500ms计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5二.200ms延时子程序程序:voiddelay200ms(void){unsignedchari,j,k;for(i=5;i>0;i--)for(j=132;j>0;j--)for(k=150;k>0;k--);}三.10ms延时子程序程序:voiddelay10ms(void){unsignedchari,j,k;for(i=5;i>0;i--)for(j=4;j>0;j--)for(k=248;k>0;k--);}四.1s延时子程序程序:voiddelay1s(void){unsignedcharh,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--); }参考链接:摘要实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。
for循环编写延时函数的方法
很多初学者对于程序中ms级延时函数的编写方法比较疑惑,其原理和方式虽然简单,但是却没有相关资料。
这里用一个例程详细介绍一下。
过程参考如下:
在编译器下建立一个新项目,也可以利用已有项目。
此过程中需要注意,单片机晶振的选择,因为for循环里指令的执行时间和晶振有直接关系,本例中晶振使用11.0592M。
编写一段关于延时的函数,主要利用for循环,代码如下:
void delay_ms(unsigned int ms)
{
unsigned int i;
unsigned char j;
for(i=0;i<ms;i++)
{
for(j=0;j<200;j++);
for(j=0;j<102;j++);
}
}
其中ms是输入参数,如果输入1,就是要求程序延时1ms。
j变量是调整程序运行的时间参数。
调整j的数值,使1次循环的时间在1ms。
将此程序编译通过,然后利用软件仿真,调整时间。
两次时间差就是延时函数使用的时间,如果与1ms相差比较多,用户可以调整j 参数的值,使延时时间尽量接近1ms。
如增大j的值for(j=0;j<105;j++);
此方法得出延时函数,在晶振不同的情况下,延时时间会不准。
另外这种方法不是完全精确的延时,所以不要太深研究误差的问题。
软件调试结果,这个程序的延时时间为:1.01779ms,一般的单片机系统中都可以应用。
单片机C语言中_nop_函数使用及延时计算
标准的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结构来完成,每个循环体内的变量仍然采用无符号字符变量。
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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
共有三条延时函数说明如下:
函数调用分两级:一级是小于10US的延时,二级是大于10US的延时
//====================小于10US的【用1US级延时】====================
//----------微秒级延时---------
for(i=X;i>X;i--) 延时时间=(3+5*X)/12 提示(单位us, X不能大于255)
//================大于10US<小于21.9955Ms的可用【10US级延时函数】=========== void Delay10us(uchar Ms)
{
uchar data i;
for(;Ms>0;Ms--)
for(i=26;i>0;i--);
}
i=[(延时值-1.75)*12/Ms-15]/4
如想延时60US则i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再调用上面的【10US 级延时函数】Delay10us(6); 则就精确延时60US;
如果想延时64US可以用这二种函数组合来用: Delay10us(6); for(i=9;i>X;i--) 共延时64US。