单片机中运行多个定时器
在单片机的裸机编程环境中,同时运行多个定时器是完全可行的,但需要注意一些关键点以确保系统的稳定性和效率。以下是一些考虑因素和实现方法:
1. 硬件支持
2. 中断配置
3. 定时器初始化
4. 任务调度
5. 性能优化
6. 示例代码
下面是一个简单的示例,展示了如何在STM32单片机上同时配置和使用三个定时器。假设我们使用的是STM32CubeMX生成的基础代码框架。
#include "stm32f4xx_hal.h"
TIM_HandleTypeDef htim2; // 定时器2
TIM_HandleTypeDef htim3; // 定时器3
TIM_HandleTypeDef htim4; // 定时器4
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM4_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) {
// 处理定时器2的中断
// 例如,每1秒触发一次
printf("Timer 2 Interrupt\n");
} else if (htim->Instance == TIM3) {
// 处理定时器3的中断
// 例如,每500毫秒触发一次
printf("Timer 3 Interrupt\n");
} else if (htim->Instance == TIM4) {
// 处理定时器4的中断
// 例如,每250毫秒触发一次
printf("Timer 4 Interrupt\n");
}
}
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM4_Init();
// 启动定时器
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim4);
while (1) {
// 主循环可以用来做其他事情
}
}
static void MX_TIM2_Init(void) {
__HAL_RCC_TIM2_CLK_ENABLE();
htim2.Instance = TIM2;
htim2.Init.Prescaler = 8399; // 假设系统时钟为84MHz,预分频器设置为8400-1
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 9999; // 每10000个计数周期溢出,即1秒
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&htim2);
}
static void MX_TIM3_Init(void) {
__HAL_RCC_TIM3_CLK_ENABLE();
htim3.Instance = TIM3;
htim3.Init.Prescaler = 8399;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 4999; // 每5000个计数周期溢出,即500毫秒
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&htim3);
}
static void MX_TIM4_Init(void) {
__HAL_RCC_TIM4_CLK_ENABLE();
htim4.Instance = TIM4;
htim4.Init.Prescaler = 8399;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 2499; // 每2500个计数周期溢出,即250毫秒
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_Base_Init(&htim4);
}
void SystemClock_Config(void) {
// 系统时钟配置代码
}
static void MX_GPIO_Init(void) {
// GPIO初始化代码
}
7. 注意事项
MX_TIMx_Init()
函数中通过htimx.Init.Priority
参数进行设置。作者:鹿屿二向箔