单片机怎样实现微秒级延迟

单片机怎样实现微秒级延迟,第1张

  对于某些对时间精度要求较高的程序,用c写延时显得有些力不从心,故需用到汇编程序。至于如何在c中嵌入汇编大家可以去网上查查,这方面的资料很多,且很简单。以12MHz晶振为例,12MHz晶振的机器周期为1us,所以,执行一条单周期指令所用时间就是1us,如NOP指令。下面具体阐述一下。

  1.若要延时1us,则可以调用_nop_();函数,此函数是一个c函数,其相当于一个NOP指令,使用时必须包含头文件“intrins.h”。例如:

  #include《intrins.h》

  #include《reg52.h》

  voidmain(void){

  P1=0x0;

  _nop_();//延时1us

  P1=0xff;

  }

  2.延时5us,则可以写一个delay_5us()函数:

  delay_5us(){

  #pragmaasm

  nop

  #pragma endasm

  }

  这就是一个延时5us的函数,只需要在需要延时5us时调用此函数即可。或许有人会问,只有一个NOP指令,怎么是延时5us呢?

  答案是:在调用此函数时,需要一个调用指令,此指令消耗2个周期(即2us);函数执行完毕时要返回主调函数,需要一个返回指令,此指令消耗2个周期(2us)。调用和返回消耗了2us+2us=4us。然后再加上一个NOP指令消耗1us,不就是5us吗。

  3.延时10us。我们编写一个delay_10us()函数:

  delay_10us(){

  #pragma asm

  nop

  nop

  nop

  nop

  nop

  nop

  #pragma endasm

  }

  这就是延时10us的函数。同延时5us函数一样,调用和返回消耗4us,加上函数中的6个NOP指令6us,正好是10us。

  此时有人不禁要问那么,任意微秒时,函数应该怎么写呢?

  首先,延时任意微秒我暂时没有想到,但是,我可以延时任意偶数微秒或延时任意奇数微秒,也就是说,需要两个函数,一个函数专门实现任意偶数的微秒级延时,另一个函数专门实现任意奇数的微秒级延时。只要有了这两个函数在,不就可以延时任意的微秒了吗!

  首先我们来实现任意偶数的微秒级延时:

  voiddelay_even_us(unsignedchareven){ //任意偶数的微秒级延时

  #pragmaasm

  1 mova,r7 //为什么要用到r7呢,因为r7里面装的是函数的参数!!!//^_^这句消耗1个周期

  2 subb a,#10H//这句看完程序我再解释这句消耗1个周期

  3 movb,#02H//这句看完程序我再解释这句消耗2个周期

  4 divab//这句意思是a/b,商放在a里,余数放在b里稍 //后解释这句消耗4个周期

  5 movr0,a //这句消耗1个周期

  6 nop //这句消耗1个周期

  7 loop:

  8 djnz r0,loop //不等于0跳转指令,也就是说r0中的值若不为0的话,

  //就跳转到loop处这句消耗2个周期

  #pragmaendasm

  }

  如下程序能实现ms毫秒级的比较精确的延时

  void Delayms(unsigned int n)

  {

  unsigned int i,j;

  for(j=n;j》0;j--)

  for(i=112;i》0;i--);

  }

  用keil可以看出这个延时的时间,我们先延时1ms(Delayms(1))。

  进入Delayms前,sec=0.00042209s

  延时后,sec=0.00142253s

  可以知道Delayms(1)实际延时0.00142253s—0.00042209s=0.00100044s≈1ms

  同样如果想延时15ms的话,用Delayms(15),实际延时0.01480903s≈15ms,延时还是挺精确的。

  也可以用_nop_( )函数来实现微秒级的延时。

  1_nop_(); // 直接当成一条语句使用,产生一条NOP指令

  NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。

  注:使用该函数时,需要将头文件#include《intrins.h》包含进源文件中。

  任意奇数的微秒级延时:

  voiddelay_odd_us(unsignedcharodd){

  #pragmaasm

  1 mova,r7

  2 subba,#0fH

  3 movb,#02H

  4 div ab

  5 mov r0,a

  6 loop1:

  7 djnz r0,loop1

  #pragmaendasm

  }

  此即为任意奇数微秒的延时,和偶数延时一样的道理

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/dianzi/2717218.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-17
下一篇 2022-08-17

发表评论

登录后才能评论

评论列表(0条)

保存