/*
* @Description:
* @Version: 2.0
* @Author: lkc
* @Date: 2022-12-11 10:08:57
* @LastEditors: lkc
* @LastEditTime: 2022-12-11 16:56:33
*/
#include "includes.h"
/**
* @description: 编码器定时器初始化
* @detail:
* @param {uint32_t} counts 编码器分辨率
* @return {*}
* @author: lkc
*/
void TIM4_Encoder_Init(uint32_t counts)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
/* 初始化外设时钟以及gpio时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* 编码器AB 分别为6以及7 初始化为复用 */
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 设置复用功能 */
GPIO_PinAFConfig(GPIOB, GPIO_Pin_6, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_Pin_7, GPIO_AF_TIM4);
TIM_DeInit(TIM4);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
/* 这里很多人会初始化为编码器分辨率-1,相当于重载值,加载到编码器最大脉冲就置0
和TIM_SetAutoreload差不多,如果在多任务中可以通过计数值判断差值,判断正反转以及旋转距离位置
TIM_TimeBaseStructure.TIM_Period = counts - 1;
TIM_SetAutoreload(TIM4, counts - 1);
*/
/* 使用65535的好处个人是认为,可以每次读取脉冲的时候,不至于到重载值清零
很多多任务处理,读取脉冲没办法及时响应,当电机高速旋转可能会导致转了好几圈,无法对脉冲及时响应
*/
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
/* 提供滤波器以及死区时间,这里对于咱们的比较滤波器挺有用的 */
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
/* 重载值 */
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/* 编码器模式,这里的模式跟最终一圈的脉冲数是有联系的
分为三个模式,应该是这三个模式决定分辨率,1024线,如果是前两种应该是2048,第三种模式4096 为4倍频
触发方式:看似三个参数,上升沿 下降沿 和 双边沿,但是实际编码器模式应该是是否反相
通过配置理论上1024线 如果单纯记录上升沿 应该只有2048个脉冲,但是仍然是按照双边沿计算输出一圈脉冲4096
*/
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);//将结构体中的内容缺省输入
TIM_ICInitStructure.TIM_ICFilter = 6; //选择输入比较滤波器
TIM_ICInit(TIM4, &TIM_ICInitStructure);//将TIM_ICInitStructure中的指定参数初始化TIM3
//Reset counter
TIM4->CNT = 0;//
TIM_Cmd(TIM4, ENABLE); //启动TIM4定时器
/* I开启中断,主要是脉冲
简单讲一下这个脉冲的作用:当编码器旋转到固定位置,输出该脉冲,也就是旋转一圈固定位置输出
所以这个位置我们是可以过滤坏脉冲的
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 选择 EXTI 的信号源 */
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return;
}
【定时器】编码器定时器初始化详解
于 2022-12-11 17:00:05 首次发布