jinglixixi 发表于 2021-2-18 01:21

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

本帖最后由 jinglixixi 于 2021-2-18 11:48 编辑

#申请原创#
在常规的例程中,都少不了测试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等开发板。当然,也可将它移植到具有嘀嗒计时器又缺少基准延时函数的地方。





页: [1]
查看完整版本: 基于LPC54114的延时函数设计及应用