本帖最后由 南来之风 于 2023-7-31 22:42 编辑
#申请原创# 目前ST官方库有1ms的延迟函数:HAL_Delay(),但是有时候需要用到1us延迟,官方没有提供HAL库供我们调用。此时可以使用功能强大的TIM模块来产生任意时间点延迟,并最终实现呼吸灯效果。
关于TIM模块的基本用法,可以参考我的上一篇帖子:【STM32WBA52CG测评】-4- 定时器模块TIM例程分析 https://bbs.21ic.com/icview-3318482-1-1.html
本次我们将修改main.h中TIM模块相关参数,实现一个1us的中断,然后在ISR中,放置一个计数器,之后封装一个微秒延迟接口供主函数调用。
/* USER CODE BEGIN Private defines */
/*
In this example TIM2 input clock (TIM2CLK) is set to APB1 clock (PCLK1),
since APB1 prescaler is equal to 1.
TIM2CLK = PCLK1
PCLK1 = HCLK
=> TIM2CLK = HCLK = SystemCoreClock
To get TIM2 counter clock at 2 MHz, the Prescaler is computed as following:
Prescaler = (TIM2CLK / TIM2 counter clock) - 1
Prescaler = (SystemCoreClock /2 MHz) - 1
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32wbaxx.c file.
Each time the core clock (HCLK) changes, user had to update SystemCoreClock
variable value. Otherwise, any configuration based on this variable will be incorrect.
This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
----------------------------------------------------------------------- */
/* Compute the prescaler value to have TIMx counter clock equal to 2000000 Hz (2 MHz) */
#define PRESCALER_VALUE (uint32_t)(((SystemCoreClock) / (2000000)) - 1)
/* Initialize TIMx peripheral as follows:
+ Period = 10000 - 1
+ Prescaler = (SystemCoreClock/1000000) - 1
+ ClockDivision = 0
+ Counter direction = Up
*/
#define PERIOD_VALUE (2 - 1);
上面的代码,把TIM模块100MHz的时钟,通过预分频器后得到2MHz的时钟,接着定义Period参数为1,这样就是2MHz/(Period + 1) = 1MHz
每1us进入如下函数执行,其中myCounter是一个静态全局变量:
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] Period elapsed callback in non blocking mode
* @param htim : TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
myCounter++;
BSP_LED_Toggle(LD3);
}
接着封装一个延迟函数:
void my_delay_us(uint32_t Nus){
uint32_t i = myCounter;
while((myCounter - i ) <= Nus){
;
}
}
主函数中通过如下简单的延迟,即可实现呼吸灯的效果
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
for(i = 0; i < interVal; i++){
BSP_LED_Off(LD1);
my_delay_us(i);
BSP_LED_On(LD1);
my_delay_us(interVal-i);
}
for(i = 0; i < interVal; i++){
BSP_LED_On(LD1);
my_delay_us(i);
BSP_LED_Off(LD1);
my_delay_us(interVal-i);
}
}
最终效果:
|