原创 [转]:ARM的延时 LPC2100系列延时的研究

2008-8-7 07:42 3091 15 16 分类: MCU/ 嵌入式

        ARM延时问题一直是比较令人头疼的问题,因为ARM是流水工作,并且在程序跳转的时候不遵循流水规律,所以不像51单片机一样好计算,今天为了调18B20,因此把ARM的延时问题研究了一下。总结起来,有三种计算方法。


 



         1.做好看一下编译出来的汇编语句,再自己用笔做个加减乗除,算出结果。
这种方法最直接,但是最麻烦,因为汇编指令的时间不好计算,并且要弄明白流水的工作原理,一个指令执行的时间等,因此对于像我这样的菜鸟级人物,这种方法虽然最直观,但是不可取。
       2.用定时器的中断获得精确的延时。
用定时器中断获得的延时非常精确,现将代码举例如下:


void __irq IRQ_Timer0 (void)
{
++timeval;
T0IR = 0x01;     清除中断标志     VICVectAddr = 0x00;    //通知VIC中断处理结束       
}


void time0_init(void) //定时器0初始化
{
        timeval = 0;
T0TC   = 0;    //定时器设置为0      T0PR   = 0;    //时钟不分频      T0MCR = 0x03;   //设置T0MR0匹配后复位T0TC,并产生中断标志   T0MR0 = Fpclk/1000; //1毫秒钟定时       T0TCR = 0x01;   //启动定时器
      
        VICIntSelect = 0x00; //所有中断通道设置为IRQ中断   
VICVectCntl0 = 0x20 | 0x04;//设置定时器0中断通道分配最高优先级
VICVectAddr0 = (uint32)IRQ_Timer0;//设置中断服务程序地址    VICIntEnable = 1 << 0x04;//使能定时器0中断      
        IRQEnable();   //IRQ中断使能


void wait(uint32 t)   //延时
{                           
       unsigned long i;
       if (t<1)   
          t="1";
      i = timeval;
      while ((i + t) != timeval);                 
}


这样在主函数里面用wait(10) 就延时10毫秒了。这种延时相当精确,但是占用了一个定时器,比较浪费,并且可移植性也比较差,因此在并非要求精确定时的情况下,一半不建议采用。
            3.用等待作延时。
此方法最经典的用法就是书本上经常用的用法:
void DelayNS (uint32 dly)
{
uint32 i;

for ( ; dly>0; dly--)
   for (i=0; i<50000; i++);
}
那么这个程序到底延时多长时间呢,有很多人一直用,但是并不知道延时多长时间,就像我,以前一直不知道这个程序到底延时多长时间,直到昨天用示波器观察了一下,才明白这个程序在主频为11.0592*4M的情况下延时大概为5.6毫秒,因此延时1毫秒的程序就写出来了,代码如下:
void Delay(uint32 time)    //1毫秒延时
{
uint32 i;
for(;time>0;time--)
   for(i=8929;i>0;i--);
}


10微秒和1微秒延时程序分别如下:


void delay(uint32 time)    //10微秒延时
{
uint32 i;
for(;time>0;time--)
   for(i=84;i>0;i--);
}


void delay_1(uint32 time)    //1微秒延时
{
uint32 i;
for(;time>0;time--)
   for(i=5;i>0;i--);
}
这样在主函数里就可以用以上函数基本上达到非精确延时的目的了。这种方法延时不大精确,但是不占用资源,并且可移植性很好,因此建议在非精确定时的情况下采用此方法进行定时。

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户186546 2009-2-23 13:08

void Delay(uint32 time) //1毫秒延时 void delay(uint32 time) //10微秒延时 这些函数的参数是多少才为1毫秒10微秒延时呢?望博主说明
相关推荐阅读
用户925035 2009-11-15 00:44
通用按键消抖函数 -- 数据与过程分离
AUTO:  nicksean 不务正业          项目里经常处理按键消抖, 本来这个消抖的过程是与具体按下的键无关的, 可以前的代码总是在消抖的同时处理具体的按键值, 再加上长按 短按 组合...
用户925035 2009-11-13 13:16
液晶ST7920串行显示
液晶显示128*64以7920为主控制器,采用3线制,比较经济简单。代码如下.....
用户925035 2009-11-13 13:11
DS18B20 C51完整版
使用WINBOND W78C516单片机,11.0592MHZ晶振,用共阳LED数码管P0口输出段码,P1口扫描/*******************************************...
用户925035 2009-11-12 13:19
74HC164驱动数码管
          74HC164是串行输入,并行输出接口器件,可用在单向的并行输出/并行地址锁存等. 74HC164因为价格便宜,容易使用特别适合使用在在需要用到数码管显示IO口又比较紧张的电子产品...
用户925035 2009-11-10 20:13
at24c512多字节读写函数 欢迎测试
刚写的at24c512多字节读写函数,欢迎测试。/********************************************************************函数功能:EE...
用户925035 2009-11-10 19:59
旋转编码器
    很好的旋转编码器的读码程序,设旋转编码器的输出波形如下                 ______        ______        ______        ______正转时:...
EE直播间
更多
我要评论
1
15
关闭 站长推荐上一条 /1 下一条