EC11 Rotary Encoder Program Interpretation

Directory

foreword

Principle of EC11 Rotary Encoder

Encoder button press handler

Encoder key analysis processing program

There are deficiencies in the code and some improvements of its own

EC11.c

EC11.h


Preface

When I was learning the EC11 rotary encoder recently, I saw two high-quality articles (1, 2). You can read them first. The code written by the boss is very good, but in the process of handling, I found that the code still has some errors. And there are deficiencies (personal opinions), so I modified and improved it on the basis of the big brother’s code, and the corresponding functions can be realized after testing. So I plan to publish an article about the code interpretation of the big guys, so that novices can understand it faster. After all, I have read the code for a long time, so let’s get to the point!

The principle of EC11 rotary encoder

First of all, let’s briefly understand the working principle of EC11. EC11 uses a mechanical structure to output two square waves with different phases, A and B. When rotating clockwise, phase A leads phase B by 90 degrees, and when rotating counterclockwise, phase B leads phase A by 90 degrees. Its output signal is shown in the figure below.

There may be clutter in the real output square wave, which can be eliminated by hardware and software. Generally, hardware elimination is used, and RC filtering is used. The details are not here. If you want to go deeper, you can find relevant information by yourself (actually, I don’t know understand>-<). There is also a point that the rotary encoder has one positioning pulse and two positioning one pulses. This detailed explanation is explained in detail in the big guy article. (The rotary encoders we usually buy on Taobao usually have one positioning and one pulse, so the code in this chapter is about this selection of encoders)

Come up with a piece of code analysis on how to judge the forward and reverse. This piece of code cleverly uses the reversal of the old and new states to know the jump of the level, and then enters the judgment only when the A item is judged to be zero, and can simulate the detection of the falling edge to trigger the interrupt effect, and finally according to the B item The level will know whether it is forward rotation or reverse rotation at this time.

if (EC11_A_Now != EC11_A_Last) //Use A as clock and B as data. AB reverse phase during forward rotation, AB in phase during reverse rotation
 {
if (EC11_A_Now == 0)
{
if (EC11_B_Now == 1) //Only need to collect any state of the rising edge or falling edge of A, if B is 1 when A is falling edge, forward rotation
ScanResult = 1; //forward rotation
else // reverse
ScanResult = 2;
}
EC11_A_Last = EC11_A_Now; //Update the last status temporary storage variable of the encoder
EC11_B_Last = EC11_B_Now; //Update the last status temporary storage variable of the encoder
}

Encoder button press handler

?
//>>>>>>>>>>>>>>>>Encoder button press processing program<<<<<<<<<<<<<<<<<<//
if (EC11_Key == 0) //==== detect key press ====//
{
if (EC11_KEY_COUNT<10000) //Open the key press time timer
EC11_KEY_COUNT++;
if (EC11_KEY_COUNT > KEY_COUNT_DESHAKING) //When the time of pressing the key reaches the debounce time
{ //Set short press button flag
FLAG_EC11_KEY_ShotClick = 1;
}
if ((EC11_KEY_DoubleClick_Count > 0) & amp; & amp; (EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) // After releasing the key, press the key again within the double-click time of the timer
{ //Set the double-click button flag
FLAG_EC11_KEY_DoubleClick = 1;
}
if (EC11_KEY_COUNT > KEY_COUNT_LONGTIME) // Press the key to reach the long press time
{ //Set the long press button flag and reset the short press button flag
FLAG_EC11_KEY_LongClick = 1;
FLAG_EC11_KEY_ShotClick = 0;
}
}
else //==== detect that the button is released ====//
{
if (EC11_KEY_COUNT < KEY_COUNT_DESHAKING) //Release the key before the debounce time, reset all timers and key signs
{
EC11_KEY_COUNT = 0;
FLAG_EC11_KEY_ShotClick = 0;
FLAG_EC11_KEY_LongClick = 0;
FLAG_EC11_KEY_DoubleClick = 0;
EC11_KEY_DoubleClick_Count = 0;
}
else
{
if (FLAG_EC11_KEY_ShotClick == 1) //Short press the button timing is valid
{
if ((FLAG_EC11_KEY_DoubleClick == 0) & amp; & amp; (EC11_KEY_DoubleClick_Count >= 0))//Record the first press action, so that if you can press the second time within the specified time, you can execute the following line generation
{
EC11_KEY_DoubleClick_Count++;
}
if ((FLAG_EC11_KEY_DoubleClick == 1) & amp; & amp; (EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //If the key is pressed again within the specified double-click time
{ // Think of the button as a double-click action
FLAG_EC11_KEY_DoubleClick = 2;
}
if ((FLAG_EC11_KEY_DoubleClick == 0) & amp; & amp; (EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME)) //If the key is not pressed again within the specified double-click time
{
FLAG_EC11_KEY_ShotClick = 0;
} //Think the button is a click action
}
if (FLAG_EC11_KEY_LongClick == 1)//It is detected that the key is long pressed and released
{
Flag = 1;
}
}
}

?

Let’s take a brief look at the whole first. The two if statements of short press and long press should be easy to understand. As for why it should be set to zero when it is released, it is for the next section of the encoder key analysis and processing program, knowing that it has ended This action returns the corresponding flag bit. The double-click program is not executed when the if is pressed for the first time. After the release, EC11_KEY_DoubleClick_Count + + is continued to be pressed. At this time, the if statement is executed, and the FLAG_EC11_KEY_DoubleClick flag position can be set to 1, and the FLAG_EC11_KEY_DoubleClick = 2 can be released, so that know to complete the double-tap action.

encoder key analysis processing program

 if (EC11_KEY_COUNT > KEY_COUNT_DESHAKING) //Short press the key to delay the time
{
//Short press button action end code
if ((FLAG_EC11_KEY_ShotClick == 0) & amp; & amp; (FLAG_EC11_KEY_DoubleClick != 2) & amp; & amp; (FLAG_EC11_KEY_LongClick != 1)) //Short press button action end code
{
//--------Short press the button action end code --------//
ScanResult = 3;
//--------Clear flags--------//
EC11_KEY_COUNT = 0;
EC11_KEY_DoubleClick_Count = 0;
FLAG_EC11_KEY_DoubleClick = 0;
}
else if ((FLAG_EC11_KEY_LongClick == 1) & amp; & amp; (EC11_KEY_COUNT >= KEY_COUNT_LONGTIME)) //Continuously press the key to press the code
{
//-------Continuously press the button to press the code --------//
if (Flag == 0)
{
ScanResult = 5;
Flag = 2;
}
else if (Flag == 1)//Detect when the long press is released
{
Flag = 0;
//--------Clear flags--------//
EC11_KEY_COUNT = 0;
EC11_KEY_DoubleClick_Count = 0;
FLAG_EC11_KEY_ShotClick = 0;
FLAG_EC11_KEY_DoubleClick = 0;
}
}
//End code for double-click button action
if ((FLAG_EC11_KEY_DoubleClick == 2) & amp; & amp; (EC11_KEY_DoubleClick_Count > 0) & amp; & amp; (EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //End code of double-click button action
{
//--------Double-click button action end code--------//
ScanResult = 4;
//--------Clear flags--------//
EC11_KEY_COUNT = 0;
EC11_KEY_DoubleClick_Count = 0;
FLAG_EC11_KEY_ShotClick = 0;
FLAG_EC11_KEY_DoubleClick = 0;
}
}

The encoder button analysis and processing program can be compared with the previous program of the big brother. It is much simpler. I deleted some codes and added a long press to release the flag, so that only one long press output will be performed after the long press. After releasing it, you can enter the next long press output, which is the effect I think should be long press.

The deficiencies in the code and some improvements of your own

Based on the original author’s code, I modified and deleted some related functions and parameters, and some errors and parameters in the source code were not adjusted. For example, in the key analysis part of the source code, the forward and reverse processing and some functional codes are executed, and the codes of long press, short press and double click are subdivided in it, and the data is not directly called out completely, so I modified it The code, I only want to know a flag bit that I want to know that a certain program has been executed, and only return the corresponding data. For example, if I rotate forward, I will return a 1, and then execute the corresponding forward rotation in another program. If you want to implement a program, this function is more portable and less coupled. There are also some parameter setting modifications and some function abandonment, so I won’t say much here, and I will attach my own modified code at the end. The effect can be seen in the figure below, which is still very good (if you want the entire test code, Please leave a message or private message me).

EC11.c

#include "sys.h"

u8 Num = 5;
u8 Num1 = 6;

void TIM4_Int_Init(u16 arr, u16 psc)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//TIM2 clock enable
TIM_TimeBaseStructure.TIM_Period = arr; //Set the value of the auto-reload register period to load activity on the next update event
TIM_TimeBaseStructure.TIM_Prescaler = psc; //Set the prescaler value used as the divisor of the TIMx clock frequency
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Set clock division: TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM up counting mode
TIM_TimeBaseInit(TIM4, & amp;TIM_TimeBaseStructure); //Initialize the time base unit of TIMx according to the specified parameters
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //Enable the specified TIM7 interrupt and allow update interrupt

NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//Preemption priority 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //sub-priority 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ channel enable
NVIC_Init( & amp;NVIC_InitStructure); //Initialize the VIC register according to the specified parameters

TIM_Cmd(TIM4, ENABLE);//Start timer 4
}

//Timer 4 interrupt service routine
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//is update interruption
{
EC11_Hander(Encoder_EC11_Scan());

TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //Clear TIM4 update interrupt flag
}
}

//************************************************** *******************/
//Function: Initialize EC11 rotary encoder related parameters
//Formal parameter: type of EC11 rotary encoder -->> unsigned char Set_EC11_TYPE <<--: 0--one positioning corresponds to one pulse; 1 (or non-zero)--two positionings correspond to one pulse.
//return: none
//Detailed explanation: Set the IO port mode for the connection IO port of the EC11 rotary encoder. and initialize related variables
//************************************************** *******************/
void EC11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Push-pull output
GPIO_Init(GPIOA, & GPIO_InitStructure);

GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_2);

//Avoid an action misjudgment caused by the uncertain position of the EC11 knob when powering on
EC11_A_Last = EC11_A_Now;
EC11_B_Last = EC11_B_Now;

//--------Clear key counter and flag --------//
EC11_KEY_COUNT = 0; //EC11 key action counter
EC11_KEY_DoubleClick_Count = 0; //EC11 key double click action counter
FLAG_EC11_KEY_ShotClick = 0; //EC11 button short press action flag
FLAG_EC11_KEY_LongClick = 0; //EC11 button long press action flag
FLAG_EC11_KEY_DoubleClick = 0; //EC11 key double click action flag
\t
TIM4_Int_Init(9,7199); //Initialize timer 4 1ms interrupt

}
//************************************************** *******************/
//Function: realize the corresponding function according to the corresponding formal parameter EC11_Value
//Formal parameter: EC11_Value
//return: none
//Detailed explanation: the function encapsulation function of the rotary encoder, you can fill in the corresponding realized functions according to your own ideas
//************************************************** *******************/
void EC11_Hander(u8 EC11_Value)
{
if (EC11_Value == 1) //forward rotation
{
//--------Encoder forward rotation action code--------//
printf("forward!!");
Num++;
}
else if (EC11_Value == 2) // reverse
{
//--------encoder reverse action code--------//
printf("Reverse!!");
Num--;
}
else if (EC11_Value == 3) //press once
{
//--------Encoder button press once code--------//
printf("Press once!!");
Num1++;
}
else if (EC11_Value == 4) //double click
{
//--------Encoder button double-click code-------//
printf("Double click!!");
Num1--;
}
else if (EC11_Value == 5) //long press
{
//--------encoder button long press code-------//
printf("Long press!!");
}
}
//************************************************** *******************/
//Function: analyze the action of the EC11 rotary encoder, and make corresponding action processing code
//Formal parameters: none
// Returns: char AnalyzeResult = 0; currently useless. If action processing is done in this function, the return value of the function does not need to be ignored
//Detailed explanation: conduct mode analysis on the action of the EC11 rotary encoder, whether it is single-click or double-click, long-press and let go, or keep pressing. The formal parameters are passed in from the [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] function. Modify the required action processing code in this function
//************************************************** *******************/

//************************************************** *******************/
//Function: Scan the action of the EC11 rotary encoder and return the parameters to the action analysis function for use
//Formal parameter: type of EC11 rotary encoder -->> unsigned char Set_EC11_TYPE <<--: 0--one positioning corresponds to one pulse; 1 (or non-0)--two positionings correspond to one pulse
//Return: scan result of EC11 rotary encoder -->> char ScanResult -->> 0: no action; 1: forward rotation; -1: reverse rotation; 2: only press the button; 3: press the button to forward Turn; -3: press the button to reverse
//Detailed explanation: only scan whether the EC11 rotary encoder has any action, and don't care how many times the button is pressed or long-pressed or double-clicked. The return value is directly passed to the [ void Encoder_EC11_Analyze(char EC11_Value); ] function as a parameter
//************************************************** *******************/
char Encoder_EC11_Scan(void)
{
//The following variables that store the last values of A and B are declared as static global variables, which is convenient for initializing the corresponding IO port of EC11
// static char EC11_A_Last = 0;
// static char EC11_B_Last = 0;
char ScanResult = 0; //return the encoder scan result, used to analyze the action of the encoder
\t
//The value of the return value: 0: no action; 1: forward rotation; 2: reverse rotation;
// 3: Only press the button; 4: Double-click; 5: Long press
//================================================== ======//
              
if (EC11_A_Now != EC11_A_Last) //Take A as clock and B as data. AB reverse phase during forward rotation, AB in phase during reverse rotation
{
if (EC11_A_Now == 0)
{
if (EC11_B_Now == 1) //Only need to collect any state of the rising edge or falling edge of A, if B is 1 when A is falling edge, forward rotation
ScanResult = 1; //forward rotation
else // reverse
ScanResult = 2;
}
EC11_A_Last = EC11_A_Now; //Update the last status temporary storage variable of the encoder
EC11_B_Last = EC11_B_Now; //Update the last status temporary storage variable of the encoder
}

//>>>>>>>>>>>>>>>>Encoder button press processing program<<<<<<<<<<<<<<<<<<//
if (EC11_Key == 0) //==== detect key press ====//
{
if (EC11_KEY_COUNT<10000) //Open the key press time timer
EC11_KEY_COUNT++;
if (EC11_KEY_COUNT > KEY_COUNT_DESHAKING) //When the time of pressing the key reaches the debounce time
{ //Set short press button flag
FLAG_EC11_KEY_ShotClick = 1;
}
if ((EC11_KEY_DoubleClick_Count > 0) & amp; & amp; (EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //After releasing the key, press the key again within the double-click time of the timer
{ //Set the double-click button flag
FLAG_EC11_KEY_DoubleClick = 1;
}
if (EC11_KEY_COUNT > KEY_COUNT_LONGTIME) // Press the key to reach the long press time
{ //Set the long press button flag and reset the short press button flag
FLAG_EC11_KEY_LongClick = 1;
FLAG_EC11_KEY_ShotClick = 0;
}
}
else //==== detect that the button is released ====//
{
if (EC11_KEY_COUNT < KEY_COUNT_DESHAKING) //Release the key before the debounce time, reset all timers and key signs
{
EC11_KEY_COUNT = 0;
FLAG_EC11_KEY_ShotClick = 0;
FLAG_EC11_KEY_LongClick = 0;
FLAG_EC11_KEY_DoubleClick = 0;
EC11_KEY_DoubleClick_Count = 0;
}
else
{
if (FLAG_EC11_KEY_ShotClick == 1) //Short press the button timing is valid
{
if ((FLAG_EC11_KEY_DoubleClick == 0) & amp; & amp; (EC11_KEY_DoubleClick_Count >= 0))//Record the first press action, so that if you can press the second time within the specified time, you can execute the following line generation
{
EC11_KEY_DoubleClick_Count++;
}
if ((FLAG_EC11_KEY_DoubleClick == 1) & amp; & amp; (EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //If the key is pressed again within the specified double-click time
{ // Think of the button as a double-click action
FLAG_EC11_KEY_DoubleClick = 2;
}
if ((FLAG_EC11_KEY_DoubleClick == 0) & amp; & amp; (EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME)) //If the key is not pressed again within the specified double-click time
{
FLAG_EC11_KEY_ShotClick = 0;
} //Think the button is a click action
}
if (FLAG_EC11_KEY_LongClick == 1)//It is detected that the key is long pressed and released
{
Flag = 1;
}
}
}
//>>>>>>>>>>>>>>>>Encoder key analysis processing program<<<<<<<<<<<<<<<<<<//
if (EC11_KEY_COUNT > KEY_COUNT_DESHAKING) //Short press the button to delay the time
{
//Short press button action end code
if ((FLAG_EC11_KEY_ShotClick == 0) & amp; & amp; (FLAG_EC11_KEY_DoubleClick != 2) & amp; & amp; (FLAG_EC11_KEY_LongClick != 1)) //Short press button action end code
{
//--------Short press the button action end code --------//
ScanResult = 3;
//--------Clear flags--------//
EC11_KEY_COUNT = 0;
EC11_KEY_DoubleClick_Count = 0;
FLAG_EC11_KEY_DoubleClick = 0;
}
else if ((FLAG_EC11_KEY_LongClick == 1) & amp; & amp; (EC11_KEY_COUNT >= KEY_COUNT_LONGTIME)) //Continuously press the key to press the code
{
//-------Continuously press the button to press the code --------//
if (Flag == 0)
{
ScanResult = 5;
Flag = 2;
}
else if (Flag == 1)//Detect when the long press is released
{
Flag = 0;
//--------Clear flags--------//
EC11_KEY_COUNT = 0;
EC11_KEY_DoubleClick_Count = 0;
FLAG_EC11_KEY_ShotClick = 0;
FLAG_EC11_KEY_DoubleClick = 0;
}
}
//End code for double-click button action
if ((FLAG_EC11_KEY_DoubleClick == 2) & amp; & amp; (EC11_KEY_DoubleClick_Count > 0) & amp; & amp; (EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //End code of double-click button action
{
//--------Double-click button action end code--------//
ScanResult = 4;
//--------Clear flags--------//
EC11_KEY_COUNT = 0;
EC11_KEY_DoubleClick_Count = 0;
FLAG_EC11_KEY_ShotClick = 0;
FLAG_EC11_KEY_DoubleClick = 0;
}
}
return ScanResult;
}



EC11.h

#ifndef __ec11_H
#define __ec11_H

#include "sys.h"



//----------------IO port definition----------------//
#define EC11_A_Now PAin(2) //A pin of EC11, regarded as clock line
#define EC11_B_Now PAin(1) //The B pin of EC11 is regarded as a signal line
#define EC11_Key PAin(0) //key of EC11


//--------------encoder parameter fine-tuning macro definition----------------//
#define EC11_SCAN_PERIOD_MS 1 //EC11 encoder scan period
#define KEY_COUNT_DESHAKING ( 6/EC11_SCAN_PERIOD_MS) //Key debounce time
#define KEY_COUNT_LONGTIME (600/EC11_SCAN_PERIOD_MS) //Long press the button to determine the time
#define KEY_COUNT_DUALCLICKTIME (200/EC11_SCAN_PERIOD_MS) //Double-click the button to determine the time
#define KEY_LONG_REPEAT_TIME (200/EC11_SCAN_PERIOD_MS) //The reciprocal of the return rate of the long press button, that is, the response time interval when the button is pressed for a long time

//----------------variable list in local file----------------//
static char EC11_A_Last = 0; //The last state of the A pin of EC11
static char EC11_B_Last = 0; //The last state of the B pin of EC11
static char Flag = 0; //long press end glyph
//The so-called one position corresponds to one pulse, which means that each time the EC11 rotary encoder rotates one division, A and B will output a complete square wave.

static int EC11_KEY_COUNT = 0; //EC11 key action counter
static int EC11_KEY_DoubleClick_Count = 0; //EC11 key double click action counter
static char FLAG_EC11_KEY_ShotClick = 0; //EC11 button short press action flag
static char FLAG_EC11_KEY_LongClick = 0; //EC11 button long press action flag
static char FLAG_EC11_KEY_DoubleClick = 0; //EC11 button double click action flag

//----------------Function Quick Call (Copy-Paste) List----------------//
//
/**************************************************** *******************
void Encoder_EC11_Init(void); //Initialize EC11 rotary encoder IO port and type and variable initialization
char Encoder_EC11_Scan(); //The action of scanning the rotary encoder
void Encoder_EC11_Analyze(char EC11_Value); //Analyze the action and action processing code of EC11 rotary encoder
***************************************************** *****************/
//-------->>>>>>>>>------- Notes: The scanning time interval of the EC11 rotary encoder is controlled between 1~4ms, otherwise 5ms and above The scan time may misjudge the direction of rotation when rotating rapidly --------<<<<<<<<-------//
//-------->>>>>>>>>------- Notes: The scanning time interval of the EC11 rotary encoder is controlled between 1~4ms, otherwise 5ms and above The scan time may misjudge the direction of rotation when rotating rapidly --------<<<<<<<<-------//
//-------->>>>>>>>>------- Notes: The scanning time interval of the EC11 rotary encoder is controlled between 1~4ms, otherwise 5ms and above The scan time may misjudge the direction of rotation when rotating rapidly --------<<<<<<<<-------//

//----------------Function declaration list----------------//
//
//************************************************** *******************/
//Function: Initialize EC11 rotary encoder related parameters
//Formal parameter: type of EC11 rotary encoder -->> unsigned char Set_EC11_TYPE <<--: 0--one positioning corresponds to one pulse; 1 (or non-zero)--two positionings correspond to one pulse.
//return: none
//Detailed explanation: Set the IO port mode for the connection IO port of the EC11 rotary encoder. and initialize related variables
//************************************************** *******************/
void EC11_Init(void);

//************************************************** *******************/
//Function: Scan the action of the EC11 rotary encoder and return the parameters to the action analysis function for use
//Formal parameter: type of EC11 rotary encoder -->> unsigned char Set_EC11_TYPE <<--: 0--one positioning corresponds to one pulse; 1 (or non-0)--two positionings correspond to one pulse
//Return: scan result of EC11 rotary encoder -->> char ScanResult -->> 0: no action; 1: forward rotation; -1: reverse rotation; 2: only press the button; 3: press the button to forward Turn; -3: press the button to reverse
//Detailed explanation: only scan whether the EC11 rotary encoder has any action, and don't care how many times the button is pressed or long-pressed or double-clicked. The return value is directly passed to the [ void Encoder_EC11_Analyze(char EC11_Value); ] function as a parameter
//************************************************** *******************/

char Encoder_EC11_Scan(void);

//************************************************** *******************/
//Function: analyze the action of the EC11 rotary encoder, and make corresponding action processing code
//Formal parameters: none
// Returns: char AnalyzeResult = 0; currently useless. If action processing is done in this function, the return value of the function does not need to be ignored
//Detailed explanation: conduct mode analysis on the action of the EC11 rotary encoder, whether it is single-click or double-click, long-press and let go, or keep pressing. The formal parameters are passed in from the [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] function. Modify the required action processing code in this function
//************************************************** *******************/
void EC11_Hander(u8 EC11_Value);

#endif