在常规的例程中,都少不了测试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所有,任何人未经允许禁止转载。