目录

目录

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、TIM8 APB2 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器

TIM2、TIM3

TIM4、TIM5

APB1 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器 TIM6、TIM7 APB1 拥有定时中断、主模式触发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);
	}
}

作者:风抓不住过往

物联沃分享整理
物联沃-IOTWORD物联网 » STM32定时器(TIM)详解

发表回复