定时器常用功能配置函数

定时器常用功能配置函数:

本文提供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);
	}
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GuiStar_李什么恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值