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

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


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

📘内容提要

  • 📝本文主要实现,通过STM32 HAL库开发,实现的EC11编码器功能,按键结合状态机思想实现的拓展单击、双击、长按的综合功能。
  • 🗝该功能可以很方便实现移植,例如使用在OLED屏幕显示菜单上。
  • 🔖验证对象:STM32F401
  • 🍁编码器部分的原理图:
    在这里插入图片描述

🛠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,
    },
    /*
            .
            .
        user add other key 
            .
            .
    */
 
};


/******************************************************************************
                           User Interface [END]
*******************************************************************************/

static void key_write_value(unsigned short key_val);
static void key_status_down_check(struct key_dev *key_dev);
static void key_status_down_shake(struct key_dev *key_dev);
static void key_status_down_handle(struct key_dev *key_dev);
static void key_status_long_check(struct key_dev *key_dev);
static void key_status_short_up_shake(struct key_dev *key_dev);
static void key_status_double_check(struct key_dev *key_dev);
static void key_status_short_up_handle(struct key_dev *key_dev);
static void key_status_double_down_shake(struct key_dev *key_dev);
static void key_status_double_up_check(struct key_dev *key_dev);
static void key_status_double_up_shake(struct key_dev *key_dev);
static void key_status_double_up_handle(struct key_dev *key_dev);
static void key_status_long_hanle(struct key_dev *key_dev);
static void key_status_continue_check(struct key_dev *key_dev);
static void key_status_long_up_shake(struct key_dev *key_dev);
static void key_status_long_up_handle(struct key_dev *key_dev);
 
 
/**
description : write key vaule to buffer
param :  key_val - key value , (KEY_EVENT | KEY_NUMBER<<8) 
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_write_value(unsigned short key_val)
{   
    key_buf.value[key_buf.wr++] = key_val;
    key_buf.wr %= KEY_BUF_SIZE;
 
    /*
        overflow handle
    */
    if(key_buf.wr == key_buf.rd)
    {
        key_buf.rd++;
        key_buf.rd %= KEY_BUF_SIZE;
    }
}
 
/**
description : read key vaule from buffer
param : None
retval : key_val - key value , (KEY_EVENT | KEY_NUMBER<<8)
author : huohongpeng
data : 2017-03-02
*/
unsigned short key_read_value(void)
{
    unsigned short key_val;
 
    if(key_buf.wr == key_buf.rd)
    {
        key_val = KEY_EVENT_NULL;
    }
    else
    {
        key_val = key_buf.value[key_buf.rd++];
        key_buf.rd %= KEY_BUF_SIZE;
    }
 
    return key_val;
}
 
/**
description : check key whether press down
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_down_check(struct key_dev *key_dev)
{
    unsigned char key_read;
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_DOWN)
    {
        key_dev->status = KEY_STATUS_DOWN_SHAKE;
        key_dev->count_ms = 0;
    }
}
 
/**
description : filter shake after key pressed down
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_down_shake(struct key_dev *key_dev)
{
    unsigned char key_read;
 
    key_dev->count_ms++;
 
    if(key_dev->count_ms < key_dev->shake_filter_ms)
    {
        return;
    }
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_DOWN)
    {
        key_dev->status = KEY_STATUS_DOWN_HANDLE;
    }
    else
    {
        key_dev->status = KEY_STATUS_DOWN_CHECK;
    }
}
 
 
/**
description : key press down handle after pressed down filter shake  
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_down_handle(struct key_dev *key_dev)
{
    unsigned short key_val = key_dev->num<<8 | KEY_EVENT_DOWN;
    
    key_write_value(key_val);
 
    key_dev->status = KEY_STATUS_LONG_CHECK;
    key_dev->count_ms = 0;
 
}
 
/**
description : check key whether long click   
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_long_check(struct key_dev *key_dev)
{
    unsigned char key_read;
 
    key_dev->count_ms++;
    key_read = key_dev->read_key();
    
    if(key_dev->count_ms < key_dev->long_click_ms)
    {
        if(key_read == KEY_READ_UP)
        {
            key_dev->status = KEY_STATUS_SHORT_UP_SHAKE;                 
        }
 
        return;
    }
 
    key_dev->status = KEY_STATUS_LONG_HANDLE;            
    
}
 
/**
description : short cilck key up filter shake   
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_short_up_shake(struct key_dev *key_dev)
{
    unsigned char key_read;
    static unsigned short old = 0xffff;
 
    if(old == 0xffff)
    {
        old = key_dev->count_ms;
        key_dev->count_ms = 0;
    }
 
    key_dev->count_ms++;
 
    if(key_dev->count_ms < key_dev->shake_filter_ms)
    {
        return;
    }
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_UP)
    {
        key_dev->status = KEY_STATUS_DOUBLE_CHECK;
        key_dev->count_ms = 0;
    }
    else
    {
        key_dev->status = KEY_STATUS_LONG_CHECK;
        key_dev->count_ms += old;        
    }
 
    old = 0xffff;
}
 
/**
description : double cilck check. we consider double click event if key pressed 
              down when after short click up and within max double click interval
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_double_check(struct key_dev *key_dev)
{
    unsigned char key_read;
 
    key_dev->count_ms++;
    key_read = key_dev->read_key();
    
    if(key_dev->count_ms < key_dev->max_dclick_ms)
    {
        if(key_read == KEY_READ_DOWN)
        {
            key_dev->status = KEY_STATUS_DOUBLE_DOWN_SHAKE;
            key_dev->count_ms = 0;                 
        }
    }
    else
    {
        key_dev->status = KEY_STATUS_SHORT_UP_HANDLE;            
    }
 
}
 
/**
description : short click key up handle
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_short_up_handle(struct key_dev *key_dev)
{
    unsigned short key_val;
 
    key_val= key_dev->num<<8 | KEY_EVENT_SHORT;
    
    key_write_value(key_val);
 
    key_val= key_dev->num<<8 | KEY_EVENT_UP_SHORT;
    
    key_write_value(key_val);
 
    key_dev->status = KEY_STATUS_DOWN_CHECK;
}
 
/**
description : double click key down filter shake
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_double_down_shake(struct key_dev *key_dev)
{
    unsigned char key_read;
    static unsigned short old = 0xffff;
 
    if(old == 0xffff)
    {
        old = key_dev->count_ms;
        key_dev->count_ms = 0;
    }
 
    key_dev->count_ms++;
 
    if(key_dev->count_ms < key_dev->shake_filter_ms)
    {
        return;
    }
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_DOWN)
    {
        unsigned short key_val;
 
        key_val= key_dev->num<<8 | KEY_EVENT_DOUBLE;
    
        key_write_value(key_val);
 
        key_dev->status = KEY_STATUS_DOUBLE_UP_CHECK;
        key_dev->count_ms = 0;
    }
    else
    {
        key_dev->status = KEY_STATUS_DOUBLE_CHECK;
        key_dev->count_ms += old;        
    }
 
    old = 0xffff;
}
 
/**
description : double click key up check
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_double_up_check(struct key_dev *key_dev)
{
    unsigned char key_read;
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_UP)
    {
        key_dev->status = KEY_STATUS_DOUBLE_UP_SHAKE;
        key_dev->count_ms = 0;
    }
}
 
/**
description : double click key up filter shake
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_double_up_shake(struct key_dev *key_dev)
{
    unsigned char key_read;
 
    key_dev->count_ms++;
 
    if(key_dev->count_ms < key_dev->shake_filter_ms)
    {
        return;
    }
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_UP)
    {
        key_dev->status = KEY_STATUS_DOUBLE_UP_HANDLE;
    }
    else
    {
        key_dev->status = KEY_STATUS_DOUBLE_UP_CHECK;
    }
 
}
 
/**
description : double click key up handle
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_double_up_handle(struct key_dev *key_dev)
{
    unsigned short key_val;
 
    key_val= key_dev->num<<8 | KEY_EVENT_UP_DOUBLE;
    
    key_write_value(key_val);
 
    key_dev->status = KEY_STATUS_DOWN_CHECK;
}
 
/**
description : long click handle after long click check
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_long_hanle(struct key_dev *key_dev)
{
    unsigned short key_val;
 
    key_val= key_dev->num<<8 | KEY_EVENT_LONG;
    
    key_write_value(key_val);
 
    key_dev->status = KEY_STATUS_CONTINUE_CHECK;
    key_dev->count_ms = 0;
}
 
/**
description : continue send short click if long click time overflow
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_continue_check(struct key_dev *key_dev)
{
    unsigned char key_read;
    unsigned short key_val;
 
    key_dev->count_ms++;
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_UP)
    {
        key_dev->status = KEY_STATUS_LONG_UP_SHAKE;
    }
 
    if(key_dev->count_ms < key_dev->continue_send_ms)
    {
        return;
    }
 
    if(key_dev->continue_send_ms == 0)
    {
        return;
    }
  
    key_val= key_dev->num<<8 | KEY_EVENT_SHORT;
    
    key_write_value(key_val);
    key_dev->count_ms = 0;
}
 
/**
description : long click key up filter shake
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_long_up_shake(struct key_dev *key_dev)
{
    unsigned char key_read;
    static unsigned short old = 0xffff;
 
    if(old == 0xffff)
    {
        old = key_dev->count_ms;
        key_dev->count_ms = 0;
    }
 
    key_dev->count_ms++;
 
    if(key_dev->count_ms < key_dev->shake_filter_ms)
    {
        return;
    }
 
    key_read = key_dev->read_key();
 
    if(key_read == KEY_READ_UP)
    {
        key_dev->status = KEY_STATUS_LONG_UP_HANDLE;
    }
    else
    {
        key_dev->status = KEY_STATUS_CONTINUE_CHECK;
        key_dev->count_ms += old;      
    }
    
    old = 0xffff;
}
 
/**
description : long click key up filter handle
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_status_long_up_handle(struct key_dev *key_dev)
{
    unsigned short key_val;
 
    key_val= key_dev->num<<8 | KEY_EVENT_UP_LONG;
    
    key_write_value(key_val);
 
    key_dev->status = KEY_STATUS_DOWN_CHECK;
}
 
/**
description : run key state machine once every 1ms
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
*/
static void key_check_1ms(struct key_dev *key_dev)
{
    switch(key_dev->status)
    {
        case KEY_STATUS_DOWN_CHECK :
             key_status_down_check(key_dev);
             break;      
        case KEY_STATUS_DOWN_SHAKE : 
             key_status_down_shake(key_dev);
             break;           
        case KEY_STATUS_DOWN_HANDLE : 
             key_status_down_handle(key_dev);
             break;          
        case KEY_STATUS_LONG_CHECK : 
             key_status_long_check(key_dev);
             break;              
        case KEY_STATUS_SHORT_UP_SHAKE :  
             key_status_short_up_shake(key_dev);
             break;
        case KEY_STATUS_DOUBLE_CHECK :
             key_status_double_check(key_dev);
             break;
        case KEY_STATUS_SHORT_UP_HANDLE :
             key_status_short_up_handle(key_dev);
             break;
        case KEY_STATUS_DOUBLE_DOWN_SHAKE : 
             key_status_double_down_shake(key_dev);
             break;
        case KEY_STATUS_DOUBLE_UP_CHECK :
             key_status_double_up_check(key_dev);
             break;
        case KEY_STATUS_DOUBLE_UP_SHAKE :
             key_status_double_up_shake(key_dev);
             break;
        case KEY_STATUS_DOUBLE_UP_HANDLE :
             key_status_double_up_handle(key_dev);
             break;         
        case KEY_STATUS_LONG_HANDLE :
             key_status_long_hanle(key_dev);
             break;
        case KEY_STATUS_CONTINUE_CHECK : 
             key_status_continue_check(key_dev);
             break;
        case KEY_STATUS_LONG_UP_SHAKE : 
             key_status_long_up_shake(key_dev);
             break;
        case KEY_STATUS_LONG_UP_HANDLE :  
             key_status_long_up_handle(key_dev);
             break;
        default:
             key_dev->status = key_dev->status;
    }
}
 
/**
description : run all key state machine once every 1ms
param : key_dev - key device pointer
retval : None
author : huohongpeng
data : 2017-03-02
call :
       timer(1ms) interrupt handle 
*/
void key_check_all_loop_1ms(void)
{
    unsigned char key_num, i;
 
    key_num = sizeof(key_dev)/sizeof(struct key_dev);
 
    for(i = 0; i < key_num; i++)
    {
        key_check_1ms(&key_dev[i]);
    }
 
}


  • 📄KEY.h
#ifndef __key_H
#define __key_H

#ifdef __cplusplus
 extern "C" {
#endif 

#include "main.h"

#define shortmaxclickms (300)
#define shortminclickms (10)
#define longclickms (800)



#define KEY_EVENT_NULL                     0x0000  
#define KEY_EVENT_DOWN                     0x0001
#define KEY_EVENT_UP_SHORT                 0x0002  // 短按后松开事件
#define KEY_EVENT_UP_LONG                  0x0003  // 长按后松开事件
#define KEY_EVENT_UP_DOUBLE                0x0004  // 双击后松开事件
#define KEY_EVENT_SHORT                    0x0005
#define KEY_EVENT_LONG                     0x0006
#define KEY_EVENT_DOUBLE                   0x0007

#define KEY_READ_DOWN                        0x00  /* key is pressed          */
#define KEY_READ_UP                          0x01  /* Key isn't pressed       */ 


/******************************************************************************
                           User Interface [START]
*******************************************************************************/
 
#define KEY0_NUM                           0x0001
 
#define KEY0_DOWN               (KEY_EVENT_DOWN      | KEY0_NUM<<8)
#define KEY0_UP_SHORT           (KEY_EVENT_UP_SHORT  | KEY0_NUM<<8)
#define KEY0_UP_LONG            (KEY_EVENT_UP_LONG   | KEY0_NUM<<8)
#define KEY0_UP_DOUBLE          (KEY_EVENT_UP_DOUBLE | KEY0_NUM<<8)
#define KEY0_SHORT              (KEY_EVENT_SHORT     | KEY0_NUM<<8)
#define KEY0_LONG               (KEY_EVENT_LONG      | KEY0_NUM<<8) 
#define KEY0_DOUBLE             (KEY_EVENT_DOUBLE    | KEY0_NUM<<8)
 
 
 
/******************************************************************************
                           User Interface [END]
*******************************************************************************/


void key_check_all_loop_1ms(void);
unsigned short key_read_value(void);

#ifdef __cplusplus
}
#endif

#endif


🔱main函数中按键处理内容

#include "stdio.h"
#include "key.h"
int32_t test_num = 0;//支持正负数值增减
uint8_t dir_flag = 2; /*  方向标志 0: 顺时 1: 逆时 2: 未动*/
uint8_t key_click_flag = 0;//EC11 中键

unsigned short key_value;



int main(void)
{
    /* USER CODE BEGIN 1 */
    uint32_t tick2, tick3;
    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */
    uint32_t Main_Fosc = HAL_RCC_GetSysClockFreq();
    printf("Main_Fosc:%dHz \r\n", Main_Fosc);
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while(1) {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        if(dir_flag != 2) {
            switch(dir_flag) {
                case 0:
                    printf("顺时针转动\r\n");
                    break;
                case 1:
                    printf("逆时针转动\r\n");
                    break;
            }
            dir_flag = 2;
            printf("num: %d\n", test_num);
        }
        if(HAL_GetTick() - tick2 >= 1) {
            tick2 = HAL_GetTick();
            key_check_all_loop_1ms();
        }

        /* Key按键按下查询 */
        if(HAL_GetTick() - tick3 >= 10) {
            tick3 = HAL_GetTick();
            key_value = key_read_value();

            if(key_value == KEY0_UP_SHORT) {	//单击事件
                HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
                // 实现单击KEY
                test_num++;
                printf("Press 单击,num:%d\r\n", test_num);

            } else if(key_value == KEY0_UP_DOUBLE) {	//双击事件
                HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);

                test_num += 2;
                printf("\r\nDouble Press 双击,num:%d\r\n", test_num);
            } else if(key_value == KEY0_LONG) {	//长按事件
                printf("\r\nLong Press 长按\r\n");
                // 实现长按KEY
                test_num = 0;//清除编码器计数值
                printf("按键计数清零,num:%d\r\n", test_num);

            }
        }

    }
    /* USER CODE END 3 */
}

📚工程源码

链接:https://pan.baidu.com/s/1zTMkY8iEGSCu_gSavR_I3A?pwd=4m2q 
提取码:4m2q

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/347411.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

win下安装es可视化工具——elasticsearch head(win_Elasticsearch)

一、head简介 Elasticsearch Head是集群管理、数据可视化、增删改查、查询语句可视化工具。 二、node.js的安装 ElasticSearch-head 依赖于node.js 下面先安装node.js 下面是node.js下载地址http://nodejs.cn/download/&#xff1b; 下载后&#xff0c;就是一个安装包&#xf…

如何在Ubuntu安装配置SVN服务端并实现无公网ip访问内网资料库

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改au…

Java可以用于物联网的开发吗?

Java可以用于物联网的开发吗? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;J…

备忘录记事本内容转移到新手机的方法

在日常的工作和生活中&#xff0c;我习惯用备忘录来记录一切&#xff1a;工作的要点、买菜的清单、生活的琐事……这些看似微小的记录&#xff0c;却是我生活的重要组成部分。然而&#xff0c;每次换手机&#xff0c;我总是面临一个难题&#xff1a;如何将旧手机上的备忘录内容…

下沉市场哪些品牌正当红?“下沉同花顺”异军突起

文 | 螳螂观察 作者 | 易不二 2023年的消费市场&#xff0c;越来越多“农村包围城市”的下沉品牌&#xff0c;以亮眼的表现成为拉动消费复苏的主力军。 全球36000多家门店的蜜雪冰城&#xff0c;向港交所递表冲刺IPO&#xff1b;两大量贩零食巨头赵一鸣零食与零食很忙战略合…

一个响指,代码生成!华为云CodeArts Snap正式公测

月初&#xff0c;华为云CodeArts Snap正式开启公测&#xff0c;这是一款基于华为云研发大模型的智能化编程助手&#xff0c;旨在为开发者提供高效且智能的编程体验&#xff0c;提升研发人员的单兵作战能力。 如今&#xff0c;生成式AI爆发式增长&#xff0c;大模型商用节奏加快…

JVM/GC复习

JVM/GC JVM(java虚拟机)MATjstack(将正在运行的JVM的线程进行快照并且打印出来)死锁VisualVM工具(监控线程内存使用情况)JMX GC垃圾回收算法1.引用计数法2.标记清除发3.标记压缩算法4.复制算法5.分代算法 收集器1.串行垃圾收集器2.并行垃圾收集器2.CMS垃圾收集器 3.G1垃圾收集器…

威联通QNAP NAS结合cpolar内网穿透实现公网远程访问NAS中存储的文件

文章目录 推荐 前言1. 威联通安装cpolar内网穿透2. 内网穿透2.1 创建隧道2.2 测试公网远程访问 3. 配置固定二级子域名3.1 保留二级子域名3.2 配置二级子域名 4. 使用固定二级子域名远程访问 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣…

一文了解prettier

简介 eslint和prettier都是用来做代码格式化的&#xff0c;他们其中又分为npm包和vscode插件&#xff0c;顺序是&#xff1a;先有npm包再有vscode插件 eslint限制工具 作用&#xff1a; 检查代码规范变量声明是否调用是否有console.log()语句… 用法 新建index.js文件 //…

MySQL数据库的锁机制

目录 一、引言 二、锁的类型及作用 2.1 行级锁 2.2 间隙锁与临键锁 2.3 共享锁与排他锁 2.4 意向锁 2.5 表级锁 2.6 元数据锁 三、锁的管理与优化 3.1 合理设置事务隔离级别 3.2 避免长事务 3.3 索引优化 3.4 明确锁定范围 3.5 避免不必要的全表扫描 四、实战分…

JDBC数据库连接

JDBC(Java DataBase Connectivity)就是用Java语言操作关系型数据库的一套API JDBC的步骤固定&#xff0c;大体分为8个步骤&#xff0c;以MySQL数据库为例 1.创建工程并导入驱动jar包 2.注册驱动 注册驱动的目的是告诉代码要执行哪一个jar包 Class.forName(com.mysql.jdbc.D…

多尺度特征融合13种创新方案全面汇总,含2024年最新

前段时间和大佬朋友交流学术的时候&#xff0c;发现目前发论文最好用的2大创新方式一是加注意力机制&#xff0c;二是多尺度特征融合。上回我们讲过了加注意力机制&#xff0c;今天我们就来聊聊多尺度特征融合。 多尺度特征融合是一种在图像处理和CV中使用的技术&#xff0c;由…

05-Seata下SQL使用限制

不支持 SQL 嵌套不支持多表复杂 SQL(自1.6.0版本&#xff0c;MySQL支持UPDATE JOIN语句&#xff0c;详情请看不支持存储过程、触发器部分数据库不支持批量更新&#xff0c;在使用 MySQL、Mariadb、PostgreSQL9.6作为数据库时支持批量&#xff0c;批量更新方式如下以 Java 为例 …

大创项目推荐 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

网络协议与攻击模拟_09部署DHCP服务器

一、部署DHCP服务器 Windows server部署DHCP服务器 1、虚拟机网络架构理解 Vmware里面不同的虚拟机可以设置相同的Vmnet网络&#xff0c;也可以设置不同的Vmnet网络。两台虚拟机设置相同的Vmnet1网卡&#xff0c;可以看作为使用虚拟交换机将两台Vmnet1的虚拟机连接起来的。 …

在使用springboot框架式的的script无法通过${}来获取值

今天使用springboot框架做项目&#xff0c;想着来实现一下搜索的下拉框回显功能&#xff0c;然后就一直在报错误&#xff0c;关键是报的错误牛头不对马嘴&#xff0c;检查了一下后端代码&#xff0c;发现没什么问题&#xff0c;就把目光聚焦了.jsp页面的代码 <script type&…

xinput1_3.dll文件的几种修复办法以及修复xinput1_3.dll注意事项

xinput1_3.dll文件是DirectX的一部分&#xff0c;它在Windows系统中负责处理游戏控制器的输入。然而&#xff0c;有时候此文件可能会出现问题&#xff0c;导致游戏无法正常运行或启动。在本文中&#xff0c;将介绍多种解决xinput1_3.dll文件问题的方法&#xff0c;并对它们进行…

Linux本地部署MeterSphere测试平台并实现公网远程访问

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…

Java项目:基于SSM框架实现同城蔬菜配送管理系统(SSM+B/S架构+源码+数据库+毕业论文)

一、项目简介 本项目是一套ssm825基于SSM框架实现同城蔬菜配送管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&…

Go Zero微服务个人探究之路(十)实战走通微服务前台请求调用的一套流程model->rpc微服务->apiHTTP调用

前言 Go语言凭借低占用&#xff0c;高并发等优秀特性成为后台编程语言的新星&#xff0c;GoZero框架由七牛云技术副总裁团队编写&#xff0c;目前已经成为Go微服务框架里star数量最多的框架 本文记录讲述笔者一步步走通前台向后台发出请求&#xff0c;后台api调用rpc服务的相…