[LPC]基于LPC54114的延时函数设计及应用

在常规的例程中,都少不了测试I/O控制作用的点亮LED的程序。而伴随该例程出现的往往少不了延时函数,利用此类延时函数则可以达到相对精准的时基性的延时效果,如毫秒级及微秒级的函数。缺少了此类延时函数,则只能通过定时器来编程解决了。在LPC54114的官方例程中,也有点亮LED的程序,但该例程却没有提供此类的时基性的延时函数。那它是如何来获得延时效果的呢?

其例程的主程序如下:

int main(void)

{

    int loop = 1;   

    /* Used to fix the unreachable statementwarning */

    SystemCoreClockUpdate();

    Board_Init();

    Board_IO_Init();

    Board_LED_RGB_Off();

    /* EnableSysTick Timer */

    SysTick_Config(SystemCoreClock/ TICKRATE_HZ);

    while (loop){

        __WFI();

    }

    return 0;

}

由此可以推断,它是提供嘀嗒计时器来控制延时效果的。

那嘀嗒计时器又是如何来控制LED的呢?

从下面的中断处理函数即可看出结果:

void SysTick_Handler(void)

{

    tick_ct += 1;

    /* bump tickcount */

    if ((tick_ct% 10) == 0) {

        /* if one second has elapsed (10 ticks) */

        tick_ct =0;

        LED_ct+= 1;

        /* bumpthe LED count */

        Board_LED_RGB_Set(LED_ct& 0x07);

        /* display the new LED value */

    }

}

原来它是依靠嘀嗒计时器来产生标准的时基信号,然后再通过程序设计了一个软件计时器来控制延时长短,并以此来切换RGB_LED的显示状态。

在了解了这些之后,我们能否据此来为LPC54114的例程来添加毫秒级及微秒级的延时函数呢?

答案自然是可以的,那又该这样实现呢?

为了便于理解我们先看一下如下的程序:

voidSysTick_Handler(void)

{

         tick_ct += 1;

         if ((tick_ct % M) == 0) {

                  tick_ct = 0;

                  LED_ct += 1;

                  F=(F+1)%2;

         }

}

通过增添延时标识变量F,即可判别延时是否完成,然后在主程序中即可实现延时控制的作用,而修改M的数值即可到达改变延时长短的作用。

while (1)

{

                  if(F)   LED_R_Set();

                  else   LED_R_Clr();

                  __WFI();

}

为了符合我们调用延时函数的习惯,可以将其变换为如下的形式:

voidSysTick_Handler(void)

{

         tick_ct += 1;

         if ((tick_ct % M) == 0) {

                  tick_ct = 0;

                  LED_ct += 1;

                  F=1;

         }

}

void delay_ns(uint16_t n)

{

         M=n;

         F=0;

         while(!F)

         {

            __WFI();

         }

}

这样我们就可以在主程序中,自由地使用延时函数了。

while (1)

{

        delay_ns(2);

        LED_R_Set();

        delay_ns(2);

        LED_R_Clr();

}


图1 上电状态(点亮电源指示灯)

图2 嘀嗒计时器控制LED闪烁



图3 延时函数用于RGB_LED控制

以此为基础,若将中断处理函数改为:

void SysTick_Handler(void)

{

           tick_ct += 1;

           if ((tick_ct % TICKRATE) == 0)

           {

                    tick_ct = 0;

                    LED_ct++;

                    if(LED_ct>=M)

                    {

                             LED_ct=0;

                             F=1;

                    }

           }

}

则可以达到3个等级的延时函数:

void delay_ns(uint16_t n)

{       //  秒级延时

         M=n;

         TICKRATE=1000000;

         TICKRATE_HZ=1000000;

         F=0;

         while(!F)

         {

            __WFI();

         }

}

void delay_nms(uint16_t n)

{       //  毫秒级延时

         M=n;

         TICKRATE=1000;s

         TICKRATE_HZ=1000000;

         F=0;

         while(!F)

         {

            __WFI();

         }

}

void delay_nus(uint32_t n)

{        //  微秒级延时

         M=n;

         TICKRATE=1;

         TICKRATE_HZ=1000000;

         F=0;

         while(!F)

         {

            __WFI();

         }

}

有了这些延时函数后,除了解决延时问题,我们还能做些什么呢?

在数字式的传感器驱动中,对顺序的要求比较高,因此就需要有比较基准的延时函数来配合,如单总线的DS18B20、DHT11/DHT22等,以及I2C和SPI接口的外设也需要延时函数的配合来驱动,故延时函数的作用还是非常重要的。

例如在驱动OLED屏的辅助函数中,是通过调用延时函数来保持信号作用时间的。

void IIC_Start()

{

         OLED_SCLK_Set();

         delay_nus(2);

         OLED_SDIN_Set();

         delay_nus(2);

         OLED_SDIN_Clr();

         delay_nus(2);

         OLED_SCLK_Clr();

         delay_nus(2);

}

图4 延时函数用于OLED屏显示

此外,该延时函数还适用于LPC54110等开发板。当然,也可将它移植到具有嘀嗒计时器又缺少基准延时函数的地方。
---------------------
作者:jinglixixi
链接:https://bbs.21ic.com/icview-3071742-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值