HAL STM32+EC11编码器实现增减调节及单击、双击、长按功能
- 📺实现效果演示:
📘内容提要
- 🔖验证对象:STM32F401
- 🍁EC11编码器部分的原理图:
🛠stm32cubemx配置
- 🔧将EC11中键引脚配置为输入模式、开启内部上拉模式,其余2个引脚配置为外部中断引脚(一个配置为下降沿中断,另外一个配置为上、下降沿中断,这一点很关键!)。
✅EC11编码器增减功能,通过外部中断实现
- 🌿外部中断回调处理函数:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
static uint8_t count = 0;
static uint8_t b_flag;
GPIO_PinState a_value = HAL_GPIO_ReadPin(EC11_A_GPIO_Port, EC11_A_Pin);
GPIO_PinState b_value = HAL_GPIO_ReadPin(EC11_B_GPIO_Port, EC11_B_Pin);
if(GPIO_Pin == EC11_A_Pin) {
if(a_value == RESET && count == 0) {
b_flag = 0;
if(b_value) b_flag = 1;
count = 1;
}
if(a_value == SET && count == 1) {
if(b_value == RESET && b_flag == 1) {
//开始逆时针转动
test_num--;
dir_flag = 1;
}
if(b_value && b_flag == 0) {
//开始顺时针转动
test_num++;
dir_flag = 0;
}
count = 0;
}
}
/* EC11中键,按键中断 */
// if(GPIO_Pin == EC11_KEY_Pin)
// {
// key_click_flag = 1;
// }
}
📓单击、双击、长按功能实现驱动代码
- 📝KEY.C
#include "key.h"
//代码来源网络 侵权联系删除
/*
--------------------------------------------------------------------
| short click |
| ______ ________ |
| | \ / | |
| | \_______________/ | |
| | | | | |
| |shake| < long |shake| |
| |
-------------------------------------------------------------------
| double click |
| ______ _____________ ____ |
| | \ / | | \ / | |
| | \_______________/ | | \_______________/ | |
| | | | | < max | | | | |
| |shake| < long |shake|dclick |shake| any time |shake| |
| |
--------------------------------------------------------------------
| long click |
| ______ ________ |
| | \ / | |
| | \_______________________________________/ | |
| | | | | |
| |shake| > long click |shake| |
| |
--------------------------------------------------------------------
*/
#define KEY_STATUS_DOWN_CHECK 0x00
#define KEY_STATUS_DOWN_SHAKE 0x01
#define KEY_STATUS_DOWN_HANDLE 0x02
#define KEY_STATUS_LONG_CHECK 0x03
#define KEY_STATUS_SHORT_UP_SHAKE 0x04
#define KEY_STATUS_DOUBLE_CHECK 0x05
#define KEY_STATUS_SHORT_UP_HANDLE 0x06
#define KEY_STATUS_DOUBLE_DOWN_SHAKE 0x07
#define KEY_STATUS_DOUBLE_UP_CHECK 0x08
#define KEY_STATUS_DOUBLE_UP_SHAKE 0x09
#define KEY_STATUS_DOUBLE_UP_HANDLE 0x0a
#define KEY_STATUS_LONG_HANDLE 0x0b
#define KEY_STATUS_CONTINUE_CHECK 0x0c
#define KEY_STATUS_LONG_UP_SHAKE 0x0d
#define KEY_STATUS_LONG_UP_HANDLE 0x0e
#define KEY_READ_DOWN 0x00 /* key is pressed */
#define KEY_READ_UP 0x01 /* Key isn't pressed */
#define KEY_BUF_SIZE 0x10 /* key value buffer size */
struct
{
unsigned short value[KEY_BUF_SIZE];
unsigned char rd;
unsigned char wr;
}key_buf;
struct key_dev
{
unsigned char status; /* state machine status */
unsigned char num; /* number */
unsigned short count_ms; /* ms counter */
unsigned short long_click_ms; /* long click check min time */
unsigned short shake_filter_ms; /* shake filter time */
unsigned short max_dclick_ms; /* double click max interval time */
unsigned short continue_send_ms; /* after long, continue send interval */
unsigned char (*read_key)(void); /* key read pin status function pointer*/
};
/******************************************************************************
User Interface [START]
*******************************************************************************/
unsigned char key0_read(void)
{
if (HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)
{
return KEY_READ_DOWN;
}
else
{
return KEY_READ_UP;
}
}
struct key_dev key_dev[] = {
{
KEY_STATUS_DOWN_CHECK,
KEY0_NUM,
0,
1500,
20,
300,
1000,
(unsigned char (*)(void))key0_read,