STM32-TIM 02
定时器简介
TIM定义:对输入的时钟进行计数,并在计数值达到设定值时触发中断
TIM:
-
时基单元:16位计数器,预分频器,自动重装寄存器
-
分类:高级定时器 通用定时器 基本定时器
-
计数模式 向上计数模式:cnt == arr溢出 向下计数: cnt = arr -> 0 溢出 中央对齐模式:cnt == arr,cnt = arr -> 0 注意 中央对齐模式先向上计数,再向下计数
-
定时器溢出效应: 更新中断 更新事件: 影子寄存器更新:将预装载寄存器的值立即更新到影子寄存器中包括ARR、PSC和比较值(CCR) 中心对齐模式计数器计数方向改变 注意 影子寄存器是实际起作用的寄存器,预装载寄存器供读写
-
定时器时钟源选择: 内部时钟源:系统时钟 外部时钟模式1 外部时钟模式2:TIM2_ETR引脚 注意 stm32f103c8t6的TIM2_ETR引脚位PA0
-
各时钟频率 基准计数时钟频率(内外时钟源) 计数器计数时钟频率(基准计数时钟分频后) 计数器溢出频率:基准计数时钟/分频系数+1/重装载值+1
定时器函数
时基单元初始化函数:
-
函数使用 函数:TIM_TimeBaseInit 入参:定时器 结构体指针 返回值:无 注意: 为了寄存器重载,函数内部会让定时器产生一个更新事件,同时伴随更新中断,这样板子一上电,定时器就会进入一次中断; 措施:调用TIM_ClearFlag(TIM2, TIM_IT_Flag);
-
TIM_TimeBaseInitTypedef结构体成员: TIM_ClockDivision: 配置滤波器时钟,对时基单元无影响 TIM_CKD_DIV1 / TIM_CKD_DIV2 / TIM_CKD_DIV4 TIM_CounterMode: 计数器模式TIM_CounterMode_Up / TIM_CounterMode_Down TIM_Period: ARR数值 TIM_Prescaler: 预分频系数 TIM_RepetitionCounter: 高级定时器控制更新中断的发生频率
-
时基单元初始化函数调用示例
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
定时器配置外部时钟模式2函数:
-
函数使用: 函数:TIM_ETRClockMode2Config 入参:定时器 外部时钟分频 外部触发极性 外部触发滤波器 返回值:无
-
入参解析 外部时钟分频: TIM_ExtTRGPSC_OFF / TIM_ExtTRGPSC_DIV2 / TIM_ExtTRGPSC_DIV4 / TIM_ExtTRGPSC_DIV8 外部触发极性: TIM_ExtTRGPolarity_Inverted 上升沿触发 / TIM_ExtTRGPolarity_NonInverted 下降沿触发 外部触发滤波器:外部触发滤波器
-
函数调用示例
TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
定时器中断使能函数:
-
函数使用 函数:TIM_ITConfig 入参:定时器 待使能的中断标志位 ENABLE/DISABLE 返回值:无
-
定时器中断使能函数调用示例
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
定时器使能函数:
-
函数使用 函数:TIM_Cmd 入参:定时器 ENABLE/DISABLE 返回值:无
-
定时器使能函数调用示例
TIM_Cmd(TIM2, ENABLE);
定时器查询CNT函数:
-
函数使用 函数:TIM_GetCounter 入参:定时器 返回值:CNT值
-
定时器使能函数调用示例
uint16_t cnt = TIM_GetCounter(TIM2);
定时器标志位: TIM_GetITStatus函数: TIM_IT_Update:定时器产生更新中断
定时器中断服务函数:
EXTI中断服务函数示例
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update))
{
//中断处理事件
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
定时器输出比较简介
OC前置:
-
英文: OC:输出比较 IC:输入捕获 CCR:捕获/比较寄存器, OC:比较寄存器 IC:捕获寄存器
OC定义: 通过比较CNT与CCR寄存器值的关系,对输出电平进行置1,置0操作,用于输出一定占空比的PWM波
OC:
-
模式:PWM模式1
-
PWM波: 定义: 配置不同占空比的PWM波,等效模拟参量
参数计算: 周期:定时器中断周期 占空比:OC值 / ARR值 分辨率:1 / ARR + 1
-
高级定时器PWM波: 需调用PWM波输出使能函数:TIM_CtrlPWMOutputs(TIM1, ENABLE);
定时器输出比较函数
OC初始化函数:
-
函数使用 函数:TIM_OC1Init 入参:定时器 结构体指针 返回值:返回值 注意:OC1借用TIM2_CH1输出
-
TIM_OCInitTypedef结构体成员变量 TIM_OCMode: PWM1模式 TIM_OCMode_PWM1 TIM_OCPolarity: 输出极性 TIM_OCPolarity_High / TIM_OCPolarity_Low 输出高低电平取反 TIM_OutputState: 输出使能 TIM_OutputState_Enable / TIM_OutputState_Disable TIM_Pulse: OC值
-
函数调用示例:
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC2Init(TIM2, &TIM_OCInitStructure);
输出比较模式修改OC值函数:
-
函数使用 函数:TIM_SetCompare1 入参:定时器 OC值 返回值:无
-
函数调用示例
TIM_SetCompare1(TIM2, 33);
定时器输入捕获简介
IC前置:
-
测量频率的方法: 测频法:时基1s内的数波形有多少个上升沿,波形数就是频率 测周发:波形俩个上升沿按一定频率fc,数N次,fc/N就是频率
IC定义: 通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中
IC:
-
通道: 定时器输出比较与输入捕获共用4个通道,OC1 OC2 OC3 OC4 IC1 IC2 IC3 IC4,同一通道输出比较与输入捕获不可同时进行
-
输入捕获模式测频率: TIM2_CH1通道输入的PWM波,给单片机的输入滤波器和边沿检测器,得到TI1FP1信号,再经过分频器进行分频,每来一个触发信号,CNT值锁存到CCR1中后清零,根据CNT的驱动时钟频率fc,得频率:fc/CNT 注意 若fc频率过低,可能导致CNT溢出
-
输入捕获模式测PWM波频率占空比:
PWMI模式: TIM2_CH1通道输入的PWM波,经过单片机的输入滤波器和边沿检测器,得到TI1FP1与TI2FP2俩路信号; IC1配置为上升沿触发,直连,捕获TI1FP1上升沿;IC2配置为下降沿触发,交叉,捕获TI1FP1下升沿; 再经过分频器进行分频,TI1FP1来一个上升沿,CNT值锁存到CCR1中后清零,TI2FP2来一个下降沿,CNT锁存到CCR2中; 根据CNT的驱动时钟频率fc,得频率:fc/CCR1 得占空比:CCR2/CCR1 注意 TI1FP1与TI2FP2相同的信号,只不过被不同的通道捕获 CCR1就是一个周期的计数值;CCR2就是高电平的计数值
定时器输入捕获函数
输入捕获初始化函数:
-
函数使用: 函数:TIM_ICInit 入参:定时器 结构体指针 返回值:无
-
TIM_ICInitTypedef结构体成员变量: TIM_Channel: 选择IC通道 TIM_Channel_1 / TIM_Channel_2 / TIM_Channel_3 / TIM_Channel_4 TIM_ICFilter: 触发锁存边沿 TIM_ICPolarity_Rising / TIM_ICPolarity_Falling / TIM_ICPolarity_BothEdge
TIM_ICPrescaler: 捕获预分频,选择不分频,每次信号都触发捕获TIM_ICPSC_DIV1 / TIM_ICPSC_DIV2 / TIM_ICPSC_DIV4 / TIM_ICPSC_DIV8
TIM_ICSelection: 输入信号交叉与否 TIM_ICSelection_DirectTI 只测频率 / TIM_ICSelection_IndirectTI 测频率与占空比
-
函数调用示例:
TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICFilter = 0xF; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInit(TIM3, &TIM_ICInitStructure);
PWMI模式配置函数:
-
函数使用: 函数:TIM_PWMIConfig 入参:定时器 结构体指针 返回值:无 注意 仅支持通道1与通道2的配合使用
-
函数调用示例:
TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICFilter = 0xF; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
注意 TIM_PWMIConfig()内部会调用一次IC_init在配置通道1为上升沿触发、直连的同时,会将通道2自动配置为下降沿触发,并将其输入选择为“间接”(从通道1获取信号),以实现对同一PWM信号周期和脉宽的测量。
输入触发源选择函数:
-
函数使用: 函数:TIM_SelectInputTrigger 入参:定时器 输入触发源 返回值:无
-
函数调用示例:
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
从模式选择函数:
-
函数使用: 函数:TIM_SelectSlaveMode 入参:定时器 从模式 返回值:无
-
函数调用示例:
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
注意 前面TI1FP1配置为上升沿触发,这里表示每来一个上升沿作为触发源都会引发从模式把CNT计数值清0
CCR寄存器读取函数:
-
函数使用: 函数:TIM_GetCapture1 入参:定时器 返回值:CCR值
-
函数调用示例:
uint16_t ccr = TIM_GetCapture1(TIM3);
定时器输入捕获模块函数
void IC_Init(void)
{
RCC_APB1PeriphClockCmd//开启TIM3的时钟
RCC_APB2PeriphClockCmd//开启GPIOA的时钟
GPIO_Init//将PA6引脚初始化为上拉输入
TIM_TimeBaseInit
TIM_PWMIConfig
TIM_SelectInputTrigger//触发源选择TI1FP1
TIM_SelectSlaveMode//从模式选择复位
TIM_Cmd
}
uint32_t IC_GetFreq(void)
{
return 1000000 / (TIM_GetCapture1(TIM3)); //测周法得到频率fx = fc / N
}
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
定时器编码器接口
编码器接口前置:
-
正交编码器 输出A B俩相波形,俩个波形相位相差90度
正转波形:A相波形上升沿,B相低电平;A相波形下降沿,B相高电平;B相波形上升沿,A相高电平;B相波形下降沿,A相低电平 反转波形:A相波形上升沿,B相高电平;B相波形上升沿,A相低电平;A相波形下降沿,B相低电平;B相波形下降沿,A相高电平
编码器接口定义: 接收正交编码器信号,通过定时器输入捕获的通道1与通道2,输入到定时器编码器接口,正转编码器接口控制CNT自增,反转控制自减
编码器接口:
-
资源 每一个高级定时器与通用定时器都有一个编码器接口
-
工作模式 仅在TI1计数 仅在TI2计数 在TI1与TI2都计数
定时器编码器接口函数
编码器接口配置函数:
-
函数使用: 函数:TIM_EncoderInterfaceConfig 入参:定时器 计数模式 A相波形极性 B相波形极性 返回值:无
-
参数解析 计数模式:选择单相波形计数,还是俩项波形都计数TIM_EncoderMode_TI1 / TIM_EncoderMode_TI2 / TIM_EncoderMode_TI12
A相波形极性:A相波形不反转 TIM_ICPolarity_Rising / A相波形反转 TIM_ICPolarity_Falling B相波形极性:B相波形不反转 TIM_ICPolarity_Rising / B相波形反转 TIM_ICPolarity_Falling
-
函数调用示例:
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
定时器编码器接口模块函数
int16_t Encoder_Get(void)
{
int16_t Temp;
Temp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
return Temp;
}
注意 TIM_GetCounter函数返回的是uint16_t类型的数据,范围0~65535 赋值给int16_t类型的数据,范围-32768~32767
TIM_GetCounter返回45678,对应temp -19858,俩者相减为65536
隔一段时间,取一次CNT值就代表编码器转速
更多推荐

所有评论(0)