第31章 高级定时器-定时
第三十一章 高级定时器-定时
1. 硬件设计
无需硬件设计
2. 软件设计
2.1 编程大纲
-
TIM相关参数宏定义
-
TIM NVIC及Mode配置
-
TIM中断服务函数
-
主函数测试
2.2 代码分析
2.2.1 高级定时器相关参数宏定义
#define ATMx TIM1
#define ATIM_Period 999
#define ATIM_Prescaler 71
#define ATIM_IRQ TIM1_UP_IRQn
#define ATIM_IRQHandler TIM1_UP_IRQHandler
2.2.2 NVIC及Mode配置
#include "AdvanceTim.h"
static void ATIM_NVIC_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = ATIM_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void ATIM_Mode_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseStructure.TIM_Period = ATIM_Period; // 999
TIM_TimeBaseStructure.TIM_Prescaler = ATIM_Prescaler; // 71
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(ATMx, &TIM_TimeBaseStructure);
TIM_ClearFlag(ATMx, TIM_FLAG_Update); // 清除更新标志位
TIM_ITConfig(ATMx, TIM_IT_Update, ENABLE); // 使能更新中断
TIM_Cmd(ATMx, ENABLE); // 使能定时器
}
void ATIM_Config(void)
{
ATIM_NVIC_Init();
ATIM_Mode_Init();
}
2.2.3 中断服务函数
volatile uint32_t time = 0; // ms 计时变量
void ATIM_IRQHandler(void)
{
if(TIM_GetITStatus(ATMx, TIM_IT_Update) != RESET)
{
time++;
TIM_ClearITPendingBit(ATMx , TIM_FLAG_Update);
}
}
2.2.4 主函数
#include "stm32f10x.h"
#include "led.h"
#include "AdvanceTim.h"
#include "usart.h"
extern volatile uint32_t time;
int main(void)
{
LED_Init();
ATIM_Config();
USART_Config();
while(1)
{
if(time == 1000) // 1000 * 1 ms = 1s 时间到
{
time = 0;
LED1_TOGGLE();
printf("这是由TIM1产生的1s定时器中断\r\n");
}
}
}
3. 小结
这个与其他定时器无异,只是基本使用,无法体现高级定时器的功能,那我们再来回顾一下定时器基本配置的流程吧:
3.1 定义定时器结构体
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- 这行代码定义了一个
TIM_TimeBaseInitTypeDef
类型的结构体TIM_TimeBaseStructure
。这个结构体用于配置定时器的基本参数,如计数周期、预分频器等。
3.2 开启定时器时钟
ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK, ENABLE);
- 通过调用
ADVANCE_TIM_APBxClock_FUN
函数启用与定时器相关的时钟。ADVANCE_TIM_CLK
是要使能的时钟源(例如RCC_APB2Periph_TIM1
),ENABLE
表示开启时钟。 - 这一步骤是必须的,因为定时器在未使能其时钟之前无法正常工作。
3.3 配置自动重装载寄存器
TIM_TimeBaseStructure.TIM_Period = ADVANCE_TIM_Period;
TIM_Period
设置了定时器的自动重装载寄存器的值。定时器会在计数到这个值后重新从零开始计数,从而触发一个更新事件或中断。
3.4 配置时钟预分频数
TIM_TimeBaseStructure.TIM_Prescaler = ADVANCE_TIM_Prescaler;
TIM_Prescaler
设置了时钟的预分频值。定时器时钟频率通过将输入时钟除以TIM_Prescaler
来降低。这决定了定时器的计数频率。
3.5 时钟分频因子
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_ClockDivision
指定了时钟的分频因子。在这里,它被设置为TIM_CKD_DIV1
,表示没有额外的分频。这一项在很多情况下可以忽略,特别是当使用定时器的基本模式时。
3.6 计数器计数模式
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
3.7 重复计数器的值
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_RepetitionCounter
用于高级定时器的重载计数模式,但在此代码中设置为0
,表示不使用该功能。
3.8 初始化定时器
TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);
3.9 清除计数器中断标志位
TIM_ClearFlag(ADVANCE_TIM, TIM_FLAG_Update);
TIM_ClearFlag
函数用于清除定时器的更新中断标志位。通常在中断处理程序中或在启用中断之前需要清除标志位,以防止错误的中断触发。
3.10 开启计数器中断
TIM_ITConfig(ADVANCE_TIM, TIM_IT_Update, ENABLE);
TIM_ITConfig
函数用于配置定时器的中断。这里设置TIM_IT_Update
中断为使能状态,以便定时器达到更新事件时产生中断。
3.11 使能计数器
TIM_Cmd(ADVANCE_TIM, ENABLE);
- 最后,调用
TIM_Cmd
函数启用定时器。此时定时器开始工作,并根据设置的周期和预分频值产生定时器中断或事件。
2024.9.13 第一次修订,后期不再维护
2025.1.27 优化代码
本文作者:hazy1k
本文链接:https://www.cnblogs.com/hazy1k/p/18412743
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步