本博客使用简单的翻转电平(Led亮灭)来测试两个延时函数,如Code1。所使用的delay_xx()来自江科大的STM32教程(Code2)。
实验现象:while(1)的第1轮循环符合预期:两个for循环正常运行。while(1)进入第2轮循环后在HAL_Delay()中卡死,即Led常亮(据观察发现:至少10分钟)。
推测:使用delay_xx()之后HAL_Delay()延时不准。
原因:从Code2可以看到:delay_us根据输入的参数修改了System->LOAD寄存器,通过该寄存器的注释(/*!< Offset: 0x004 (R/W) SysTick Reload Value Register */)知道调用delay_us()会直接修改System的重载值。
HAL_Delay()函数如Code3所示,在debug中发现程序一直停留在Code3的while(.......)循环中,原因可能是:还没有跳出while()System就自行重载了,这导致系统永远无法跳出循环。
while (1)
{
for(i=0; i<5; i++)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_SET);
HAL_Delay(1000);
}
for(i=0; i<5; i++)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET);
delay_ms(1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_SET);
delay_ms(1000);
}
}
Code1
#include "stm32l4xx.h" // Device header
void delay_us(uint32_t us)
{
SysTick->LOAD = 32 *us; // Sys频率:32MHz
SysTick->VAL = 0x00;
SysTick->CTRL = 0x00000005;
while(!(SysTick->CTRL & 0x00010000));
SysTick->CTRL = 0x00000004;
}
void delay_ms(uint32_t ms)
{
while(ms--)
{
delay_us(1000);
}
}
void delay_x(uint32_t s)
{
while(s--)
{
delay_ms(1000);
}
}
Code2
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a period to guaranty minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)uwTickFreq;
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
Code3
8234

被折叠的 条评论
为什么被折叠?



