微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > ARM技术讨论 > ARM精密延时子程序设计

ARM精密延时子程序设计

时间:10-02 整理:3721RD 点击:

大家好!今天分享一个有趣儿的实用程序。
我的MCU的时钟频率是12MHz,时钟周期是1/12=0.083333us。
这种12MHz时钟情况下,要实现一个1us为单位的延时子程序,又要求比较准确,不是一件容易事儿。 您如果是使用几十~100MHz以上的高速MCU,就不要往下看了。
首先测试了for循环,不成功,最小时延1.8us,做不到1us,而且2,3,4,5us的误差都比较大。
后用inline __asm volatile ("nop")测试,可以实现,重复一次加多50ns。
最后,搞成了这个样子:
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
  __asm volatile ("nop");
}
//-----uS delay ( >=1us)---------------
void vDelayUS(uint32_t u32DelayUS)
{
     volatile uint32_t i;

if (u32DelayUS <= 15)
{
     switch(u32DelayUS)
  {
   case 1:
       __NOP();
       __NOP();
       __NOP();
       return;
   
   case 2:
       i = 3;
       __NOP();
       break;
   case 3:
       i = 6;
       __NOP();
       __NOP();
       __NOP();
       break;
   case 4:
       i = 10;
       __NOP();
       __NOP();
       break;
   default:
       i = (u32DelayUS - 2) << 2;
       i++;
       i++;
  }
loop: if (--i > 0) goto loop;
  return;
}
    // >=16us
    u32DelayUS = (13260 * u32DelayUS) >> 12;
    for (i = 0;  i < u32DelayUS; i++) {}
}
注意,
1. ARM编译器的优化处理会对定时产生极大的影响,使用时必须用示波器测试调整。
2. 微秒级别的延时,运行时不允许有中断事件发生,要关闭所有中断。
3. 上面这个程序,适合1000uS以下使用。mS延时程序,有太多选择了。
4. 调整测试,1,2,3,4,5,15,16us, 1000us都需要单独调整,或者兼顾调整。
下面这个是测试用的,也可以单独使用:
//-----delay 1us-----------------------
void vDelay1us(void)
{
volatile uint32_t i=0;
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
请大家多提宝贵意见。

简单了解一下   毕竟不会

顶一个~~~~~~~~~~~~~~

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top