HAL STM32+EC11编码器实现增减调节及单击、双击、长按功能

HAL STM32+EC11编码器实现增减调节及单击、双击、长按功能


  • 📺实现效果演示:
    在这里插入图片描述

📘内容提要

  • 📝本文主要实现,通过STM32 HAL库开发,实现的EC11编码器功能,按键结合状态机思想实现的拓展单击、双击、长按的综合功能。单片机硬件上使用了2个外部中断引脚实现。
  • 🗝该功能可以很方便实现移植,例如使用在OLED屏幕显示菜单上。
  • 🔖验证对象: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,
好的,这里给您提供一个基于EC20HAL库连接MQTT服务器的C语言代码示例,仅供参考: ```c #include "stdio.h" #include <stdlib.h> #include "ec20_hal.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientSub" #define TOPIC "MQTT Examples" #define PAYLOAD "Hello World!" #define QOS 1 #define TIMEOUT 10000L int main(int argc, char *argv[]) { int rc = 0; EC20_HAL_Init(); // 初始化EC20模块 Network network; MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message msg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(-1); } printf("Connected to MQTT server\n"); MQTTClient_subscribe(client, TOPIC, QOS); while (1) { char payload[100] = {0}; int len = 0; if (EC20_HAL_MQTTReceive(&len, payload) == 0) // 从EC20接收MQTT消息 { msg.payload = payload; msg.payloadlen = len; msg.qos = QOS; msg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &msg, &token); printf("MQTT message published\n"); } } MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 注意,这只是一个简单的示例代码,您需要根据具体的需求进行修改和完善。同时,也需要根据您的具体开发环境和硬件平台进行适当的调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值