目录
1. TIM(Timer)定时器
2. 定时器类型
2.1 基本定时器框图
2.2 通用定时器框图
2.3 高级定时器框图
3. 定时器代码
3.1 恢复缺省配置
3.2 时基单元初始化
3.3 结构体变量附一个默认值
3.4 使能计数器
3.5 使能中断输出信号
3.6 选择内部时钟
3.7 选择ITRx其他定时器的时钟
3.8 选择TIx捕获通道的时钟
3.9 选择ETR通过外部时钟模式1输入的时钟
3.10 选择ETR通过外部时钟模式2输入的时钟
3.11 配置ETR引脚的预分频起,极性滤波器等
3.12 单独写预分频的值
3.13 改变计数器的计数模式
3.14 自动重装器预装功能配置
3.15 给计数器写入一个值
3.16 给自动重装器写入一个值
3.17 获取当前计数器的值
3.18 获取当前预分频器的值
4. 定时器配置
4.1 指定时钟分频,1分频
4.2 配置计数方式
4.3 全部配置如下
1. TIM(Timer)定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。
计数器:用来执行计数定时的一个寄存器,每来一个时钟,计数器加1
预分频器:对计数器的时钟进行分频,让计数更加灵活
自动重装寄存器:计数的目标值,就是我们想要多少个时钟申请中断
16位寄存器(2^16=65536),假如预分频器和自动重装寄存器,设到最大,就是:
72MHz/(2^16)/(2^16)=中断频率(f)
取倒数得时间(T=1/f)
可得最大定时59.65s
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。
2. 定时器类型
STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4
2.1 基本定时器框图
2.2 通用定时器框图
2.3 高级定时器框图
第一遍暂时没看懂,插个眼:
[6-1] TIM定时中断_哔哩哔哩_bilibili
3. 定时器代码
大概了解一下
3.1 恢复缺省配置
void TIM_DeInit(TIM_TypeDef* TIMx);
3.2 时基单元初始化
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
TIM_TypeDef* TIMx:选择某个定时器
TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct:包含了一些配置时基单元的参数
3.3 结构体变量附一个默认值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
3.4 使能计数器
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
TIM_TypeDef* TIMx:选择定时器
FunctionalState NewState:新的状态(使能还是失能)
3.5 使能中断输出信号
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
TIM_TypeDef* TIMx:选择定时器
uint16_t TIM_IT:选择要配置哪个中断
FunctionalState NewState:新的状态(使能还是失能)
3.6 选择内部时钟
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
3.7 选择ITRx其他定时器的时钟
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t TIM_InputTriggerSource:选择要接入哪个其他定时器
3.8 选择TIx捕获通道的时钟
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
uint16_t TIM_ICPolarity, uint16_t ICFilter);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t TIM_TIxExternalCLKSource:选择TIx具体某个引脚
uint16_t TIM_ICPolarity, uint16_t ICFilter:选择极性和滤波器
3.9 选择ETR通过外部时钟模式1输入的时钟
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t TIM_ExtTRGPrescaler:外部触发预分频起
uint16_t TIM_ExtTRGPolarity:极性
uint16_t ExtTRGFilter:滤波器
3.10 选择ETR通过外部时钟模式2输入的时钟
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t TIM_ExtTRGPrescaler:外部触发预分频起
uint16_t TIM_ExtTRGPolarity:极性
uint16_t ExtTRGFilter:滤波器
3.11 配置ETR引脚的预分频起,极性滤波器等
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t TIM_ExtTRGPrescaler:外部触发预分频起
uint16_t TIM_ExtTRGPolarity:极性
uint16_t ExtTRGFilter:滤波器
3.12 单独写预分频的值
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t Prescaler:写入预分频的值
uint16_t TIM_PSCReloadMode:写入的模式
3.13 改变计数器的计数模式
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
TIM_TypeDef* TIMx:选择要配置的定时器
uint16_t TIM_CounterMode:选择要计数的模式
3.14 自动重装器预装功能配置
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
TIM_TypeDef* TIMx:选择要配置的定时器
FunctionalState NewState:使能还是失能
3.15 给计数器写入一个值
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
3.16 给自动重装器写入一个值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
3.17 获取当前计数器的值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
3.18 获取当前预分频器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
4. 定时器配置
4.1 指定时钟分频,1分频
uint16_t TIM_ClockDivision; /*!< Specifies the clock division.
This parameter can be a value of @ref TIM_Clock_Division_CKD */
点击TIM_Clock_Division_CKD,按Ctrl+F搜索,可以看到
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)
#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \
((DIV) == TIM_CKD_DIV2) || \
((DIV) == TIM_CKD_DIV4))
可以选择,1分频,2分频,4分频以及不分频,根据自己需求进行选择。
4.2 配置计数方式
#define TIM_CounterMode_Up ((uint16_t)0x0000)
#define TIM_CounterMode_Down ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \
((MODE) == TIM_CounterMode_Down) || \
((MODE) == TIM_CounterMode_CenterAligned1) || \
((MODE) == TIM_CounterMode_CenterAligned2) || \
((MODE) == TIM_CounterMode_CenterAligned3))
/**
向上计数,向下计数,三种中央对齐的模式
4.3 全部配置如下
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启始终APB1
TIM_InternalClockConfig(TIM2);//选择时机单元的时钟,内部时钟
//定时器上电默认内部时钟,可不写
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//结构体
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频,1分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
//计数器溢出频率:CK_CNT_OV=CK_CNT/(ARR+1)=CK_PSC/(PSC+1)/(ARR-1)
//对72M进行7200分频,得到10k的计数频率,在10k的频率下,记10000个数,1s
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//PSC,自动重装
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//ARR,预分频
//预分频多,自动重装少,以比较低的频率记比较少的数
//预分频少,自动重装多,以比较高的频率记比较多的数
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器,高级采用,这里不用给0
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//手动把更新中断标志位清除一下,避免刚初始化完就进入中断的问题
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//更新中断到NVIC的通路
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC分组2
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE);//使能计数器
}
STM32F1中断NVIC-CSDN博客
STM32F1外部中断EXTI-CSDN博客