C51精确延时

合集下载

51单片机技巧:精确延时

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倍速的单片机,只要修改一下参数值其它系例单片机也通用,适用范围宽。

51单片机的几种精确延时

51单片机的几种精确延时
2软件延时与时间计算
在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。
2.1短暂延时
可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10μs的延时函数可编写如下:
同样对do…while,while循环语句中,也是如此
例:
unsigned char n;
n=255;
do{n--}
while(n);

n=255;
while(n)
{n--};
这两个循环语句经过C51编译之后,形成DJNZ来完成的方法,
故其精确时间的计算也很方便。
其三:对于要求精确延时时间更长,这时就要采用循环嵌套
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--};
i--;
}
这三种方法都是用DJNZ指令嵌套实现循环的,由C51编
译器用下面的指令组合来完成的
MOVR7,#0FFH
当采用while (DlyT--)循环体时,DlyT的值存放在R7中。相对应的汇编代码如下:
C:0x000FAE07MOVR6, R7//1T
C:0x00111F DECR7//1T
C:0x0012EE MOVA,R6//1T
C:0x001370FAJNZC:000F//2T

单片机C51精确延时程序的设计与实现

单片机C51精确延时程序的设计与实现

2利用K e i l C 5 1 的软件仿真调试功能实现精确延时设计
这里设计一个1 毫秒延 时函数如下 , 该函数利用循环语句实现 延时 , 修改f o r 循环结束判 断条件 的循环次数 , 然后通过K e l f 软件 仿 真测量其运行 时间 , 如此反复 修改循环 次数并仿真运行 , 最 终获得 准确的循环次数值 。 本 函数 中设置P r  ̄e c t / o p t i o n s f o r Ta r g e t 子菜单 中的晶振为
A, #0 x0 0
R5
C: 0 x 0 0 3 B C: O xO 0 3 C C: 0 x O 0 3 F C: O x 0 0 4 0 C: 0 x 0 0 4 2
CJ NE I NC S J MP RE T
R5, #0 x0 0 , C: 0 0 4 0
C: 0 x 0 0 2 6 C: 0 x 0 0 2 7 C: 0 x 0 0 2 8 C: 0 x 0 0 2 A C: 0 x 0 0 2 B C: o ) 【 o o 2 C
C: 0 x0 0 2 E C: 0 x 0 0 2 F C: 0 x 0 0 3 0 M OV
设计开发
1 1 戴 目 q j 0 术
单片机 C 5 1 精确延时程序的设计与实现
鲁杰爽
( 湖北职业技术学院 湖北孝感 4 3 2 0 0 0 )
摘要: 本文 阐述 了在单 片i  ̄ K e i l C 5 1 开发 环境 中, 利用c 5 1 语言 实现 精确延 时程序设 计的 方法, 并 实例 分析 了延 时 时间的计算 方法 。 关键 词: 单 片机 c 5 1 语 言 软件 延 时 程序 设计 中图分类号: T P 3 1 5 文 献标识 ̄ L q : A 文章 编号 : 1 0 0 7 . 9 4 1 6 ( 2 0 1 4 ) 0 9 — 0 1 7 4 一 O<r e g5 1 . h>

C51

C51

C语言的延时计算今天碰到这个问题,想想大家也可能用得上,就转过来了,希望对大家有用C51中精确的延时与计算的实现C51由于其可读性和可移植性很强,在单片机中得到广泛的应用,但在某些时候由于C51编写的程序对在有精确时间要求下,可能就得要用汇编语言来编写,但在C51是否也能实现时间的精确控制呢?答案是肯定的。

在C51中要实现对时间的精确延时有以下几种方法其一:对于延时很短的,要求在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级的延时。

51单片机C语言精确延时程序(超级准)

51单片机C语言精确延时程序(超级准)
单片机c语言单片机c语言教程pic单片机c语言教程pic单片机c语言单片机c语言指令集单片机c语言入门单片机c语言中断c语言和单片机avr单片机c语言单片机c语言编程
51单片机 C语言精确延时程序(超级准)
51单片机C语言精密延时程序 程序如下: void delayms(unsigned char t) { unsigned char j; unsigned char i; do { j=3; do { i=165; do { --i; } while(i!=0); --j; } while(j!=0); --t; } while(t!=0); } 该程序延时时基为1ms,所以最大延时时间是255ms 下面是反编译的汇编程序 C:0x0031 7E03 MOV R6,#0x03 C:0x0033 7DA5 MOV R5,#0xA5 C:0x0035 DDFE DJNZ R5,C:0035 C:0x0037 DEFA DJNZ R6,C:0033 C:0x0039 DFF6 DJNZ R7,delayms(C:0031) C:0x003B 22 RET 延时时间计算公式如下: ((R5*2 + 2+1)*R6+2+1)R7
假设R7=1,上式为(165*2+3)*3+2+1 =1002us!!!!! 以上程序使用的晶振是12MHz,如果使用的是其他频率的晶振只需计算出1ms的机器周期 数,代入5*2 + 2+1)*R6+2+1,选择合适的R

while(--n)延时计算详解

while(--n)延时计算详解

C51中精确的延时与计算的实现(转载)2011-12-29 13:44:39| 分类:每天一学|举报|字号订阅C51由于其可读性和可移植性很强,在单片机中得到广泛的应用,但在某些时候由于C51编写的程序对在有精确时间要求下,可能就得要用汇编语言来编写,但在C51是否也能实现时间的精确控制呢?答案是肯定的。

在C51中要实现对时间的精确延时有以下几种方法其一:对于延时很短的,要求在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级的延时。

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

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

C程序中可‎使用不同类‎型的变量来‎进行延时设‎计。

经实验测试‎,使用uns‎i gned‎ char类‎型具有比u‎n sign‎e d int更优‎化的代码,在使用时应‎该使用un‎si gne‎d char作‎为延时变量‎。

以某晶振为‎12MHz‎的单片机为‎例,晶振为12‎MH z即一‎个机器周期‎为1us。

一. 500ms‎延时子程序‎程序:void delay‎500ms‎(void){unsig‎n 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 = 162us‎DJNZ 2us二层循环m‎:R6*(n+3) = 202*165 = 33330‎u s DJNZ 2us + R5赋值1us = 3us三层循环: R7*(m+3) = 15*33333‎= 49999‎5us DJNZ 2us + R6赋值1us = 3us循环外: 5us 子程序调用‎ 2us + 子程序返回‎ 2us + R7赋值1us = 5us延时总时间‎ =三层循环+ 循环外= 49999‎5+5 = 50000‎0us =500ms‎计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5二. 200ms‎延时子程序‎程序:void delay‎200ms‎(void){unsig‎n 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 delay‎10ms(void){unsig‎n 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 delay‎1s(void){unsig‎n 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摘要实际的单片‎机应用系统‎开发过程中‎,由于程序功‎能的需要,经常编写各‎种延时程序‎,延时时间从‎数微秒到数‎秒不等,对于许多C‎51开发者‎特别是初学‎者编制非常‎精确的延时‎程序有一定‎难度。

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

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

Keil C51精确延时程序程序说明如下:振荡频率:12MHz机器周期=12/振荡频率=12/12000000=1us#include <reg52.h>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=25usdelay2(10); //赋值并调延时程序delay2说明:本句为赋值并调用Delayus2:延时时间=(1+2)*机器周期。

全部延时时间为:延时时间=(1+2+6*i+2)*机器周期。

i=1~255。

本例:延时时间=(1+2+6*10+2)*1us=65usm=10; //赋值,m=1~255while(--m) ; //计算,延时时间=2*m*机器周期说明:本两句为赋值并计算。

全部延时时间为:延时时间=(1+2*m)*机器周期。

m=1~255。

本例:延时时间=(1+2*10)*1us=25uswhile(1);}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C51中实现精确延时是编程中的重要环节。由于C语言实时性较差,需要通过特定技巧来达到精确延时的目的。本文介绍了使用for循环结构来编写延时子程序的方法,通过嵌套循环来控制延时时间。具体实例包括50Байду номын сангаасms、200ms、10ms和1s的延时子程序,每个程序都详细列出了循环变量和循环次数的设定,以及对应的汇编代码。这些实例可以帮助初学者更好地理解延时函数的实现原理。此外,还提到了使用_nop_指令来进行更精确的延时控制,这是一种利用内嵌汇编指令来实现微秒级延时的方法。总之,本文提供了C51中实现精确延时的多种方法和实例,有助于读者在实际编程中灵活应用。
相关文档
最新文档