4、stm32——定时器(TIM)

目录

目录

1、定时器简介(TIM)

简介:

定时器类型和功能

 三种定时器基本框图

1、高级定时器

2、通用定时器 

 3、基本定时器

2、定时器基本结构

3、预分频器时序图

计数器时序 

RCC时钟树 

4、初始化定时器的基本步骤

基本函数

5、定时中断和时钟源选择代码部分(定时器功能1)

定时器配置代码部分 

主函数(定时器中断——正点原子精英板)

6、输出比较OC(Output Compare)

PWM简介

输出比较通道(通用)

​编辑 输出比较通道(高级)

​编辑7、 输出比较模式汇总

8、PWM基本结构

参数计算

配置PWM

输出比较函数简要 

还没写完会继续更新


1、定时器简介(TIM)

简介:

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断

16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时

不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

定时器类型和功能

定时器类型和功能

类型编号总线功能
高级定时器TIM1、TIM8APB2拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器

TIM2、TIM3

TIM4、TIM5

APB1拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器TIM6、TIM7APB1拥有定时中断、主模式触发DAC的功能

在stm32f103c8t6中只有TIM1、TIM2、TIM3、TIM4

 三种定时器基本框图

1、高级定时器

高级定时器
高级定时器结构框图

重复次数计数器,可以控制每隔几个计数周期才发生一次中断,且可以给无刷电机输出PWM方波。 

2、通用定时器 

通用定时器结构框图

除了向上计数外,通用计数还有向下计数,中央对齐模式。 

 3、基本定时器

基本定时器结构框图

 分频器可以改变数值(0-不分频-72Mhz,1-2分频-36Mhz以此类推)

2、定时器基本结构

3、预分频器时序图

计数器计数频率:CK_CNT = CK_PSC / (PSC + 1) 

计数器时序 

计数器溢出频率:CK_CNT_OV  = CK_CNT / (ARR + 1)                           

                                                    = CK_PSC / (PSC + 1) / (ARR + 1) 

RCC时钟树 

4、初始化定时器的基本步骤

1.打开RCC时钟
2.选择时基单元的时钟源(内部时钟源)
3.配置时基单元(结构体)
4.配置输出中断控制,允许更新中断输出到NVIC
5.配置NVIC,打开定时器中断通道,设置优先级
6.运行控制,使能计数器。

基本函数

恢复缺省配置
void TIM_DeInit(TIM_TypeDef* TIMx);
时基单元初始化(一:选择某个计数器 二:时基单元结构体)
    
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
把结构体变量附一个默认值
    
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
使能计数器(运行控制用,一:选择定时器 二:状态(使能或者失能))
    
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
使能中断输出信号(一:选择定时器 二:配置那个中断输出 三:状态)(用于中断输出控制)
    
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
配置时基单元的时钟选择
    
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
选择选择ITRx其他定时器的时钟(一:选择定时器 二:选择要接入的其他定时器)
    
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

选择TIx捕获通道的时钟(一:选择定时器 二:选择TIx具体的某个引脚 三,四:输入的级性和滤波器)

void TIM_TIxExternalClockConfig(TIM_TypeDef* TIx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);
选择ETR通过外部时钟模式一通过的时钟( 一:选择定时器 二 外部触发分频器, 三,四:输入的级性和滤波器     
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
与上面的相同可以互换    
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
用于配置ETR引脚的预分频器,级性和滤波器    
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
一些修改函数
修改预分频值(一:定时器选择 二:预分频值 三:写入模式)
    
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
·改变计数器的计数模式
    
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
·自动重装器预装功能配置    
    
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
·给计数器写入一个值
    
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
·给自动重装器写一个值
    
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
·获取当前计数器的值
    
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
·获取当前预分频器的值
    
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

5、定时中断和时钟源选择代码部分(定时器功能1)

定时器配置代码部分 

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	//1.开启RCC时钟,定时器二在总线1上,所以要用APB1
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//2.选择时基单元的时钟源(内部时钟源)
	TIM_InternalClockConfig(TIM2);
	
	//3.配置时基单元(结构体)
	TIM_TimeBaseInitTypeDef TIMInitStructure;
	TIMInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
	TIMInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
	TIMInitStructure.TIM_Period = 10000 - 1;
	TIMInitStructure.TIM_Prescaler = 7200 - 1;//预分频值
	TIMInitStructure.TIM_RepetitionCounter = 0;//重装值
	TIM_TimeBaseInit(TIM2,&TIMInitStructure);
	
	//4.配置输出中断控制,允许更新中断输出到NVIC
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);//手动清楚更新标志位,不会出现进程序就进入中断的情况
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	//5.配置NVIC,打开定时器中断通道,设置优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//优先级设置
	
	NVIC_InitTypeDef NVICInitStructure;
	NVICInitStructure.NVIC_IRQChannelPreemptionPriority = 2;//通道抢占优先级
	NVICInitStructure.NVIC_IRQChannelSubPriority = 1;//优先级
	NVICInitStructure.NVIC_IRQChannelCmd = ENABLE;//
	NVICInitStructure.NVIC_IRQChannel = TIM2_IRQn;//定时器
	NVIC_Init(&NVICInitStructure);
	
	//6.运行控制,使能计数器
	TIM_Cmd(TIM2,ENABLE);
}


/*
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/

根据代码,定时器(TIM2)的中断触发时间间隔将会根据以下参数计算得出:

1. 预分频值(`TIM_Prescaler`):7200 - 1
2. 周期值(`TIM_Period`):10000 - 1

首先,计算实际应用于计数器的时钟频率:
时钟频率 = (输入时钟频率) / (预分频值 + 1)
          = (输入时钟频率) / (7200)

然后,计算每个计数周期所需的时间:
计数周期时间 = 1 / (实际应用于计数器的时钟频率)

最后,计算中断触发时间间隔:
中断触发时间间隔 = 计数周期时间 * 周期值
                           = (1 / 实际应用于计数器的时钟频率) * (周期值)

对于STM32F103ZE(c8t6也是一样的时钟频率),它的内部时钟(主时钟)为72 MHz。

根据之前的计算公式,使用预分频值7200和周期值10000-1,可以计算出中断触发时间间隔:

实际应用于计数器的时钟频率 = 72 MHz / (7200) = 10 kHz

计数周期时间 = 1 / 实际应用于计数器的时钟频率 = 1 / 10 kHz = 0.1 ms

中断触发时间间隔 = 计数周期时间 * 周期值 = 0.1 ms * (10000 - 1) ≈ 1 s

因此,根据给定的配置,定时器(TIM2)将在每秒触发一次中断。请注意,这里的计算结果可能会受到其他因素的影响,例如系统时钟的准确性和其他中断或操作的干扰。

主函数(定时器中断——正点原子精英板)

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "Buzzer.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "Timer.h"

int16_t Num;
unsigned int KeyNum;

int main(void)
{
	Timer_Init();
	u8 lcd_id[12];			//存放LCD ID字符串
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	LCD_Init();
	POINT_COLOR=RED;
	sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。	
	LCD_Clear(WHITE);
	POINT_COLOR=BLACK;	
  	while(1) 
	{		 
		
 		LCD_ShowString(30,70,200,16,16,lcd_id);		//显示LCD ID  	
		LCD_ShowNum(90,100,Num,5,16);				   		 

	} 
}

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

6、输出比较OC(Output Compare)

输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形

每个高级定时器和通用定时器都拥有4个输出比较通道

高级定时器的前3个通道额外拥有死区生成和互补输出的功能

PWM简介

PWM(Pulse Width Modulation)脉冲宽度调制 在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域 PWM参数:      

频率 = 1 / TS            占空比 = TON / TS           分辨率 = 占空比变化步距

 

占空比越大,所模拟的输出就越大。 

输出比较通道(通用)

 输出比较通道(高级)

7、 输出比较模式汇总

模式描述
冻结CNT=CCR时,REF保持为原状态
匹配时置有效电平CNT=CCR时,REF置有效电平
匹配时置无效电平CNT=CCR时,REF置无效电平
匹配时电平翻转CNT=CCR时,REF电平翻转
强制为无效电平CNT与CCR无效,REF强制为无效电平
强制为有效电平CNT与CCR无效,REF强制为有效电平
PWM模式1

向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平

向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平

PWM模式2

向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平

向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平

#define TIM_OCMode_Timing                  ((uint16_t)0x0000)

#define TIM_OCMode_Active                  ((uint16_t)0x0010)

#define TIM_OCMode_Inactive                ((uint16_t)0x0020)

#define TIM_OCMode_Toggle                  ((uint16_t)0x0030)

#define TIM_OCMode_PWM1                    ((uint16_t)0x0060)

#define TIM_OCMode_PWM2                    ((uint16_t)0x0070)

8、PWM基本结构

主要用PWM模式1和2,一般使用向上计数

参数计算

PWM频率:        Freq = CK_PSC / (PSC + 1) / (ARR + 1)

PWM占空比:    Duty = CCR / (ARR + 1)

PWM分辨率:    Reso = 1 / (ARR + 1)

配置PWM

1.配置TIM外设和GPIO外设的RCC时钟

2.配置时基单元

3.配置输出比较单元(结构体)

4.配置GPIO(复用推挽)

5.运行控制。

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	//1.配置TIM外设和GPIO外设的RCC时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//4.配置GPIO(复用推挽)
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIOInitStructure);
	
	//重映射
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//	GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	//2.配置时基单元
	TIM_InternalClockConfig(TIM2);//内部时钟配置
	
	
	//3.配置输出比较单元(结构体)
	TIM_TimeBaseInitTypeDef TIMInitStructure;
	TIMInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIMInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIMInitStructure.TIM_Period = 100 - 1;	//ARR
	TIMInitStructure.TIM_Prescaler = 720 - 1;	//PSC
	TIMInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIMInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//输出比较配置PWM1
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//高电平
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);
	
	//5.运行控制。
	TIM_Cmd(TIM2,ENABLE);
}

void PWM_SetCompare1(uint16_t Compare)//设置占空比
{
	TIM_SetCompare1(TIM2, Compare);
}

 其中重映射不用就是A0口,使用重映射就变成了A15,如下图。

输出比较函数简要 

输出比较单元配置函数(选择定时器,输出比较结构体)

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

·给输出比较结构体赋默认值

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);

·更改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);

9、输入捕获(IC(Input Capture))

输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数

每个高级定时器和通用定时器都拥有4个输入捕获通道

可配置为PWMI模式,同时测量频率和占空比

可配合主从触发模式,实现硬件全自动测量

1.RCC开启时钟(GPIO和TIM)

2.配置GPIO,把GPIO配置为输入模式,上拉或者浮空

3.配置时基单元,让cnt计数器在内部时钟的驱动下自增运行

4.配置输入捕获单元(结构体)

5.选择从模式的触发源

6.选择触发之后执行的操作

7.开启定时器

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	//1.RCC开启时钟(GPIO和TIM)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//2.配置GPIO,把GPIO配置为输入模式,上拉或者浮空
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_IPU;//下拉输入
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIOInitStructure);
	
	//3.配置时基单元,让cnt计数器在内部时钟的驱动下自增运行
	TIM_InternalClockConfig(TIM3);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//4.配置输入捕获单元(结构体)
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICFilter = 0xF;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	//5.选择从模式的触发源
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	
	//6.选择触发之后执行的操作
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	
	//7.开启定时器
	TIM_Cmd(TIM3, ENABLE);
}

uint32_t IC_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}

上述配置完成后我们就可以使用它进行测试了 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "Buzzer.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "PWM.h"
#include "IC.h"


uint8_t i;
unsigned int KeyNum;

int main(void)
{
	PWM_Init();
	IC_Init();
	u8 lcd_id[12];			//存放LCD ID字符串
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	//LED_Init();			     //LED端口初始化
	LCD_Init();
	POINT_COLOR=RED;
	sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。	
	LCD_Clear(WHITE);
	POINT_COLOR=BLACK;	
	
	PWM_SetPrescaler(720 - 1);			//Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);				//Duty = CCR / 100
	
	LCD_ShowString(30,90,200,16,16,"Freq:");
  	while(1) 
	{		 
		LCD_ShowString(30,70,200,16,16,lcd_id);		//显示LCD ID  					   		 
		LCD_ShowNum(60,90,IC_GetFreq(),15,16);
		
	} 
}

10、编码器测速

简单来说就是在编码器的使用上加入定时器,让定时器给我们做一个简单的加加操作,因为TIM定时器可以在产生脉冲的的时候崔cnt自增,所以可以把编码器的每一次操作记录下来并且每次自增和自减。 

#include "stm32f10x.h"                  // Device header

void Encoder_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
		
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	
	TIM_Cmd(TIM3, ENABLE);
}

int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3, 0);
	return Temp;
}

 然后再定时器函数中让编码器++就行了。

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Speed = Encoder_Get();
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值