PC7: A相
PC9:B相
初始化:
void encoder_io_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
__HAL_RCC_GPIOC_CLK_ENABLE();/* Enable GPIOC clock */ GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Pin = GPIO_PIN_9 |GPIO_PIN_8;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PC.7 PC9 pin as input floating */
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING_FALLING;//GPIO_MODE_IT_FALLING;//GPIO_MODE_IT_RISING;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable and set EXTI line 4_15 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
外部中断:
void EXTI4_15_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
}
中断回调函数:
int16_t B_level, Cnt;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_7)
{
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0 && Cnt==0)//A相下降沿触发第一次中断
{
Cnt++;//计数值加一,表示已经触发了第一次中断
B_level=0;//读取B相电平,若为高电平则B_level置1,反之保持0
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9) == 1){
B_level=1;
}
}
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 1 && Cnt==1)//A相上升沿触发第二次中断
{
Cnt=0;//计数清零
if(B_level==1 && HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9) == 0){
g_p7++;//正转
}
if(B_level==0 && HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9) == 1){
g_p9++;//反转
}
}
}
}
注意:A相先判断下降沿
原理:
增加判断正、反转的条件,读取一个周期内的电平变化再进行判断。首先将最小系统板的PB0引脚与A相连接,触发方式选择上升/下降沿触发,用A相的输出信号来触发中断,然后在A相下降沿触发第一次中断后读取B相电平,紧接着A相上升沿触发第二次中断后读取B相电平,结合两次读取到的电平来判断是正转还是反转,这种检测方法和第二种方法的原理相同,即从A相的下降沿触发到上升沿触发期间,若B相电平发生了变化,则判定编码器转动,反之未转动,波形抖动时B相的电平保持不变,能够实现消抖。