您的位置 首页 被动

在进行C51程序设计时怎么准确延时的常见办法介绍

单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域。单片机开发者在编制各种应用程序时经常会遇到实现精确…

单片机因具有体积小、功用强、成本低以及便于完结分布式控制而有十分广泛的运用领域。单片机开发者在编制各种运用程序时经常会遇到完结准确延时的问题,比方按键去抖、数据传输等操作都要在程序中刺进一段或几段延时,时刻从几十微秒到几秒。有时还要求有很高的精度,如运用单总线芯片DS18B20时,答应差错范围在十几微秒以内,不然,芯片无法作业。为此我特意的将如安在C51程序中准确延时进行了一个小结。

用51汇编言语写程序时,这种问题很简略得到解决,而现在开发嵌入式体系软件的干流东西为C言语,因而很有必要了解用C51写延时程序时需求的一些技巧。

完结延时一般有两种办法:

一种是硬件延时,要用到守时器/计数器,这种办法能够进步CPU的作业功率,也能做到准确延时;

一种是软件延时,这种办法首要选用循环体进行。

1 运用守时器/计数器完结准确延时

单片机体系一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。榜首种更简略发生各种规范的波特率,后两种的一个机器周期别离为1 μs和2 μs,便于准确延时。假定运用频率为12 MHz的晶振。最长的延时时刻可达2^16=65 536 μs。若守时器作业在办法2,则可完结极短时刻的准确延时;如运用其他守时办法,则要考虑重装守时初值的时刻(重装守时器初值占用2个机器周期)。

在实践运用中,守经常选用中止办法,如进行恰当的循环可完结几秒乃至更长时刻的延时。运用守时器/计数器延时从程序的履行功率和稳定性两方面考虑都是最佳的计划。但应该留意,C51编写的中止服务程序编译后会主动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC句子,履行时占用了4个机器周期;如程序中还有计数值加1句子,则又会占用1个机器周期。这些句子所耗费的时刻在核算守时初值时要考虑进去,从初值中减去以到达最小差错的意图。

2 软件延时与时刻核算

  在许多情况下,守时器/计数器经常被用作其他用处,这时分就只能用软件办法延时。下面介绍几种软件延时的办法。

2.1 时刻短延时

能够在C文件中经过运用带_NOP_( )句子的函数完结,界说一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自界说的C文件中,需求时在主程序中直接调用。如延时10 μs的延时函数可编写如下:

void Delay_10us()

{

_NOP();

_NOP();

_NOP();

_NOP();

_NOP();

_NOP();

}

Delay_10us( )函数中共用了6个_NOP_( )句子,每个句子履行时刻为1 μs。主函数调用Delay_10us( )时,先履行一个LCALL指令(2 μs),然后履行6个_NOP_( )句子(6 μs),最终履行了一个RET指令(2 μs),所以履行上述函数时共需求10 μs。

 能够把这一函数当作根本延时函数,在其他函数中调用,即嵌套调用延时函数,以完结较长时刻的延时;但需求留意,如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时刻将是42 μs,而不是40 μs。这是由于履行Delay40us( )时,先履行了一次LCALL指令(2 μs),然后开端履行榜首个Delay10us( ),履行完最终一个Delay10us( )时,直接回来到主程序。依此类推,假如是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),则也要先履行一次LCALL指令(2 μs),然后履行两次Delay40us( )函数(84 μs),所以,实践延时时刻为86 μs。简言之,只要最内层的函数履行RET指令。该指令直接回来到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),此刻的延时时刻为82 μs。经过修正根本延时函数和恰当的组合调用,上述办法能够完结不一起刻的延时。

关于_NOP()函数,信任有不少人会感到疑问,这儿我就具体的介绍一下_NOP();函数:

_NOP();函数是用来发生空指令来进行延时的,在汇编言语中写几个nop指令就能够到达延时的作用。

留意:

1、 调用库函数是一定要包括头文件#include,在该库中声明晰void _NOP(void);

2、 这个函数适当汇编NOP指令,延时几微秒。NOP指令为单周期指令,可由晶振频率算出延时时刻,关于12M晶振,延时1uS。

关于C51的延时函数要留意:

求在大于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,#0FFH
LOOP: DJNZ 09H,LOOP
指令适当简练,也很好核算准确的延时时刻。

已然能用高档言语进行延时,当然也能用最根本的汇编言语进行相关的延时,下面咱们来简略的了解下(注:关于汇编言语我也只略懂一点,这是我在网上相关的材料学习到的):

在C51中经过预处理指令#pragma asm和#pragma endasm能够嵌套汇编言句子子。用户编写的汇编言语紧跟在#pragma asm之后,在#pragma endasm之前完毕。

如: #pragma asm
    …
    汇编言语程序段
    …
    #pragma endasm

延时函数可设置进口参数,可将参数界说为unsigned char、int或long型。依据参数与回来值的传递规矩,这时参数和函数回来值坐落R7、R7R6、R7R6R5中。在运用时应留意以下几点:

◆ #pragma asm、#pragma endasm不答应嵌套运用;
  ◆ 在程序的最初应加上预处理指令#pragma asm,在该指令之前只能有注释或其他预处理指令;

◆ 当运用asm句子时,编译体系并不输出方针模块,而只输出汇编源文件;

  ◆ asm只能用小写字母,假如把asm写成大写,编译体系就把它作为一般变量;
  ◆ #pragma asm、#pragma endasm和 asm只能在函数内运用。

2.3 运用示波器确认延时时刻

了解硬件的开发人员,也能够运用示波器来测定延时程序履行时刻。办法如下:编写一个完结延时的函数,在该函数的开端置某个I/O口线如P1.0为高电平,在函数的最终清P1.0为低电平。在主程序中循环调用该延时函数,经过示波器丈量P1.0引脚上的高电平时刻即可确认延时函数的履行时刻。(有条件的哥们能够试试)

2.4 运用Keil_C中的功用剖析器核算延时时刻:

这儿我就具体介绍下,这是很有用的办法:

咱们先在Keil_C中敲入如下代码:

#include

#define uint unsigned int

sbit led=P1^0;

main()

{

uint i,j,x,y,k,n,m;

while(1)

{

led=0;

for(i=1000;i>0;i–)//延时1

for(j=110;j>0;j–);

led=1;

for(x=0;x<500;x++)//延时2

for(y=0;y<130;y++);

led=0;

for(n=500;n>0;n–)//延时3

for(m=114;m>0;m–);

led=1;

k=90;//延时4

while(k>0)k–;

led=0;

}

}

下面将介绍怎么树立Keil工程,并剖析延时时刻的准确核算办法,运用keil能够比较便利、准确的核算程序延时时刻。

1. 树立keil工程。

发动keil,挑选“Project”à“New uVision Project”à输入工程称号,确认,弹出下面对话框,挑选Atmel:

接着挑选:AT89C52

挑选好芯片之后会弹出下面的对话框,挑选“否”:

点击“File”à “New”,新建一个Text,用以输入程序。程序输入今后保存,保存称号需求和工程称号共同,假如运用C言语则以.c作为保存格局,运用汇编言语保存格局为.asm。保存之后如图:

下一步便是把方才保存的.c程序导入到工程中。选中上图中左上角的“Source Group 1”,单击右键,挑选“Add Files to Group Source Group 1..”,在弹出的对话框挑选方才保存的.c文件,Add,即完结导入。

下面这一步设置关于运用keil准确核算延时时刻很要害。选中下图左上角的Target 1:

单击右键,挑选“Options for Target Target 1..”,弹出下面对话框,把Xtal(Mhz)的24.0修正成当时运用的晶振频率,这儿改为11.0592Mhz。

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232351900.png” title=”图片6.png” alt=”232351900.png” />

假如还要生成.hex文件用于下载到芯片上,能够挑选“Output”,钩选“Creat HEX File”选项,如下:

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232456128.png” title=”图片7.png” alt=”232456128.png” />

这样就树立好了一个keil工程。经过程序调试,“Save”,“Build”,生成.hex文件,下载到芯片就能够直接运用了。

1. 接着讲第二个知识点,便是怎么准确核算延时的时刻。

咱们挑选最初给出的程序为例,延时1的程序如下:

for(i=1000;i>0;i–)//延时1

for(j=110;j>0;j–);

要准确核算它的延时时刻,能够经过设置断点来完结。断点设置如下图:

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232538186.png” title=”图片8.png” alt=”232538186.png” />

在延时1的最初和下一句句子的最初别离设置断点A1和A2,然后全速运转,运转到A1处,程序中止,记载这时的运转时刻t1,持续全速运转,遇到断点A2,程序中止,记载此刻的时刻t2。那么延时1的延时时刻便是t=t2-t1。

下面是具体过程:

(1) 设置断点。如上图所示,在程序最初的数字处双击左键,就会呈现一个赤色的点,这便是断点。假如要消去断点,相同能够双击断点。

(2) 进入调试形式。单击窗口上的调试按键方便图标:

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232623936.png” title=”图片9.png” alt=”232623936.png” />

即可进入调试形式。初度进入调试形式的界面如下:

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232724504.png” title=”图片10.png” alt=”232724504.png” />

首要介绍一下几个重要按钮。如下图所示:

赤色数字1上面的图标:将程序复位到主函数的最开开端处,预备从头运转程序;

赤色数字2上面的图标:全速运转,运转程序时中心不中止,直到遇到断点;

赤色数字3上面的图标:中止全速运转。

赤色数字4上面的图标:进入子函数内部。

赤色下划线上的sec便是程序从开端运转到当时中止场所用的时刻。

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232800342.png” title=”图片11.png” alt=”232800342.png” />

(3) 先复位。即点击上图中红字1上面的图标。

(4) 全速运转,记载运转时刻。即点击上图红字2上面的图标。遇到09处的榜首个断点,体系会主动中止运转,停在榜首个断点处。此刻右边记载的时刻sec便是程序从开端运转到当时断点场所阅历的时刻为t1=423.18us。如下图所示:

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/232912391.png” title=”图片12.png” alt=”232912391.png” />

(5) 持续全速运转,第2次记载运转时刻。遇到11处的第二个断点,体系中止运转,此刻已运转时刻为t2=966140.41us。如下图所示:

650) this.width=650;” src=”http://img1.51cto.com/attachment/201310/233003522.png” title=”图片13.png” alt=”233003522.png” />

(6) 核算延时时刻t。从上面得到的数据能够核算出时刻

t= t2-t1= 966140.41us- 423.18us= 965717.23us= 965.71723ms。

经过上面6个过程,就能够准确,便利地核算出延时程序的时刻,关于完结准确延时,只需求调理参数,再稍加核算就OK。需求留意的是,在上图的调试形式下修正程序参数,是无法收效的。复位之后全速运转,显现的十间仍然是修正之前的参数在起作用。所以假如修正程序参数,需求到修正形式下,从头下载,然后再进入调试形式,才能够核算准确时刻。一起,在树立Keil工程的时分,一定要记住修正晶振的参数,这很要害,假如晶振不对,要完结相同的延时时刻,程序参数的设置也就不一样。

能够运用相同的办法核算延时2,延时3,延时4的准确延时时刻。它们的延时时刻别离是:498040.37us、500220.27us、783.42us。我们能够自己操练。

最终还要指出一点的是:

上面运用的Keil版本是Keil uVision4,我们也能够运用Keil 3或许Keil 2来做,仅仅软件的界面,图标等有不同,但都能够完结相同的功用。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/beidong/319816.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部