定时器常用功能配置函数:
本文提供stm32定时器配置的常用函数,只需要了解头文件中介绍的非常简单的几个函数,stm32定时器常用的一些功能就可以轻松配置了,再也不用与那些令人头痛的标准库定时器结构体打交道了,当然掌握原理对于学习stm32是至关重要的,下面的封装代码只是图个配置方便而已!初学阶段的小伙伴不建议用下面的代码,还是建议先理解定时器的基本原理再图方便!
大家在使用这两个文件的时候不必纠结我写的.c文件函数体的内容,只需要重点查看我在头文件里的说明文档和.c文件里的函数简介即可!
GuiStar_TIM.h:
/**
****************************************************************************************
* @file GuiStar_TIM.h
* @author GuiStar-李什么恩
* @version V1.1.3
* @date 2022-10-21
* @brief 该文件含有配置定时器的定时中断,输出比较,输入捕获,增量式编码器接口等
* 常用功能的配置函数,适合理解配置原理但是想提高配置效率的人群使用!
****************************************************************************************
*/
#ifndef __GUISTAR_TIM_H__
#define __GUISTAR_TIM_H__
#include "stm32f10x.h" // Device header
/*******************定时中断,输出比较,输入捕获*******************/
//提示:下面三个函数详细的使用方法请跳转到.c文件的函数注释文档查看
//以下两个宏定义用来设置输入捕获标准频率
#define IC_ARR 65536-1
#define IC_PSC 1-1
void GuiStar_TIM(TIM_TypeDef* TIMx, u16 TIM_PSC, u16 TIM_ARR, u8 TIM_ENABLE, u8 IR_State);
void GuiStar_PWM_Init(TIM_TypeDef* TIMx, u8 PWM_tongdao, u16 TIM_PSC, u16 TIM_ARR, u8 IR_State);
void GuiStar_IC_Init(TIM_TypeDef* TIMx);
//定时器2,3,4中断设置函数
//提示:(1)使用前要先开启定时器中断
//(2)这几个函数的输入参数都是某个无参函数的地址(函数名)
//(3)这个无参函数是您自己写的,里面是本次中断的行为
//(4)当然您也可以选择不用这几个函数,而去直接写某个定时器对应的中断函数
//(5)这几个函数只是出于方便考虑,如果您觉得不习惯,完全可以无视它们
void GuiStar_TIM_SetTIM2IRQHandler(void (*Function)(void));
void GuiStar_TIM_SetTIM3IRQHandler(void (*Function)(void));
void GuiStar_TIM_SetTIM4IRQHandler(void (*Function)(void));
/***************************增量式编码器*************************/
//提示:使用之前一定要仔细对照每一个宏定义是否设置正确
//否则可能导致函数失效!!!
#define Encoder_TIM_CLKFunction() RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE)//开启编码器定时器时钟
#define TI1_Port GPIOA //选择TI1端口
#define TI1_Pin GPIO_Pin_0 //选择TI1引脚
#define TI1_Clk RCC_APB2Periph_GPIOA //选择TI1时钟
#define TI2_Port GPIOA //选择TI2端口
#define TI2_Pin GPIO_Pin_1 //选择TI2引脚
#define TI2_Clk RCC_APB2Periph_GPIOA //选择TI2时钟
#define TIM_EncoderPolarity 0 //如果给0则极性不反向,否则极性反向(反向与不反向本身也是相对的)
void Encoder_Init(TIM_TypeDef *TIMx);
int16_t Encoder_GetSpeed(TIM_TypeDef *TIMx);
int16_t Encoder_GetValue(TIM_TypeDef *TIMx);
#endif
/***********************关于本文件的说明文档**************************
* @DocumentDescription:
* 首先说明上述四个函数中的PSC和ARR要加一才对应分频系数和重装值,因此为了函数
* 使用方便在函数内部完成加一,给参数的时候只需要写加1之后的值即可!
*
*****************************************************************************************
* @OfficialFunctions 介绍一下定时常用的官方库函数
* (1)获取定时器当前计数值(CNT):TIM_GetCounter(TIM_TypeDef* TIMx);
*
* (2)重新设置定时器计数值(CNT):void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
*
* (3)PWM:
* 设置比较输出值(CCR)的四个函数如下:
* void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
* void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
* void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
* void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
*
* 实际应用的时候还可能碰到更改ARR的值来改变PWM频率的需求,这个时候需要做以下两步:
* 第一,调用一次TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
* 这一步的目的是开启预加载寄存器,可以查看本人的第三篇博客文章
* 博客链接:https://blog.csdn.net/hhhbdbfb?type=blog
* 第二,调用TIM_SetAutoreload函数更改ARR的值
*
* (4)获取输入捕获ICR寄存器的值:TIM_GetCapture1(TIM_TypeDef* TIMx) 和
* TIM_GetCapture2(TIM_TypeDef* TIMx)
*
* (5)临时关闭定时器更新事件:TIM_UpdateDisableConfig:如果参数给ENABLE则不会触发更新中断
* 但是计数器在达到ARR之后,仍然可以清零.在特定情况下,可能需要临时关闭中断,可以使用此函数
*
* (6)关于定时器主从模式的三个函数:
* 选择触发源:
* void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
* 选择触发主模式的事件:
* void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
* 选择从模式行为:
* void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
*
******************************************************************************************
*/
GuiStar_TIM.c:
#include "GuiStar_TIM.h"
void (*GuiStar_TIM2_IRQHandler)(void);
void (*GuiStar_TIM3_IRQHandler)(void);
void (*GuiStar_TIM4_IRQHandler)(void);
/**
* @brief 确定定时器2中断处理器的行为
* @param *Function 它是一个指向定时器中断行为的指针
* @retval 无
*/
void GuiStar_TIM_SetTIM2IRQHandler(void (*Function)(void))
{
GuiStar_TIM2_IRQHandler=Function;
}
/**
* @brief 确定定时器3中断处理器的行为
* @param *Function 它是一个指向定时器中断行为的指针
* @retval 无
*/
void GuiStar_TIM_SetTIM3IRQHandler(void (*Function)(void))
{
GuiStar_TIM3_IRQHandler=Function;
}
/**
* @brief 确定定时器4中断处理器的行为
* @param *Function 它是一个指向定时器中断行为的指针
* @retval 无
*/
void GuiStar_TIM_SetTIM4IRQHandler(void (*Function)(void))
{
GuiStar_TIM4_IRQHandler=Function;
}
static void GuiStar_TIM2_Init(u16 TIM_PSC, u16 TIM_ARR, u8 TIM_ENABLE, u8 IR_State)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_TimeBaseInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_ICInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_ICInitStruct.TIM_Period = TIM_ARR-1;
TIM_ICInitStruct.TIM_Prescaler = TIM_PSC-1;
TIM_ICInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2,&TIM_ICInitStruct);
if(IR_State)
{
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
if(TIM_ENABLE)
{
TIM_Cmd(TIM2,ENABLE);
}
}
static void GuiStar_TIM3_Init(uint16_t TIM_PSC, uint16_t TIM_ARR, uint8_t TIM_ENABLE, uint8_t IR_State)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_ICInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_ICInitStruct.TIM_Period = TIM_ARR-1;
TIM_ICInitStruct.TIM_Prescaler = TIM_PSC-1;
TIM_ICInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3,&TIM_ICInitStruct);
if(IR_State)
{
TIM_ClearFlag(TIM3,TIM_FLAG_Update);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
if(TIM_ENABLE)
{
TIM_Cmd(TIM3,ENABLE);
}
}
static void GuiStar_TIM4_Init(uint16_t TIM_PSC, uint16_t TIM_ARR, uint8_t TIM_ENABLE, uint8_t IR_State)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
TIM_TimeBaseInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_ICInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_ICInitStruct.TIM_Period = TIM_ARR-1;
TIM_ICInitStruct.TIM_Prescaler = TIM_PSC-1;
TIM_ICInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4,&TIM_ICInitStruct);
if(IR_State)
{
TIM_ClearFlag(TIM4,TIM_FLAG_Update);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
if(TIM_ENABLE)
{
TIM_Cmd(TIM4,ENABLE);
}
}
/**
* @brief 通用定时器2,3,4初始化函数(stm32F103C8T6的通用定时器只有这三个)
* @param TIMx 选择定时器(TIM2,TIM3,TIM4)
* @param TIM_PSC 分频系数
* @param TIM_ARR 重装值
* @param TIM_ENABLE 定时器是否使能(非零使能)
* @param IR_State 定时器是否开启更新中断(非零中断),更新中断模板请在头文件中查看
* @retval 无
*/
void GuiStar_TIM(TIM_TypeDef* TIMx, u16 TIM_PSC, u16 TIM_ARR, u8 TIM_ENABLE, u8 IR_State)
{
if(TIMx==TIM2)
GuiStar_TIM2_Init(TIM_PSC, TIM_ARR, TIM_ENABLE, IR_State);
if(TIMx==TIM3)
GuiStar_TIM3_Init(TIM_PSC, TIM_ARR, TIM_ENABLE, IR_State);
if(TIMx==TIM4)
GuiStar_TIM4_Init(TIM_PSC, TIM_ARR, TIM_ENABLE, IR_State);
}
/**
* @brief 通用定时器PWM初始化函数(stm32F103C8T6的通用定时器只有这三个)
* @param TIMx TIMx 选择定时器(TIM2,TIM3,TIM4)
* @param PWM_tongdao 选择PWM通道(1~4)
* @param TIM_PSC 分频系数
* @param TIM_ARR 重装值
* @param IR_State 是否开启中断,(非零开启),更新中断模板请在头文件中查看
* @note PWM各个通道的引脚初始化已在函数内部实现,在此说明一下各个通道对应的引脚:
TIM2_CH1:A0;
TIM2_CH2:A1;
TIM2_CH3:A2;
TIM2_CH4:A3;
TIM3_CH1:A6;
TIM3_CH2:A7;
TIM3_CH3:B0;
TIM3_CH4:B1;
TIM4_CH1:B6;
TIM4_CH2:B7;
TIM4_CH3:B8;
TIM4_CH4:B9;
* @retval 无
*/
void GuiStar_PWM_Init(TIM_TypeDef* TIMx, u8 PWM_tongdao, u16 TIM_PSC, u16 TIM_ARR, u8 IR_State)
{
uint16_t GPIO_Pin_x;
GPIO_TypeDef* GPIOx;
if(TIMx==TIM2)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
if(PWM_tongdao==1)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_0;
}
if(PWM_tongdao==2)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_1;
}
if(PWM_tongdao==3)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_2;
}
if(PWM_tongdao==4)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_3;
}
}
if(TIMx==TIM3)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
if(PWM_tongdao==1)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_6;
}
if(PWM_tongdao==2)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_7;
}
if(PWM_tongdao==3)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_0;
}
if(PWM_tongdao==4)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_1;
}
}
if(TIMx==TIM4)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
if(PWM_tongdao==1)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_6;
}
if(PWM_tongdao==2)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_7;
}
if(PWM_tongdao==3)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_8;
}
if(PWM_tongdao==4)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_9;
}
}
GPIO_InitTypeDef GPIO_Init_Struct;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_x;
GPIO_Init(GPIOx,&GPIO_Init_Struct);
TIM_TimeBaseInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_ICInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_ICInitStruct.TIM_Period = TIM_ARR-1;
TIM_ICInitStruct.TIM_Prescaler = TIM_PSC-1;
TIM_ICInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIMx,&TIM_ICInitStruct);
TIM_OCInitTypeDef TIML_OCInitStruct;
TIM_OCStructInit(&TIML_OCInitStruct);
TIML_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIML_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIML_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIML_OCInitStruct.TIM_Pulse = 0;//CCR
if(PWM_tongdao==1)
TIM_OC1Init(TIMx,&TIML_OCInitStruct);
if(PWM_tongdao==2)
TIM_OC2Init(TIMx,&TIML_OCInitStruct);
if(PWM_tongdao==3)
TIM_OC3Init(TIMx,&TIML_OCInitStruct);
if(PWM_tongdao==4)
TIM_OC4Init(TIMx,&TIML_OCInitStruct);
if(IR_State)
{
TIM_ClearFlag(TIMx,TIM_FLAG_Update);
TIM_ITConfig(TIMx,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
if(TIMx==TIM2)
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
if(TIMx==TIM3)
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
if(TIMx==TIM4)
NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
}
TIM_Cmd(TIMx,ENABLE);
}
/**
* @brief 通用定时器输入捕获初始化函数(stm32F103C8T6的通用定时器只有这三个)
* @attention 输入捕获需要一个标准频率来测量时间,此函数利用通用定时器TIMx
来产生一个1M的标准频率
* @param TIMx TIMx 选择定时器(TIM2,TIM3,TIM4)
* @note 各个通道对应的引脚:
TIM2_CH1:A0;
TIM3_CH1:A6;
TIM4_CH1:B6;
此函数调用完之后,需要调用TIM_GetCapture1可以获取两个上升
沿之间的标准频率计数值;调用TIM_GetCapture2可以获取一个上
升沿和一个下降沿之间的标准频率计数值。而标准频率是1M,因此可
以用TIM_GetCapture1和TIM_GetCapture2计算PWM频率和占空
比。当然可以测量电平时间,具体怎么用就靠大家发挥了
* @retval 无
*/
void GuiStar_IC_Init(TIM_TypeDef* TIMx)
{
uint16_t GPIO_Pin_x;
GPIO_TypeDef* GPIOx;
if(TIMx==TIM2)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_0;
}
if(TIMx==TIM3)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIOx=GPIOA;
GPIO_Pin_x=GPIO_Pin_6;
}
if(TIMx==TIM4)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIOx=GPIOB;
GPIO_Pin_x=GPIO_Pin_6;
}
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOx, &GPIO_InitStructure);
TIM_InternalClockConfig(TIMx);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = IC_ARR;
TIM_TimeBaseInitStructure.TIM_Prescaler = IC_PSC;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStructure);
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(TIMx, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIMx, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIMx, TIM_SlaveMode_Reset);
TIM_Cmd(TIMx, ENABLE);
}
/**
* @brief 定时器编码器接口初始化函数
* @param TIMx(x=1,2,3,4,5,8),这里一定要注意定时器选择要和Encoder.h的定时器时钟宏定义匹配
* @retval 无
*/
void Encoder_Init(TIM_TypeDef *TIMx)
{
Encoder_TIM_CLKFunction();
RCC_APB2PeriphClockCmd(TI1_Clk, ENABLE);
RCC_APB2PeriphClockCmd(TI2_Clk, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = TI1_Pin;
GPIO_Init(TI1_Port, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = TI2_Pin;
GPIO_Init(TI2_Port, &GPIO_InitStruct);
TIM_TimeBaseInitTypeDef TIM_BaseInitstruct;
TIM_BaseInitstruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitstruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseInitstruct.TIM_Period = 65536-1;
TIM_BaseInitstruct.TIM_Prescaler = 1-1;
TIM_BaseInitstruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIMx, &TIM_BaseInitstruct);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_PWMIConfig(TIMx, &TIM_ICInitStructure);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_PWMIConfig(TIMx, &TIM_ICInitStructure);
if(TIM_EncoderPolarity==0)
TIM_EncoderInterfaceConfig(TIMx, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
else TIM_EncoderInterfaceConfig(TIMx, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling,TIM_ICPolarity_Rising);
TIM_Cmd(TIMx, ENABLE);
}
/**
* @brief 函数内部先将定时器计数器的值锁存,在清零计数器,最后返回锁存值
* @param 无
* @retval CNT锁存值
*/
int16_t Encoder_GetSpeed(TIM_TypeDef *TIMx)
{
int16_t temp;
temp = TIM_GetCounter(TIMx);
TIM_SetCounter(TIMx, 0);
return temp;
}
/**
* @brief 返回编码器此时的脉冲总数
* @param 无
* @retval CNT锁存值
*/
int16_t Encoder_GetValue(TIM_TypeDef *TIMx)
{
return TIM_GetCounter(TIMx);
}
/**
* @brief 定时器1中断处理器函数
* @param 无
* @retval 无
*/
void TIM1_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)//判断是否触发TIM2中断
{
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//判断是否触发TIM2中断
{
GuiStar_TIM2_IRQHandler();
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)//判断是否触发TIM2中断
{
GuiStar_TIM3_IRQHandler();
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//判断是否触发TIM2中断
{
GuiStar_TIM4_IRQHandler();
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
}