C语言中的延时与计时技巧

C语言中的延时与计时技巧
C语言中的延时与计时技巧

C语言中的延时与计时技巧

一、延时技巧

1.延时的定义:控制程序中当前语句的后一语句,延缓一段时间再执行。

2.C常用的两个延时函数:

(1) delay函数。

书写格式:delay(数值)。其中,括号中的整型数值取值范围0 ~ 32767之间。

注意:这个数值与计算机主机的频率有关,因此在不同的计算机上,同样的延时数值,会得到不同的延时效果。

(2) sleep (数值)。(睡眠函数)

书写格式:sleep (数值)。其中数值是以秒为单位,用在动态显示中最少一秒变化一次,那会有明显的停顿感觉。

二、计时技巧

1.计时的定义:计算程序中某段程序的运行时间。

2.计时程序使用条件:

(1)使用头部文件:

#include

(2)使用当前时间的时钟函数:

clock()

(3)使用时间一秒常数:

CLK_TCK

例如:

A.在“蛇吃蛋”的程序中,要引入计时程序,则:在进入while(1)循环前,先要取得计时开始时的那一时刻,使用变量t0表示。即:

t0 = clock();

B.在while(1)循环的最后处,再取当前时刻,使用变量t1表示。即:

t1=clock();

C.t1 和t0 之差即为所经历的时间,即;

t = (t1-t0 );

D.转换成秒:

sec=t/CLK_TCK;

C语言延时程序

C51精确延时程序 一、、看了网上延时程序的帖子挺多,我也说点。 用keil调试, void yanshi( uint n ) { uchar data i="0"; for(i=0;i<N;I++); return; } 延时时间=12*(n*12+17)/fosc 用keil测时功能很容易得到这个关系,很精确,偏差不过几us. 可以自己编一些延时程序,也可以很方便的得到关系式,只是系数不同. 二、、//我看到的地方也是从别的地方转贴,所以我不知道原作者是谁,但相信这么成熟的东西转一下他也不会见意。看到了个好帖,我在此在它得基础上再抛抛砖! 有个好帖,从精度考虑,它得研究结果是: void delay2(unsigned char i) { while(--i); } 为最佳方法。 分析:假设外挂12M(之后都是在这基础上讨论) 我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据: delay2(0):延时518us 518-2*256=6 delay2(1):延时7us(原帖写“5us”是错的,^_^) delay2(10):延时25us 25-20=5 delay2(20):延时45us 45-40=5 delay2(100):延时205us 205-200=5 delay2(200):延时405us 405-400=5 见上可得可调度为2us,而最大误差为6us。 精度是很高了! 但这个程序的最大延时是为518us 显然不 能满足实际需要,因为很多时候需要延迟比较长的时间。 那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。

用C语言实现精确的延时

怎么用C语言做单片机的精确延时在单片机应用中,经常会遇到需要短时间延时的情况,一般都是几十到几百μs,并且需要很高的精度(比如用单片机驱动DS18B20时,误差容许的范围在十几μs以内,不然很容易出错);而某些情况下延时时间较长,用计时器往往有点小题大做。另外在特殊情况下,计时器甚至已经全部用于其他方面的定时处理,此时就只能使用软件定时了[1]。 1C语言程序延时 Keil C51的编程语言常用的有2种:一种是汇编语言;另一种是C语言。用汇编语言写单片机程序时,精确时间延时是相对容易解决的。比如,用的是晶振频率为12MHz 的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程序代码。 延时函数: void delay1(unsigned char i){ while(i);} 主函数: void main(){ while(1){ delay1(i); } } 使用Keil C51的反汇编功能,延时函数的汇编代码如下: C:0x00E6AE07MOVR6,0x07 C:0x00E81FDECR7 C:0x00E9EEMOVA,R6 C:0x00EA70FAJNZC:00E6 C:0x00EC22RET 图1断点设置位置图 通过对i赋值为10,在主程序中图1所示的位置设置断点。经过测试,第1次执行到断点处的时间为457μs,再次执行到该处的时间为531μs,第3次执行到断点处的时间为605μs,10次while循环的时间为74μs,整个测试结果如图2所示。 图2使用i--方式测试仿真结果图 通过对汇编代码分析,时间延迟t=7X+4(其中X为i的取值)。测试表明,for循环方式虽然生成的代码与用while语句不大一样,但是这两种方法的效率几乎相同。C语言中的自减方式有两种,前面都使用的是i--的方式,能不能使用--i方式来获得不同的效果呢?将前面的主函数保持不变,delay1函数修改为下面的方式:void delay1(unsigned char i){ while(--i);} 同样进行反汇编,得到如下结果: C:0x00E3DFFEDJNZR7, C:00E3C:0x00E522RET 比较发现,--i的汇编代码效率明显高于i--方式。由于只有1条语句DJNZ,执行只需要2个时钟周期,1个时钟周期按1μs计算,其延时精度为2μs;另外,RET

STC12系列单片机C语言的延时程序

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:感谢大家的阅读,本文由我司收集整编。仅供参阅!

TMS320F2812delay 延时完整程序

TMS320F2812的延时程序(完整) .def _DSP28x_usDelay ;==================================================== ;Delay Function ;The C assembly call will look as follows: ; ; extern void Delay(long time); ; MOV AL,#LowLoopCount ; MOV AH,#HighLoopCount ; LCR _Delay ; ;Or as follows (if count is less then 16-bits): ; ; MOV ACC,#LoopCount ; LCR _Delay .global __DSP28x_usDelay _DSP28x_usDelay: SUB ACC,#1 NOP NOP BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0 LRETR ;There is a 9/10 cycle overhead and each loop ;takes five cycles. The LoopCount is given by ;the following formula: ; DELAY_CPU_CYLES = 9 + 5*LoopCount ; LoopCount = (DELAY_CPU_CYCLES - 9) / 5 ;================================================== --

RE:我是这么调用的(C语言) extern void DSP28x_usDelay(long time); 在需要延时的地方加入 DSP28x_usDelay(0x100000);//根据延迟时间写入参数

STM32延时函数

#include #include "delay.h" ////////////////////////////////////////////////////////////////////////////////// //使用SysTick的普通计数模式对延迟进行管理 //包括delay_us,delay_ms //***************************************************************************** *** //V1.2修改说明 //修正了中断中调用出现死循环的错误 //防止延时不准确,采用do while结构! ////////////////////////////////////////////////////////////////////////////////// static u8 fac_us=0;//us延时倍乘数 static u16 fac_ms=0;//ms延时倍乘数 //初始化延迟函数 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟 void delay_init(u8 SYSCLK) { SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟HCLK/8 fac_us=SYSCLK/8; fac_ms=(u16)fac_us*1000; } //延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对72M条件下,nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL=0x01 ; //开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nus //nus为要延时的us数.

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_( );

单片机C 延时时间怎样计算

C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时 应该使用unsigned char作为延时变量。以某晶振为12MHz的单片 机为例,晶振为12M H z即一个机器周期为1u s。一. 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--);

c语言中的精确延时程序举例

c语言中的精确延时程序举例 我在网上到看了一些关于延时的讨论,其中有篇文章51单片机Keil C 延时程序的简单研究,作者:InfiniteSpace Studio/isjfk 写得不错,他是用while(--i);产生DJNZ 来实现精确延时,后来有人说如果while里面不能放其它语句,否则也不行,用do-while就可以,具体怎样我没有去试.所有这些都没有给出具体的实例程序来.还看到一些延时的例子多多少少总有点 延时差.为此我用for循环写了几个延时的子程序贴上来,希望能对初学者有所帮助.(晶振12 MHz,一个机器周期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,#0x0F C:0x0802 7ECA MOV R6,#0xCA 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 二层循环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语言中nop函数的使用方法和延时计算

单片机c语言中nop函数的使用方法和延时计算 标准的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;i<255;i++); unsigned char I; for(i=255;i>0;i--); 其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令: MOV09H,#0FFH LOOP:DJNZ09H,LOOP 指令相当简洁,也很好计算精确的延时时间。 同样对do…while,while循环语句中,也是如此 例: unsigned char n; n=255; do{n--}

单片机几个典型延时函数

软件延时:(asm) 晶振12MHZ,延时1秒 程序如下: DELAY:MOV 72H,#100 LOOP3:MOV 71H,#100 LOOP1:MOV 70H,#47 LOOP0:DJNZ 70H,LOOP0 NOP DJNZ 71H,LOOP1 MOV 70H,#46 LOOP2:DJNZ 70H,LOOP2 NOP DJNZ 72H,LOOP3 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秒DELAY:CLR EX0 MOV TMOD,#01H ;设置定时器的工作方式为方式1 MOV TL0,#0B0H ;给定时器设置计数初始值 MOV TH0,#3CH SETB TR0 ;开启定时器 HERE:JBC TF0,NEXT1 SJMP HERE NEXT1:MOV TL0,#0B0H MOV TH0,#3CH DJNZ R7,HERE CLR TR0 ;定时器要软件清零 SETB EX0 RET

C语言延时程序: 10ms延时子程序(12MHZ)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延时子程序(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--); }

Keil C51精确延时程序(C语言)

Keil C51精确延时程序 程序说明如下: 振荡频率:12MHz 机器周期=12/振荡频率=12/12000000=1us #include void delay1(unsigned char i) { while(--i); } 说明:delay1程序为:延时时间=(2*i+2)*机器周期。 i=1~255。 void delay2(unsigned char i) { while(i--); } 说明:delay2程序为:延时时间=(6*i+2)*机器周期。 i=1~255。 void main (void) { unsigned char m; delay1(10); //赋值并调延时程序delay1 说明:本句为赋值并调用Delayus1:延时时间=(1+2)*机器周期。 全部延时时间为:延时时间=(1+2+2*i+2)*机器周期。 i=1~255。 本例:延时时间=(1+2+2*10+2)*1us=25us delay2(10); //赋值并调延时程序delay2 说明:本句为赋值并调用Delayus2:延时时间=(1+2)*机器周期。 全部延时时间为:延时时间=(1+2+6*i+2)*机器周期。 i=1~255。 本例:延时时间=(1+2+6*10+2)*1us=65us m=10; //赋值,m=1~255 while(--m) ; //计算,延时时间=2*m*机器周期 说明:本两句为赋值并计算。 全部延时时间为:延时时间=(1+2*m)*机器周期。 m=1~255。 本例:延时时间=(1+2*10)*1us=25us while(1); }

单片机C语言延时程序

单片机C语言延时程序 我的资料 2009-07-25 06:50 阅读211 评论0 字号:大中小 用C语言写出来程序非常的简练,它是一种模块化的语言,一种比汇编更高级的语言,但是就是这样一种语言也还是有它不足之处:它的延时很不好控制,我们常常很难知道一段延时程序它的精确延时到底是多少,这和汇编延时程序没法比。但有时后写程序又不得不要用到比较精确的延时,虽然说可以用混合编程的方式解决,但这种方式不是每个人都能掌握,且写起来也麻烦。所以,通过测试我给大家提供一个延时子程序模块,并以此给一个出我们经常用到的延时的数据表格。(注意:表格中的数据只适合我的延时模块,对其他的延时程序不适用,切忌!!!!!!!!别到时候延时不对来骂我) 延时模块:其中问号代表要填的数,要延时多少,到表格中去找数据,然后填上就OK!切忌3条FOR语句不能颠倒顺序 void Delay() { unsigned char a,b,c; for(a=0;a

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:0x0800 7F0F MOV R7,#0x0F C:0x0802 7ECA MOV R6,#0xCA 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 二层循环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,#0xD6 C:0x0808 DCFE DJNZ R4,C:0808 C:0x080A DDFA DJNZ R5,C:0806 C:0x080C DEF6 DJNZ R6,C:0804 C:0x080E DFF2 DJNZ R7,C:0802 C:0x0810 22 RET 在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.

AVR单片机常用的延时函数

AVR单片机常用的延时函数 /******************************************************************** *******/ //C header files:Delay function for AVR //MCU:ATmega8 or 16 or 32 //Version: 1.0beta //The author: /******************************************************************** *******/ #include void delay8RC_us(unsigned int time) //8Mhz内部RC震荡延时Xus { do { time--; } while(time>1); } void delay8RC_ms(unsigned int time) //8Mhz内部RC震荡延时Xms { while(time!=0) { delay8RC_us(1000); time--; } } /******************************************************************** **********/ void delay1M_1ms(void) //1Mhz延时1ms { unsigned char a,b,c; for(c=1;c>0;c--) for(b=142;b>0;b--) for(a=2;a>0;a--); } void delay1M_xms(unsigned int x) //1Mhz延时xms { unsigned int i; for(i=0;i

c语言延时语句

C语言程序延时 Keil C51的编程语言常用的有2种:一种是汇编语言;另一种是C 语言。用汇编语言写单片机程序时,精确时间延时是相对容易解决的。比如,用的是晶振频率为12 MHz的AT 89C51,打算延时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程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。 有人说如果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--); } 计算分析: 程序共有三层循环 一层循环n:R5*2 = 81*2 = 162us DJNZ 2us 二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us

CVAVR 软件中启动delay库,调用delay_ms()函数,自动带了喂狗程序

CV A VR 软件中启动delay.h库,调用delay_ms()函数,自动带了喂狗程序 近期在学习中发现个问题,CV A VR 中启动delay.h库,调用delay_ms()函数延时,系统怎么都不复位重启,即使打开看门狗熔丝位,看门狗也不会重启,找了很久原因,发现是调用调用系统自身带的delay_ms()函数引起的,换成自己的简单延时函数,问题就解决,看门狗可以正常工作,后面附带我自己写的简单延时函数。 后来查找问题,发现系统中的delay_ms()函数自带了喂狗程序,所以不会自动的重启,请大家放心使用,用延时函数看门狗不溢出是正常的。后面附带软件编辑后生产的汇编程序,一看就知道确实带了喂狗。 今天写出来供大家注意,不要犯我同样的问题。 /***************************************************** This program was produced by the CodeWizardA VR V1.25.9 Standard Chip type : A Tmega8L Program type : Application Clock frequency : 1.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include #include // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T

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;i<255;i++); unsigned char I; for(i=255;i>0;i--); 其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令: MOV09H,#0FFH LOOP:DJNZ09H,LOOP 指令相当简洁,也很好计算精确的延时时间。 同样对do…while,while循环语句中,也是如此 例: unsigned char n; n=255; do{n--} while(n); 或 n=255; while(n) {n--}; 这两个循环语句经过C51编译之后,形成DJNZ来完成的方法, 故其精确时间的计算也很方便。

通用C语言延时

通用C语言延时 在嵌入式C编程中,免不了要用到软件延时。这一般通过循环语句实现。通过控制循环语句的循环次数,便可获得多种不同的延时时间。为了便于使用和提高程序代码的复用率,一般又将循环语句封装成一个带参数的函数,称为延时函数。如: void wait(unsigned int n) { unsigned int i; for(i=0;i

PIC16系列的C语言延时子程序

PIC16系列的C语言延时子程序 //******************************************** // 主芯片采用PIC16F630;4M晶振。 // us级延时3个,使用固定延时方式,分别是: // Delay_1us(); // Delay_10us(); // Delay_100us(); // 精确度为100% // ms级延时1个,使用填值方式,可以任意写入值 // Delay_1ms(1~10000); // 固定误差:+24us // 此文由lishenglin24于2011.8.13编写,经仿真验证。 //******************************************** #define Delay_1us() asm("nop") //******************************************** #define Delay_10us() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop") //******************************************** void Delay_100us() { Delay_10us(); //1 Delay_10us(); //2 Delay_10us(); //3 Delay_10us(); //4 Delay_10us(); //5 Delay_10us(); //6 Delay_10us(); //7 Delay_10us(); //8 Delay_10us(); //9 Delay_1us(); //6us Delay_1us(); Delay_1us(); Delay_1us(); Delay_1us(); Delay_1us(); } //******************************************* void Delay_ms(unsigned int ms) { unsigned int j; for(j=ms;j>0;j--) {

相关文档
最新文档