目的
本节课目的:用普通定时器,实现延迟函数

delay:内核定时器(系统滴答定时器 SysTick)。
目录

1.获取单片机的当前时间
https://www.bilibili.com/video/BV11X4y1j7si?t=131.5&p=41

实现延迟函数步骤:配置时基单元、使能中断、写中断响应函数。
定时器配置 1ms 中断:配置时基单元,1ms 一个中断(上节学过)。 输入 72MHZ 时钟,PSC 设置为 71,得到计数器前脉冲 1MHZ。然后 ARR 设置 999,RCR 设置为 0,这样得到 1ms 的 update 事件。
定义自增全局变量:currenttick,记录单片机时间。
所以可以每隔 1ms,tick++
2.实现延迟函数
https://www.bilibili.com/video/BV11X4y1j7si?t=374.9&p=41

上图为延迟一段时间思路代码。expireTime 为延迟结束时间变量。类似 FreeRTOS 中 tick 超时的使用:
/* 等待DMA/总线空闲:短帧优先忙等待,长帧/异常场景退回tick级等待 */
uint32_t start_tick = xTaskGetTickCount();
if (len <= SPI_BUFF_BURST_LEN) {
/* 空包/短帧:忙等待,尽量在传输结束后立即拉高CS,缩短低电平时间 */
while (gd32_spi_busy(spi_dev)) {
if ((xTaskGetTickCount() - start_tick) > pdMS_TO_TICKS(2)) {
/* 超过2ms仍未结束,防止异常情况长时间占用CPU,跳出交给tick级等待兜底 */
break;
}
}
}

上图为延迟函数具体代码
3.初始化时基单元
https://www.bilibili.com/video/BV11X4y1j7si?t=480.6&p=41

初始化时基单元步骤:
1、使能时钟(APB1)
2、配置参数(PSC、CNT、ARR、RCR)
3、闭合时钟开关

上图为开启 TIM3 时钟代码。

上图为配置时基单元参数代码。
Prescaler:PSC,71
Period:ARR,999
CounterMode:CNT,向上计数
RepetitionCounter:RCR,0
clockdivision:作用于输入捕获滤波、输出比较 / PWM 的死区生成等信号处理环节,此处不讲。

闭合时基单元开关代码
放到 main 调用下
4.配置中断
https://www.bilibili.com/video/BV11X4y1j7si?t=831.8&p=41

配置中断三步骤:
1、闭合中断开关,TIM_ITConfig。注意上图三形参定义
2、配置 NVIC 模块。NVIC 为中断管理员,用到中断必配
2.1、配置中断优先级分组
2.2、设置 TIM3 中断优先级,闭合开关

上图为闭合开关,使能中断具体代码。

上图为配置 NVIC 中的配置中断优先级代码。
两位抢占优先级,两位子优先级。

上图为配置 NVIC 中的配置 TIM3 中断优先级代码。
IRQChannel 从下图 enum IRQn 中选。
抢占优先级和子优先级先配置为 0,一个中断不考虑优先级。
然后使能即可,传参初始化

stm32f10x.h 的 enum IRQn 的枚举结构体为芯片中用到的所有中断名称。
5.编写中断响应函数
https://player.bilibili.com/player.html?bvid=BV11X4y1j7si&p=41&page=41&t=1104.9&autoplay=0

在 startup 文件夹下的 startup_stm32f10x_md.s 的中断向量表 Vector Table 下。
为 TIM3_IRQHandler。

有 update、trigger、cc 事件都可以触发中断。
所以需要在 TIM3_IRQHandler 中,先查标志位是否置位,然后清标志位后再执行具体的私人代码。

上图为中断响应函数具体代码实现
写个闪灯函数,看下延迟函数好用不。
声明函数、实现函数:

上图为 LED 初始化。

延迟函数替换之前闪灯程序系统延迟函数,测试效果很 OK。
总结
这节主要讲了利用 TIM3 自制一个延迟函数。使用一个全局变量currenttick 获取 MCU 当前时间。定时器中断实现 currenttick 自增。要实现这个功能,需要三个步骤:配置时基单元(1ms),配置中断,编写中断响应函数。
配置时基单元步骤:使能 APB1 开启前端 72MHZ 时钟,配置时基单元参数(PSC、CNT、ARR、RCR),开启时基单元开关。(可对应着图回想)
配置中断步骤:闭合中断开关,配置 NVIC。配置 NVIC 为以下俩步骤:设置中断优先级分组(工程配一次即可)、设置当前外设中断优先级(TIM3),闭合开关(NVIC_Init)。
编写中断响应函数:TIM3_IRQHandler,主要是具体功能实现(currenttick 自增),比较简单。注意标志位的查询和获取,因为这个中断会被 update 事件、trigger 事件、cc 事件(捕获 / 比较事件 Capture/Compare)触发的。