#include "encoder.h"
//A线作为时钟线,B线作为信号线
//*******************************************************************/
//功能:初始化EC11旋转编码器相关参数
//返回:无
//详解:对EC11旋转编码器的连接IO口做IO口模式设置。以及将相关的变量进行初始化
//*******************************************************************/
void Encoder_EC11_Init(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
GPIO_InitType.Mode = GPIO_MODE_INPUT;
GPIO_InitType.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitType.Pull = GPIO_NOPULL;//上拉输入
GPIO_InitType.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIOB, &GPIO_InitType);
GPIO_InitType.Pin = GPIO_PIN_8;
HAL_GPIO_Init(GPIOB, &GPIO_InitType);
// GPIO_InitType.Pin = GPIO_PIN_1;
// HAL_GPIO_Init(GPIOB, &GPIO_InitType);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8|GPIO_PIN_9,GPIO_PIN_SET);
//避免上电时EC11旋钮位置不确定导致一次动作误判
EC11_A_Last = EC11_A_Now;
EC11_B_Last = EC11_B_Now;
}
//*******************************************************************/
//功能:扫描EC11旋转编码器的动作并将参数返回给动作分析函数使用
//返回:EC11旋转编码器的扫描结果-->> int8_t ScanResult -->> 0:无动作;1:正转; -1:反转;2:只按下按键;3:按着按键正转;-3:按着按键反转
//详解:只扫描EC11旋转编码器有没有动作,不关心是第几次按下按键或长按或双击。返回值直接作为形参传给Encoder_EC11_Analyze()函数使用
//*******************************************************************/
int8_t Encoder_EC11_Scan(void)
{
//以下储存A、B上一次值的变量声明为静态全局变量,方便对EC11对应的IO口做初始化
// static char EC11_A_Last = 0;
// static char EC11_B_Last = 0;
int8_t ScanResult = 0; //返回编码器扫描结果,用于分析编码器的动作
//返回值的取值: 0:无动作; 1:正转; -1:反转;
// 2:只按下按键; 3:按着按键正转; -3:按着按键反转
#if EC11_Type==0
//======================================================//
//================一定位对应一脉冲的EC11================//
//======================================================//
if(EC11_A_Now != EC11_A_Last) //以A为时钟,B为数据。正转时AB反相,反转时AB同相
{
if(EC11_A_Now == 0)
{
if(EC11_B_Now ==1) //只需要采集A的上升沿或下降沿的任意一个状态,若A下降沿时B为1,正转
ScanResult = 1; //正转
else //反转
ScanResult = -1;
}
EC11_A_Last = EC11_A_Now; //更新编码器上一个状态暂存变量
EC11_B_Last = EC11_B_Now; //更新编码器上一个状态暂存变量
}
#else
//======================================================//
//================两定位对应一脉冲的EC11=================//
//======================================================//
if(EC11_A_Now !=EC11_A_Last) //当A发生跳变时采集B当前的状态,并将B与上一次的状态进行对比。
{ //若A 0->1 时,B 1->0 正转;若A 1->0 时,B 0->1 正转;
//若A 0->1 时,B 0->1 反转;若A 1->0 时,B 1->0 反转
if(EC11_A_Now == 1) //EC11_A和上一次状态相比,为上升沿
{
if((EC11_B_Last == 1)&&(EC11_B_Now == 0)) //EC11_B和上一次状态相比,为下降沿
ScanResult = 1; //正转
if((EC11_B_Last == 0)&&(EC11_B_Now == 1)) //EC11_B和上一次状态相比,为上升沿
ScanResult = -1; //反转
//>>>>>>>>>>>>>>>>下面为正转一次再反转或反转一次再正转处理<<<<<<<<<<<<<<<<//
if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0)) //A上升沿时,采集的B不变且为0
ScanResult = 1; //正转
if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1)) //A上升沿时,采集的B不变且为1
ScanResult = -1; //反转
}
else //EC11_A和上一次状态相比,为下降沿
{
if((EC11_B_Last == 1)&&(EC11_B_Now == 0)) //EC11_B和上一次状态相比,为下降沿
ScanResult = -1; //反转
if((EC11_B_Last == 0)&&(EC11_B_Now == 1)) //EC11_B和上一次状态相比,为上升沿
ScanResult = 1; //正转
//>>>>>>>>>>>>>>>>下面为正转一次再反转或反转一次再正转处理<<<<<<<<<<<<<<<<//
if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0)) //A上升沿时,采集的B不变且为0
ScanResult = -1; //反转
if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1)) //A上升沿时,采集的B不变且为1
ScanResult = 1; //正转
}
EC11_A_Last = EC11_A_Now; //更新编码器上一个状态暂存变量
EC11_B_Last = EC11_B_Now; //更新编码器上一个状态暂存变量
}
#endif
// if(EC11_Key == 0) //如果EC11的按键按下,并且没有EC11没有转动,
// {
// if(ScanResult == 0) //按下按键时未转动
// ScanResult = 2; //返回值为2
// else
// {
// if(ScanResult == 1) //按下按键时候正转
// ScanResult = 3; //返回值为3
// if(ScanResult == -1) //按下按键时候反转
// ScanResult = -3; //返回值为-3
// }
// }
return ScanResult; //返回值的取值: 0:无动作; 1:正转; -1:反转;
}
#ifndef __ENCODER_H
#define __ENCODER_H
#include "stm32f4xx_hal.h"
//----------------IO口定义----------------//
#define EC11_A_Now HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9) //EC11的A引脚,视为时钟线
#define EC11_B_Now HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) //EC11的B引脚,视为信号线
#define EC11_Key HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15) //EC11的按键
//----------------局部文件内变量列表----------------//
static char EC11_A_Last = 0; //EC11的A引脚上一次的状态
static char EC11_B_Last = 0; //EC11的B引脚上一次的状态
#define EC11_Type 0
//存EC11的类型---->>>>---- 0:一定位对应一脉冲; 1:两定位对应一脉冲
//所谓一定位对应一脉冲,是指EC11旋转编码器每转动一格,A和B都会输出一个完整的方波。
//而两定位对应一脉冲,是指EC11旋转编码器每转动两格,A和B才会输出一个完整的方波,只转动一格只输出A和B的上升沿或下降沿
void Encoder_EC11_Init(void);
int8_t Encoder_EC11_Scan(void);
#endif
标签:编码器,Last,正转,EC11,stm32,GPIO,Now
From: https://blog.csdn.net/weixin_72569529/article/details/140376181