上一章节中,我们通过while循环中的延时方法实现了阻塞式的blink操作。这种方法虽然适用于点灯等初级操作,但由于其阻塞特性,对系统的实时性影响较大。本节我们将采用定时器来实现blink操作,通过定时达到要求后执行相应操作。
定时器功能具有几大优势:
首先,定时精准,相比之下,手动调整的延时往往存在较大误差;
其次,定时器在定时结束后通过中断处理,优先级更高。
接下来,我们将实现循环点亮LED(定时器,blink间隔500ms,自动切换间隔4s)。我们还希望可以回归到通过初始化配置模块进行配置的方法,毕竟会节省很多时间,不过希望不要碰到上一章节的BUG。首先,使用配置工具添加外设——LPTMR,并配置为基础定时器功能(10ms):
这里有多种写的方式可以实现,可以是时间,也可以是频率:
这里可以看到直接进行中断的使能,转到NVIC模块也是可以看到直接启动了,这里就又和外部中断有了差异,虽然也是有回调函数,却没有对应的中断配置,单独添加又不行,这里看着就问题不大了:
同样的回调函数是给了模版的:
可以看到更新代码后添加了外设头文件peripherals.h,并在对应的C文件里添加了定时器外设的初始化(LPTMR0_init();),注意对应的文件并没有添加在main.c中,我们需要添加peripherals.h头文件,并调用BOARD_InitBootPeripherals(void)。这样才真正实现了定时器的启用。
接下来我们编写中断函数:
void LPTMR0_IRQHANDLER(void) { uint32_t intStatus; /* Reading all interrupt flags of status register */ intStatus = LPTMR_GetStatusFlags(LPTMR0_PERIPHERAL); LPTMR_ClearStatusFlags(LPTMR0_PERIPHERAL, intStatus); /* Place your code here */ LED_cnt++; Button_cnt++; if(Button_cnt > 400){ g_ButtonPress = true; Button_cnt = 0; } if(LED_cnt >= 50){ LED_flag = 1; LED_cnt = 0; } /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt. */ #if defined __CORTEX_M && (__CORTEX_M == 4U) __DSB(); #endif }
自动切换和blink的控制我们都是通过中断中的标志位处理进行的,其中定时器时间为10ms,达到50计数时,就是LED的翻转时间到了,达到400的时候就是LED灯的切换时间到了,实际上就是模拟了按键按下的操作。
效果如下: