单片机C语言的延时计算
- 格式:doc
- 大小:43.50 KB
- 文档页数:8
STC12系列单片机C语言的延时程序本举例所用CPU 为STC12C5412 系列12 倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
共有三条延时函数说明如下:函数调用分两级:一级是小于10US 的延时,二级是大于10US 的延时//====================小于10US 的【用1US 级延时】====================//----------微秒级延时---------for(i=X;i>X;i--) 延时时间=(3+5*X)/12 提示(单位us, X 不能大于255)//================大于10US0;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//============== 对于大于20Ms 的可用中断来实现程序运行比较好===============中断用定时器0, 1Ms 中断:void timer0(void) interrupt 1{ TL0=(0xffff-1000+2)% 0x100;TH0=(0xffff-1000+2)/0x100; //每毫秒执行一次if(DelayMs_1>0) DelayMs_1--;//大于20Ms 延时程序}函数调用void DelayMs(uint a)//延时 a 乘以1(ms)的时间。
{ DelayMs_1=a; while(DelayMs_1);}如果延时50Ms 则函数值为DelayMs(50)tips:感谢大家的阅读,本文由我司收集整编。
在用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倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
如何利用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: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--);}产生的汇编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: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: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 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 C:0x0802 7E04 MOV R6,#0x04 C:0x0804 7D74 MOV R5,#0x74 C:0x0806 7CD6 MOV R4,#0xD6C: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在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.以下为6MHZ的晶振8051的核心单片机C语言的延时1秒的延时:void delay1s(void){unsigned char h,i,j,k;for(h=3;h>0;h--)for(i=5;i>0;i--)for(j=82;j>0;j--)for(k=19;k>0;k--);}。
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开发者特别是初学者编制非常精确的延时程序有一定难度。
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倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。
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秒钟的延时。
单片机C51延时时间怎样计算?C程序中可使用不同类型的变量来进行延时设计。
经实验测试,使用unsigned char类型具有比unsigned int 更优化的代码,在使用时应该使用unsigned char作为延时变量。
以某晶振为12MHz的单片机为例,晶振为12MHz即一个机器周期为1us。
void delay__ms(void) //x,y,z位固定值,故不能接受参数{unsigned char i,j,k;for(i=x;i>0;i--)for(j=y;j>0;j--)for(k=z;k>0;k--);}【Delay_Time=[(2z+3)*y+3]*x+5】一. 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--);}应用单片机的时候,经常会遇到需要短时间延时的情况。
单片机延时计算公式单片机是一种应用广泛的微型计算机系统,它被广泛应用于嵌入式系统、电子设备等领域。
在单片机的编程过程中,经常需要进行延时操作,以控制系统的运行速度或实现特定的功能。
为了准确地控制延时时间,需要使用延时计算公式。
延时时间与单片机的时钟频率有关,通常以秒、毫秒、微秒等单位来表示。
在单片机中,时钟频率是一个基本参数,它决定了单片机每秒钟所执行的指令数。
延时计算公式可以通过时钟频率和所需延时时间来计算出延时所需的指令数。
延时计算公式的一般形式如下:延时指令数 = 延时时间× 时钟频率其中,延时指令数表示需要延时的指令数目,延时时间表示所需延时的时间,时钟频率表示单片机的时钟频率。
在实际应用中,延时时间一般以毫秒或微秒为单位。
为了方便计算,可以将延时时间转换为秒,再根据单片机的时钟频率进行计算。
假设延时时间为T秒,时钟频率为f Hz,则延时指令数可以表示为:延时指令数= T × f延时指令数一般为整数,表示需要延时的指令数目。
在单片机编程中,可以通过循环执行空操作指令或者通过定时器来实现延时操作。
通过控制循环次数或者定时器的设置,可以实现精确的延时时间。
需要注意的是,延时计算公式中的时钟频率必须与实际使用的时钟频率相一致。
在单片机编程中,时钟频率一般通过设置寄存器来进行配置。
如果延时计算公式中的时钟频率与实际使用的时钟频率不一致,将会导致延时时间的不准确。
延时计算公式在单片机编程中具有重要的作用。
通过合理地计算延时指令数,可以实现精确的延时操作,从而实现系统的稳定运行和功能的正常实现。
在实际应用中,需要根据具体的需求和系统的要求,选择合适的延时时间和时钟频率,以确保系统的性能和功能的准确性。
总结起来,单片机延时计算公式是一种根据延时时间和时钟频率来计算延时指令数的方法。
通过合理地计算延时指令数,可以实现精确的延时操作,保证系统的稳定运行和功能的正常实现。
在单片机编程中,合理地应用延时计算公式,可以提高系统的性能和功能的准确性。
单片机C语言延时计算单片机是一种集成电路芯片,内部集成了微处理器、存储器、输入输出接口等主要部件。
C语言是常用的单片机编程语言,可以通过编写C程序来实现单片机的控制和功能。
在单片机编程中,延时是一种常用的操作,用于控制程序执行过程中的时间间隔。
延时的实现方法有多种,可以使用循环遍历、定时器、外部中断等方式。
在循环遍历的延时方法中,可以通过设定一个循环次数来实现延时。
具体的延时时间与循环的次数成正比关系。
例如,在一个8位单片机中,循环一次大约需要4个机器周期,因此可以通过适当设置循环次数来达到需要的延时时间。
但是,使用循环遍历的延时方法会占用CPU资源,可能会影响其他任务的执行。
另一种常用的延时方法是使用定时器。
单片机内部通常集成了一个或多个定时器,可以通过设置定时器的初值和工作模式来实现精确的延时。
例如,可以通过设置定时器的计数值和工作频率来计算出延时的时间。
在定时器工作期间,单片机可以继续执行其他任务,不会占用过多的CPU资源。
除了循环遍历和定时器方法外,还可以使用外部中断的方式来实现延时。
具体的实现方法是通过外部信号触发中断,并在中断处理程序中实现延时功能。
这种方法可以根据外部信号的频率和工作模式来调整延时时间。
在单片机编程中,为了提高代码的可读性和可重用性,可以将延时操作封装成函数。
例如,可以定义一个名为delay的函数,函数的参数为延时的时间(单位为毫秒),函数内部通过循环遍历、定时器或外部中断的方式实现延时。
延时的时间计算可以考虑单片机的工作频率、机器周期以及延时的时间要求。
单片机的工作频率可以由时钟源来决定,一般可以通过设置分频系数来调整。
机器周期是单片机执行一条指令所需的时间,通过单片机的数据手册可以查到相关的数据。
根据单片机的工作频率和机器周期,可以计算出所需的循环次数或定时器计数值。
在使用延时功能时需要注意延时时间的准确性和可调性。
准确性是指延时的实际时间与预期时间之间的误差,通过调整循环次数或定时器计数值可以实现较高的准确性。
单片机C51延时时间怎样计算
1. 延时函数:C51中提供了一个延时函数`delay(`,可以用来实现简单的延时操作。
该函数的参数为延时的时间,单位是毫秒(ms)。
2.单片机时钟频率:C51的时钟频率一般为12MHz,即每秒钟钟脉冲个数为12,000,000次。
3.定时/计数器模块:C51中的定时/计数器模块可以用来精确控制延时时间。
其中,TMOD寄存器用来设置定时器的工作模式,THx和TLx寄存器用来设置定时器的初值。
4.定时器计数:C51的定时器工作时,会不断地进行计数。
当计数值达到设定的初值时,会触发中断或者产生一个标志位,可以利用这个特性来实现精确的延时操作。
5.延时时间计算公式:延时时间(单位:毫秒)=计数器初值*定时器计数时间/定时器时钟频率
延时时间计算的具体步骤如下:
1.确定延时所需的毫秒数。
2.确定定时器的工作模式。
3.根据定时器的工作模式,设置THx和TLx寄存器的初值。
4.根据定时器的时钟频率和计数器初值,计算延时时间。
延时函数的缺点是,它是通过循环执行一段无用指令来实现延时的,因此在延时期间无法执行其他操作,延时的精度也不够高。
如果需要精确的延时时间,可以利用定时/计数器模块来实现。
单片机延时计算
在单片机编程中,延时是一种常用的控制方法。
延时的基本原理是利用单片机内部的计时器来实现时间的计算。
以下是一个简单的延时计算程序的中文代码:
1. 定义延时时间
首先需要定义需要延时的时间,例如下面的代码定义了一个需要延时10毫秒的时间:
unsigned int delay_time = 10;
2. 计算延时时间
接下来需要编写延时计算的函数,在这个函数中需要使用单片机内部的计时器来实现时间的计算。
以51单片机为例,我们可以使用定时器和定时器中断来实现延时计算。
具体代码如下:
void delay(unsigned int time) // time为需要延时的时间(单位:毫秒)
{
unsigned char i, j;
while (time--)
{
i = 10;
j = 120;
do
{
while (--j);
} while (--i);
}
}
3. 调用延时函数
最后,在需要进行延时的地方调用延时函数即可,例如下面的代
码在执行delay函数后会延时10毫秒:
delay(delay_time);
以上就是一个简单的中文延时计算程序,希望能对你有所帮助。
单片机C语言延时分析
标准的C 语言中没有空语句。
但在单片机的C 语言编程中,经常需要用几个空指令产生短延时的效果。
这在汇编语言中很容易实现,写几个nop 就行了。
在keil C51 中,直接调用库函数:
#include // 声明了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;i255;i++);
unsigned char i;
for(i=255;i0;i--);
其中,第二个循环语句C51 编译后,就用DJNZ 指令来完成,相当于如下指令:。
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--); }参考链接:摘要实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。
用单片机C语言精确延时(定时)的方法用单片机C语言精确延时(定时)的方法C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
那么用单片机C语言精确延时(定时)的方法都是怎样的呢?以下仅供参考!由于单片机C语言下利用软件延时不容易做到精确的定时,所以很多人在编写延时子程序的时候不能好好的把握延时的具体时间。
C 语言下,延时程序主要有以下几种:一:void delay(unsigned char k){unsigned char i,k; //定义变量for(i=0;i<k;i++); //for循环语句}该程序在Keil环境下,会先将C语言转化成汇编语言,那么我们就可以根据汇编语言来计算出精确的`时间,转化具体步骤如下:CLR A ;指令1MOV R7,A ;指令2LOOP:INC R7 ;指令3CJNE R7,k,LOOP ;指令4这里,指令1,指令2和指令3各消耗1个机器周期,指令4消耗两个机器周期(可查文末附录表),而在12M的晶振下一个机器周期是1us,在这个过程中,指令1和指令2分别执行1次,即消耗1+1us,而指令3和指令4分别执行了k次,那么这样加起来,这个延时子程序所消耗的具体时间就是t=1+1+(1+2)*k=3k+2us。
呵呵,这样说来,如果我们定义的k为100的话,这个延时子程序的精确时间就是302us。
二:void delay(unsigned char i){while(--i){;}}同样的道理,将其反汇编,可以看到,只有一条语句:DJNZ i,$;该语句消耗2us,一共执行i次,所以总共消耗时间t=i*2us。
三:下面的将形参换为整形int,这样的话,反汇编所执行的语句完全不同,用个具体的数字做例子:void delay(){unsigned int i=10000;while(--i);}反汇编后:4: unsigned int i=10000;C:0x0003 7F10 MOV R7,#0x10C:0x0005 7E27 MOV R6,#0x275: while(--i)6: ;C:0x0007 EF MOV A,R7C:0x0008 1F DEC R7C:0x0009 7001 JNZ C:000CC:0x000B 1E DEC R6C:0x000C 14 DEC AC:0x000D 4E ORL A,R6C:0x000E 70F7 JNZ C:0007具体计算如下1.R7经过10H(16)次循环减为0:t1=10H*(1+1+2+1+1+2)2.R6经过27H*256次循环减为0:t2=27H*256*(1+1+2+1+1+2)+27H*13.最后R7的是变为255,因此还要多出255次的循环:t3=255*(1+1+2+1+1+2)4.加上之前消耗的2us,总消耗时间:T=2+10H*(1+1+2+1+1+2)+27H*256*(1+1+2+1+1+2)+27H*1+255*(1+1+2+1+1+2)=2+16*7+39*256*7+39*1+255*7=71826us大约为72ms吧如果定义一个unsigned int i,那么延时计算公式为T=2+(i%256)*7+(i/256)*256*7+i/256+255*7关于其他类型的延时程序都可以按照这个方法对时间进行较为精确的计算。