stm32 在其他中断中使用 HAL_Delay

需求 因为 485 总线控制的时候,需要考虑在收发转换的时候,不能直接切换,应该让状态再保持一段时间,比如 2ms ,然后再进行切换,这样通讯会更加稳定。这就需要再收发中断里面使用延时,而最简单的延时就是 systick 的延时。但是实际上使用起来,这个延时工作不正常。 解决 出问题的原因也很简单,因为 st 默认让 systick 的中断优先级是最低,所以导致在其他中断中,使用 HAL_Delay, 内部的数值不变,所以一直困在中断里面。解决的方法也很简单,就是重新配置中断优先级,把 systick 的优先级提高到高于通信中断的优先级即可。 参考

2023-05-24 · 1 min · 19 words · RamLife

stm32 HAL_SYSTICK_Callback 生效

需求 今天调试的时候,发现通过 systick 的 callback 并没有被调用到,这个有问题。 解决 整体的调用流程是: SysTick_Handler -> HAL_SYSTICK_IRQHandler -> HAL_SYSTICK_Callback, 但是在最新生成的库函数中, SysTick_Handler 中没有默认调用 HAL_SYSTICK_IRQHandler, 所以需要手动在 HAL_IncTick 后添加。 void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ HAL_SYSTICK_IRQHandler(); /* USER CODE END SysTick_IRQn 1 */ } 参考 STM32 HAL_SYSTICK_Callback() 失效 无效

2023-05-21 · 1 min · 59 words · RamLife

stm32 systick 计时不准确

需求 今天调试的时候,重新配置了 systick 的周期,结果发现通过 systick 进行的延时,怎么都不准,检查了时钟配置,也是很正常。 解决 其实这个问题很简单,有两种可能,一个是配置的位置不对,一个是配置的数据不对。 重新配置位置不对 重新配置 systick 正常使用 HAL_SetTickFreq 这个函数,但是注意,这个函数必须在 main.c 中的 SystemClock_Config 之后调用才可以,否则无效。 因为 SystemClock_Config -> HAL_RCC_ClockConfig -> HAL_InitTick 这个 HAL_InitTick 使用了 uwTickFreq. 但是 uwTickFreq 已经设置了默认值。所以如果 HAL_SetTickFreq 这个函数调用的位置不对,就会导致配置之后,又被重新配置为默认值。 typedef enum { HAL_TICK_FREQ_10HZ = 100U, HAL_TICK_FREQ_100HZ = 10U, HAL_TICK_FREQ_1KHZ = 1U, HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ } HAL_TickFreqTypeDef; HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ 配置数据不对 在 HAL_InitTick 中有如下配置: /* Configure the SysTick to have interrupt in 1ms time basis*/ if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) { return HAL_ERROR; } 而 systick 的 reload 寄存器只有 24 位,如果是 168M 频率,systick 为 1k,那么必然会超出寄存器的范围,导致出错,重新配置失败。所以,需要考虑系统主频和 systick 的频率,然后带入计算,保证在 24 位之内,才可以。...

2023-05-21 · 1 min · 121 words · RamLife