目录
[1. TIM(Timer)定时器](#1. TIM(Timer)定时器)
[2. 定时器类型](#2. 定时器类型)
[2.1 基本定时器框图](#2.1 基本定时器框图)
[2.2 通用定时器框图](#2.2 通用定时器框图)
[2.3 高级定时器框图](#2.3 高级定时器框图)
[3. 定时器代码](#3. 定时器代码)
[3.1 恢复缺省配置](#3.1 恢复缺省配置)
[3.2 时基单元初始化](#3.2 时基单元初始化)
[3.3 结构体变量附一个默认值](#3.3 结构体变量附一个默认值)
[3.4 使能计数器](#3.4 使能计数器)
[3.5 使能中断输出信号](#3.5 使能中断输出信号)
[3.6 选择内部时钟](#3.6 选择内部时钟)
[3.7 选择ITRx其他定时器的时钟](#3.7 选择ITRx其他定时器的时钟)
[3.8 选择TIx捕获通道的时钟](#3.8 选择TIx捕获通道的时钟)
[3.9 选择ETR通过外部时钟模式1输入的时钟](#3.9 选择ETR通过外部时钟模式1输入的时钟)
[3.10 选择ETR通过外部时钟模式2输入的时钟](#3.10 选择ETR通过外部时钟模式2输入的时钟)
[3.11 配置ETR引脚的预分频起,极性滤波器等](#3.11 配置ETR引脚的预分频起,极性滤波器等)
[3.12 单独写预分频的值](#3.12 单独写预分频的值)
[3.13 改变计数器的计数模式](#3.13 改变计数器的计数模式)
[3.14 自动重装器预装功能配置](#3.14 自动重装器预装功能配置)
[3.15 给计数器写入一个值](#3.15 给计数器写入一个值)
[3.16 给自动重装器写入一个值](#3.16 给自动重装器写入一个值)
[3.17 获取当前计数器的值](#3.17 获取当前计数器的值)
[3.18 获取当前预分频器的值](#3.18 获取当前预分频器的值)
[4. 定时器配置](#4. 定时器配置)
[4.1 指定时钟分频,1分频](#4.1 指定时钟分频,1分频)
[4.2 配置计数方式](#4.2 配置计数方式)
[4.3 全部配置如下](#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 高级定时器框图
第一遍暂时没看懂,插个眼:
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);//使能计数器
}