用stm32写一个毫秒级的延时
时间: 2024-10-20 19:16:42 浏览: 71
在STM32微控制器上编写一个基于硬件计数器的毫秒级延时函数,通常会利用系统定时器如TIM1或TIM2来实现,因为它们提供高精度且中断周期可配置。以下是基本步骤:
1. 首先,你需要初始化定时器。例如,如果你选择TIM1,在`main.c`里做如下设置:
```c
TIM_TimeBaseInitTypeDef.TIM_InitStruct = {0};
TIM_InitStruct.TIM_Period = (TIM_APB2PrescalerDependent >> 4) - 1; // 计算出合适的周期值
TIM_InitStruct.TIM_Prescaler = TIM_APB2PrescalerDiv8; // 分频系数,取决于你的APB2频率
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_InitStruct.TIM_CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_TimeBaseInit(&htim1, &TIM_InitStruct);
```
2. 然后,设置一个溢出中断,当定时器计数值达到设定的周期时,这个中断会被触发:
```c
HAL_NVIC_EnableIRQ(TIM1_IRQn); // 启用TIM1中断
TIM_ITConfig(&htim1, TIM_IT_Update, ENABLE); // 开启更新中断
// 清除中断标志并开启中断处理程序
HAL_TIM_IRQHandler(&htim1);
```
3. 在`TIM1_IRQHandler()`中断服务函数中,简单计数然后复位定时器:
```c
void TIM1_IRQHandler(void)
{
if(__HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_UPDATE) != RESET)
{
htim1.Instance->CNT++; // 加一表示一个计时周期结束
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_UPDATE); // 清除中断标志
if(htim1.Instance->CNT >= htim1.Period) // 检查是否到达预定周期
htim1.Instance->CNT = 0; // 到达后清零计数器
}
}
```
4. 在外部需要延时的地方,你可以创建一个函数,比如`delay_ms(uint32_t ms)`,外部调用时会累计计数器次数来模拟延迟时间:
```c
static uint32_t delayCounter = 0;
void delay_ms(uint32_t ms)
{
while (delayCounter < ms * (TIM1_ConfiguredPeriod + 1)) // 考虑一下计数器可能溢出的情况
{
HAL_Delay(1); // 等待1ms
++delayCounter;
}
}
```
5. 最后别忘了在适当的时候清除中断标志和关闭中断。
阅读全文