本帖最后由 bum_ma 于 2025-4-6 21:09 编辑
我们通过while循环中的延时方法实现了阻塞式的blink操作。这种方法虽然适用于点灯等初级操作,但由于其阻塞特性,对系统的实时性影响较大。本节我们将采用定时器来实现blink操作,通过定时达到要求后执行相应操作。 定时器功能具有几大优势: 首先,定时精准,相比之下,手动调整的延时往往存在较大误差; 其次,定时器在定时结束后通过中断处理,优先级更高。 接下来,我们将实现循环点亮LED(定时器,blink间隔500ms,自动切换间隔4s)。我们还希望可以回归到通过初始化配置模块进行配置的方法,毕竟会节省很多时间,不过希望不要碰到上一章节的BUG。首先,使用配置工具添加外设——LPTMR,并配置为基础定时器功能(10ms): 
这里有多种写的方式可以实现,可以是时间,也可以是频率: 
这里可以看到直接进行中断的使能,转到NVIC模块也是可以看到直接启动了,这里就又和外部中断有了差异,虽然也是有回调函数,却没有对应的中断配置,单独添加又不行,这里看着就问题不大了: 
同样的回调函数是给了模版的: 
可以看到更新代码后添加了外设头文件peripherals.h,并在对应的C文件里添加了定时器外设的初始化(LPTMR0_init();),注意对应的文件并没有添加在main.c中,我们需要添加peripherals.h头文件,并调用BOARD_InitBootPeripherals(void)。这样才真正实现了定时器的启用。 接下来我们编写中断函数: view plaincopy to clipboardprint?
- 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灯的切换时间到了,实际上就是模拟了按键按下的操作。
|