1:简历
Encoder Interface 编码器接口
编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度
每个高级定时器和通用定时器都拥有1个编码器接口
两个输入引脚借用了输入捕获的通道1和通道2
2: 正交编码器
当编码器旋转起来的时候, 会输出下面的方波信号
3:编码器接口基本结构
编码器接口,都是上升沿和下降沿都有效的 , 上升沿和下降沿都需要计次 , 所以在编码器接口模式下 , 边沿检测极性选择就不再是边沿的极性选择了 , 而是高低电平的极性选择.
选择上升沿的参数------就是信号直通过来,高低电平极性不反转---5:极性不反转
选择下升沿的参数-------就是信号通过一个非门过来,高低电平极性反转----5:极性反转
4:编码器的工作模式
正转的状态都向上计数, 反转的状态都向下计数----TIM_EncoderMode_TI12
上面的2个模式--只在一个计数
5:极性反转
均不反转
TI1反转
6:HAL配置
极性选择:x.TriggerPolarity ---决定了我们是哪个电频触发脉冲信号。
二:代码
A:按键计次
我们的按键一段接低电平,一段接32的O口。所以不按下的时候为高电平,按下为低电平。所以我们选择下降沿
通道:
#include "stm32f1xx_hal.h"
#include "rcc.h"
TIM_HandleTypeDef PA0TIM2CH1Handleinit;
TIM_HandleTypeDef asd;
void IC_encoder_Init(uint16_t psc)
{
TIM_SlaveConfigTypeDef ConfigTypeDef={0};
PA0TIM2CH1Handleinit.Instance=TIM2;
PA0TIM2CH1Handleinit.Init.Period=65535; //ARR自动重装载值
PA0TIM2CH1Handleinit.Init.Prescaler=psc; //预分频系数
PA0TIM2CH1Handleinit.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HAL_TIM_IC_Init(&PA0TIM2CH1Handleinit);
ConfigTypeDef.InputTrigger=TIM_TS_TI1FP1; //触发源 --通道1单边沿 TIM_TS_TI1F_ED TIM_TS_TI1FP1
ConfigTypeDef.SlaveMode=TIM_SLAVEMODE_EXTERNAL1; //从模式选择--外部时钟模式1
ConfigTypeDef.TriggerFilter=0; //滤波器设置
/*极性选择:决定了哪个沿的脉冲信号可以使得计数器加1,我们选择的是下降沿*/
ConfigTypeDef.TriggerPolarity=TIM_TRIGGERPOLARITY_FALLING; //极性选择--下降沿
//从模式配置
HAL_TIM_SlaveConfigSynchro(&PA0TIM2CH1Handleinit,&ConfigTypeDef);
//打开计数器
HAL_TIM_IC_Start(&PA0TIM2CH1Handleinit,TIM_CHANNEL_1);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
__HAL_RCC_GPIOA_CLK_ENABLE() ;
__HAL_RCC_TIM2_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
HAL_NVIC_SetPriority(TIM2_IRQn ,2,0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
GPIO_InitTypeDef GPIOTypeDefHandle;
GPIOTypeDefHandle.Mode=GPIO_MODE_AF_PP; /*复用推完输出*/
GPIOTypeDefHandle.Pin=GPIO_PIN_0;
GPIOTypeDefHandle.Pull=GPIO_PULLUP; //上拉
GPIOTypeDefHandle.Speed=GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&GPIOTypeDefHandle);
}
}
#include "stm32f1xx_hal.h"
#include "rcc.h"
#include "led.h"
#include "delay.h"
#include "OLED.h"
#include "wwdg.h"
#include "key.h"
#include "IC_encoder.h"
int main(void)
{
uint16_t oldnum;
uint16_t newnum;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
LED_Init(); /* LED初始化 */
LED_Exit_Init();
OLED_Init();
IC_encoder_Init(0);
KEY_Init();
OLED_ShowString(1, 1, "keystrokes:");
while (1)
{
//读取计数器的值
newnum=__HAL_TIM_GET_COUNTER(&PA0TIM2CH1Handleinit);
if(oldnum!=newnum)
{
oldnum=newnum;
OLED_ShowNum(2,1,newnum,6);
}
if(KEY_Scan())
{
//将计数器的值清零
__HAL_TIM_SET_COUNTER(&PA0TIM2CH1Handleinit,0);
}
}
}
B:编码器接口计次
这个代码是通过定时器的编码器接口,来自动计次;
之前的代码是通过触发外部中断 , 然后在中断函数里手动进行计次-----见02:STM32--EXTI外部中断
1:连接图
2:代码
见:10:HAL--定时器代码总结