基于STM32F103C8T6怎么用定时器不用中断实现1us延时函数并用来实现LED的1s闪烁
时间: 2024-10-07 20:02:12 浏览: 39
在STM32F103C8T6单片机上,可以利用其内置的定时器如TIM1来实现1us级别的延迟,并通过周期性的延时控制LED灯1s的闪烁。这里我们将采用软件计数器的方式,因为不需要使用中断。
首先,你需要配置定时器TIM1工作在连续模式(CIRCULATE),并且设置预分频器为最细粒度(例如,如果系统时钟频率是72MHz,那么选择Prescaler = 0)。然后,将定时器的溢出事件映射到 TIMx_EncoderCapture event 上,而不是外部中断。
以下是基本步骤:
1. 初始化TIM1:
```c
TIM_TimeBaseInitTypeDef.TIM_TimeBaseInitStructure;
TIM_TimeBaseInit(&TIM1, &TIM_TimeBaseInitStructure);
TIM_TimeBaseInitStructure.TIM_Prescaler = (72000000 / 1000) - 1; // 预分频器,1ms周期
TIM_TimeBaseInitStructure.TIM_Period = 999; // 设置初始计数值,大约1us
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; // 分频系数为1
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; // 可选,这里我们不需要复位
HAL_TIM_TimeBase_Init(&TIM1);
```
2. 开启定时器:
```c
HAL_TIM_Cmd(&TIM1, ENABLE);
```
3. LED闪烁部分:
为了实现1s闪烁,你可以创建一个定时器回调函数,每1ms(因为预设了1ms周期)检查一次定时器是否溢出,若溢出则点亮或熄灭LED。这里假设有一个全局标志toggle用于控制LED状态,比如toggle = !toggle。
```c
void TIM1_IRQHandler(void)
{
if(__HAL_TIM_GET_FLAG(&TIM1, TIM_FLAG_UPDATE) != RESET)
{
HAL_TIM_IRQHandler(&TIM1); // 清除标志
toggle_LED(); // 刷新LED状态
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); // LED GPIO控制,假设LED连接PA.0
}
}
void toggle_LED()
{
static uint32_t lastToggleTime = 0;
if((HAL_GetTick() - lastToggleTime) >= 1000) // 检查1s时间间隔
{
lastToggleTime = HAL_GetTick();
toggle ^= 1; // 切换LED状态
}
}
```
4. 还需记得添加TIM1中断的处理函数到系统中断向量表中:
```c
void SystemClock_Config(void)
{
... // 其他初始化
HAL_NVIC_SetPriority(TIM1_IRQn, 0, 0); // 设置TIM1中断优先级
HAL_NVIC_EnableIRQ(TIM1_IRQn); // 启动中断
}
```
注意,这里的代码简化了一些细节,实际应用中还需要考虑错误处理、延时精度调整等因素。此外,如果你需要精确到1us,可能需要结合硬件计数或者微步进等高级技术。最后别忘了添加必要的头文件和函数声明。
阅读全文