for循环实现C语言精确延时
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单片机技巧:精确延时

在用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--);}以上的这先希望对大家有帮组,如有不足之处请指出,如有更好的方法也可以告诉我,大家一起分享第二部分关于单片机C语言的精确延时,网上很多都是大约给出延时值没有准确那值是多少,也就没有达到精确高的要求,而51hei给出的本函数克服了以上缺点,能够精确计数出要延时值且精确达到1us,本举例所用CPU为STC12C5412系列12倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
4mhz晶振延时10秒的c语言程序

4mhz晶振延时10秒的c语言程序4MHz晶振是一种常用的振荡器组件,它能够产生4百万次的振荡周期。
在计算机领域,我们经常使用晶振来提供准确的时钟信号,以便控制程序执行的时间和顺序。
本文将介绍如何使用4MHz晶振来实现一个延时10秒的C语言程序。
在C语言中,我们可以使用延时函数来控制程序的执行时间。
延时函数通常使用循环来实现,通过循环执行一定次数的空操作来消耗一定的时间。
因为晶振的频率是已知的,我们可以根据晶振的频率来计算出每个循环所需的时间,从而实现精确的延时。
我们需要了解4MHz晶振的频率是多少。
根据晶振的频率公式:频率= 振荡次数/ 时间,我们可以将已知的振荡次数(4百万次)代入公式,求解出时间。
经计算可得,每个振荡周期的时间为1 / 4MHz = 0.25微秒。
接下来,我们需要确定延时函数中循环的次数。
由于我们需要延时10秒,而每个振荡周期的时间为0.25微秒,所以我们需要执行的循环次数为10秒/ 0.25微秒= 40百万次。
因此,我们需要在延时函数中使用一个循环,执行40百万次的空操作。
下面是一个使用4MHz晶振延时10秒的C语言程序示例:```c#include <stdio.h>void delay(unsigned long count) {unsigned long i;for(i = 0; i < count; i++) {// 空操作}}int main() {unsigned long delayCount = 4000000; // 待执行的循环次数// 输出提示信息printf("开始延时...\n");// 调用延时函数delay(delayCount);// 输出延时完成信息printf("延时完成!\n");return 0;}```在上述代码中,我们定义了一个名为delay的延时函数,它接受一个参数count,表示需要执行的循环次数。
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,并设置定时器中断。
在中断服务程序中,我们进行相应的操作来实现精确的延时。
这种方法需要使用到单片机的定时器中断功能,相对复杂一些,但是可以实现精确的延时。
FOR循环实现C语言精确延时

for实现C语言精确延时C语言最大的缺点就是实时性差,我在网上到看了一些关于延时的讨论,其中有篇文章51单片机Keil C延时程序的简单研究,写得不错,他是用while(--i);产生DJNZ来实现精确延时,后来有人说如果while里面不能放其它语句,否则也不行,用do-while就可以,具体怎样我没有去试.所有这些都没有给出具体的实例程序来.还看到一些延时的例子多多少少总有点延时差.为此我用for循环写了几个延时的子程序贴上来,希望能对初学者有所帮助.(晶振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--);}产生的汇编:C:0x08007F0F MOV R7,#0x0FC:0x08027ECA MOV R6,#0xCAC:0x08047D51MOV R5,#0x51C:0x0806DDFE DJNZ R5,C:0806C:0x0808DEFA DJNZ R6,C:0804C:0x080A DFF6DJNZ R7,C:0802C:0x080C22RET计算分析:程序共有三层循环一层循环n:R5*2=81*2= 162us DJNZ2us二层循环m:R6*(n+3)=202*165= 33330us DJNZ2us+R5赋值1us=3us三层循环:R7*(m+3)=15*33333= 499995us DJNZ2us+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--);}产生的汇编C:0x08007F05MOV R7,#0x05C:0x08027E84MOV R6,#0x84C:0x08047D96MOV R5,#0x96C:0x0806DDFE DJNZ R5,C:0806C:0x0808DEFA DJNZ R6,C:0804C:0x080A DFF6DJNZ R7,C:0802C:0x080C22RET三.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--);}产生的汇编C:0x08007F05MOV R7,#0x05C:0x08027E04MOV R6,#0x04C:0x08047DF8MOV R5,#0xF8C:0x0806DDFE DJNZ R5,C:0806C:0x0808DEFA DJNZ R6,C:0804C:0x080A DFF6DJNZ R7,C:0802C:0x080C22RET四.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:0x08007F05MOV R7,#0x05C:0x08027E04MOV R6,#0x04C:0x08047D74MOV R5,#0x74C:0x08067CD6MOV R4,#0xD6C:0x0808DCFE DJNZ R4,C:0808C:0x080A DDFA DJNZ R5,C:0806C:0x080C DEF6DJNZ R6,C:0804C:0x080E DFF2DJNZ R7,C:0802C:0x081022RET在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.。
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语言中实现延时的两种常用方法。
开发者可以根据具体需求选择合适的延时方法。
通用C语言延时

通用C语言延时在嵌入式C编程中,免不了要用到软件延时。
这一般通过循环语句实现。
通过控制循环语句的循环次数,便可获得多种不同的延时时间。
为了便于使用和提高程序代码的复用率,一般又将循环语句封装成一个带参数的函数,称为延时函数。
如:void wait(unsigned int n){unsigned int i;for(i=0;i<n;i++);}延时函数的参数(形参,如上例中的变量 n ),即为控制循环语句循环次数的变量。
这样,在需要软件延时的时候,只需要调用延时函数,并将实际参数(实参,即n的实际值)代入形参,便可获得与该实际参数对应的延时时间。
这便是经典的软件延时的实现方法,非常简单。
但细心的读者会发现:延时函数的参数(比如上面的 n ),表征的是循环语句的“循环次数”,而不是“实际的延时时间”。
一般来说,假令循环语句每循环一次的时间为 b(注意,单位是“步”,即一个时钟周期,下同),函数调用、传值和返回所需的固有时间为 a ,那么,给定参数 n 时,调用一次延时函数实际实现的延时时间应为 t = a + b*n , ——而不是 n !这就意味着,当需要的延时时间为 t 时,应当传入的实参为 n = (t-a)/b,而不是 t 。
这样,为了获得比较准确的延时,每次调用函数之前,都要手工计算实际参数,很不方便;其次,当需要改变晶振频率的时候,程序中所有的延时参数都要重新计算,这显然不利于程序的移植。
为了解决这两个问题,提高程序的可移植性,可以利用宏定义的方式,对延时函数进行参数预修正。
例如,对上面给出的wait延时函数,可以使用下面的宏定义:#define delay(n) wait( ( (n) - a ) / b )这样,调用 delay(t) 就意味着调用 wait( (t-a)/b ) ,从而得到时间为t的延时,实现了参数与延时时间的同步,使用起来更加方便。
为了进一步提高可移植性,使软件延时能够适应不同的晶振频率,应当顺着上面的思路选择寻找更优方案。
c语言精确delay函数

c语言精确delay函数C语言中的精确延时函数是指能够以指定的时间精确延迟程序执行的函数。
在实际开发中,我们经常会遇到需要程序暂停一段时间的情况,这时就需要使用延时函数来实现。
在C语言中,常用的延时函数有两种,一种是使用循环来实现延时,另一种是使用系统提供的延时函数。
下面将详细介绍这两种方法的实现原理及其使用场景。
1. 循环延时法循环延时法是通过循环来实现延时的方法,其原理是让程序在一个循环中空转一段时间,从而达到延时的效果。
具体实现代码如下:```cvoid delay(unsigned int ms){unsigned int i, j;for(i = 0; i < ms; i++)for(j = 0; j < 10000; j++);}```上述代码中,delay函数接收一个参数ms,表示要延时的毫秒数。
函数内部使用两个嵌套的循环,外层循环控制延时的次数,内层循环则是一个空转的过程,通过调整内层循环的次数来控制延时的时间。
循环延时法的优点是简单易懂,适用于较简单的延时场景。
但是由于循环的执行时间受到处理器的影响,不同的处理器执行相同的循环时间可能会有差异,因此不能保证延时的精确性。
2. 系统延时函数系统延时函数是通过调用系统提供的函数来实现延时的方法,其原理是让程序暂停一段时间,从而达到延时的效果。
具体实现代码如下:```c#include <unistd.h>void delay(unsigned int ms){usleep(ms * 1000);}```上述代码中,delay函数接收一个参数ms,表示要延时的毫秒数。
函数内部使用usleep函数来实现延时,usleep函数的参数是微秒,所以需要将毫秒转换为微秒。
系统延时函数的优点是精确可靠,适用于对延时精度要求较高的场景。
由于系统延时函数是由操作系统提供的,可以保证延时的精确性,不受处理器的影响。
C语言中的精确延时函数有循环延时法和系统延时函数两种方法,根据实际需求选择合适的方法来实现延时。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C:0x0810 22 RET
在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.
C:0x080A DFF6 DJNZ R7,C:0802
C:0x080C 22 RET
三. 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--);
}
产生的汇编
C:0x0802 7E04 MOV R6,#0x04
C:0x0804 7D74 MOV R5,#0x74
C:0x0806 7CD6 MOV R4,#0xD6
C:0x0808 DCFE DJNZ R4,C:0808
C:0x080A DDFA DJNZ R5,C:0806
C:0x080C DEF6 DJNZ R6,C:0804
延时总时间=三层循环+循环外= 499995+5 = [(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--)
C:0x0804 7D51 MOV R5,#0x51
C:0x0806 DDFE DJNZ R5,C:0806
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
for实现C语言精确延时
C语言最大的缺点就是实时性差,我在网上到看了一些关于延时的讨论,其中有篇文章
51单片机Keil C延时程序的简单研究,
写得不错,他是用while(--i);产生DJNZ来实现精确延时,后来有人说如果while里面不能放其它语句,否则也不行,用do-while就可以,具体怎样我没有去试.所有这些都没有给出具体的实例程序来.还看到一些延时的例子多多少少总有点延时差.为此我用for循环写了几个延时的子程序贴上来,希望能对初学者有所帮助.(晶振12MHz,一个机器周期1us.)
for(k=150;k>0;k--);
}
产生的汇编
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E84 MOV R6,#0x84
C:0x0804 7D96 MOV R5,#0x96
C:0x0806 DDFE DJNZ R5,C:0806
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080C 22 RET
四. 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:0x0800 7F05 MOV R7,#0x05
一. 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
二层循环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
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E04 MOV R6,#0x04
C:0x0804 7DF8 MOV R5,#0xF8
C:0x0806 DDFE DJNZ R5,C:0806
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080A DFF6 DJNZ R7,C:0802