国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32 EC11 旋轉(zhuǎn)編碼器

這篇具有很好參考價(jià)值的文章主要介紹了STM32 EC11 旋轉(zhuǎn)編碼器。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

**先給大家看看我選用的EC11元器件**

代碼在最后,復(fù)制可直接食用
stm32 ec11,stm32,單片機(jī),嵌入式硬件

stm32 ec11,stm32,單片機(jī),嵌入式硬件
以及我的電路圖

stm32 ec11,stm32,單片機(jī),嵌入式硬件

在研究EC11的時(shí)序之前首先要了解一點(diǎn),EC11按旋轉(zhuǎn)的輸出動(dòng)作可以分為兩種。一種是轉(zhuǎn)兩格,A、B對(duì)C端輸出一個(gè)完整脈沖(轉(zhuǎn)一格就只是由低電平->高電平或由高電平->低電平);另一種就是轉(zhuǎn)一格,A、B對(duì)C端輸出一個(gè)完整脈沖。

一定位一脈沖的EC11按測(cè)試電路圖的接法,在靜止的時(shí)候AB兩線輸出都是高電平。轉(zhuǎn)動(dòng)一格,AB兩線各自輸出一個(gè)低電平脈沖,然后又回到高電平狀態(tài)。對(duì)應(yīng)于EC11內(nèi)部AB兩個(gè)觸點(diǎn)開關(guān)的動(dòng)作為斷開–>閉合–>斷開。

兩定位一脈沖的EC11稍微復(fù)雜一些,轉(zhuǎn)動(dòng)一格只會(huì)輸出半個(gè)脈沖。靜止時(shí),AB觸點(diǎn)開關(guān)可以是斷開的也可以是閉合的。若初始狀態(tài)時(shí)AB都是高電平,轉(zhuǎn)動(dòng)一格就輸出從高電平到低電平的下降沿,隨后一直輸出低電平。對(duì)應(yīng)于EC11內(nèi)部AB兩個(gè)觸電開關(guān)的動(dòng)作為斷開–>閉合。
若初始狀態(tài)時(shí)AB都是低電平,轉(zhuǎn)動(dòng)一格就輸出從低電平到高電平的上升沿,隨后一直輸出低電平。對(duì)應(yīng)于EC11內(nèi)部AB兩個(gè)觸點(diǎn)開關(guān)的動(dòng)作為閉合–>斷開。
由于兩脈沖一定位的EC11會(huì)有兩種初始狀態(tài),寫驅(qū)動(dòng)程序就需要考慮多一些情況。再者,這類EC11在轉(zhuǎn)動(dòng)到內(nèi)部AB觸點(diǎn)一直閉合的時(shí)候,就相當(dāng)于把上拉電阻的另一端接地,無(wú)形中加大了系統(tǒng)的功耗(若外接10K上拉電阻到5V電源就是500uA的電流),這對(duì)于低功耗應(yīng)用來(lái)說(shuō)是非常不利的。
因此對(duì)于無(wú)特殊要求的人機(jī)輸入應(yīng)用來(lái)說(shuō),我都推薦使用一定位一脈沖的EC11。
當(dāng)然了,有一些質(zhì)量比較差的EC11會(huì)有一些額外的問題要考慮,例如開關(guān)的抖動(dòng)問題,例如轉(zhuǎn)動(dòng)定位不清晰,靜止時(shí)AB兩個(gè)觸點(diǎn)都要閉合或者都要斷開才對(duì),但是定位點(diǎn)不清晰,轉(zhuǎn)動(dòng)的角度不到位導(dǎo)致一個(gè)觸點(diǎn)已經(jīng)閉合(斷開)了,另一個(gè)觸點(diǎn)卻還保持在斷開(閉合)。對(duì)于這些問題我們?cè)诤竺嬖僮隹紤]。

時(shí)序圖

要寫驅(qū)動(dòng)程序,得先了解EC11的工作過(guò)程。使用邏輯分析儀(LA)抓取時(shí)序可以很方便的從單片機(jī)的角度了解EC11的工作過(guò)程并依此來(lái)編寫驅(qū)動(dòng)程序。
??EC11的編碼器部分有3個(gè)引腳,A,B,和C。通常可以把C端接GND,A,B端接到輸入上拉模式的IO口。可以取A或B任意一根線作為時(shí)鐘線,另一根作為信號(hào)輸出線。我個(gè)人習(xí)慣把A線作為時(shí)鐘線,B線作為信號(hào)線。
??本文中出現(xiàn)的邏輯分析儀抓取的時(shí)序圖中均是最上方通道為EC11的A線,視為時(shí)鐘;下方一個(gè)通道為EC11的B線,視為數(shù)據(jù)輸出。

stm32 ec11,stm32,單片機(jī),嵌入式硬件

就不啰嗦太多,我就直接上代碼,我使用STM32F103系列

#include "ec11.h"
#include "sys.h"

void TIM4_Int_Init(u16 arr,u16 psc)
{	
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//TIM2時(shí)鐘使能    
	TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計(jì)數(shù)模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據(jù)指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM7中斷,允許更新中斷

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級(jí)0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子優(yōu)先級(jí)2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根據(jù)指定的參數(shù)初始化VIC寄存器
	
	TIM_Cmd(TIM4,ENABLE);//開啟定時(shí)器4
}

//定時(shí)器4中斷服務(wù)程序		    
void TIM4_IRQHandler(void)
{ 	
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//是更新中斷
	{	 		
		Encoder_EC11_Analyze(Encoder_EC11_Scan());
		
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIM4更新中斷標(biāo)志    
	}	    
}

//*******************************************************************/
//功能:初始化EC11旋轉(zhuǎn)編碼器相關(guān)參數(shù)
//形參:EC11旋轉(zhuǎn)編碼器的類型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對(duì)應(yīng)一脈沖;1(或非0)----兩定位對(duì)應(yīng)一脈沖。
//返回:無(wú)
//詳解:對(duì)EC11旋轉(zhuǎn)編碼器的連接IO口做IO口模式設(shè)置。以及將相關(guān)的變量進(jìn)行初始化
//*******************************************************************/
void EC11_Init(unsigned char Set_EC11_TYPE)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //推挽輸出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_SetBits(GPIOB,GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);	

	//EC11類型選擇:0-一定位一脈沖;1-兩定位一脈沖
	if (Set_EC11_TYPE == 0)
	{
		EC11_Type = 0;
	}
	else
	{
		EC11_Type = 1;
	}
	//避免上電時(shí)EC11旋鈕位置不確定導(dǎo)致一次動(dòng)作誤判
	EC11_A_Last = EC11_A_Now;
	EC11_B_Last = EC11_B_Now;

	//--------清除按鍵計(jì)數(shù)器和標(biāo)志位--------//
	EC11_KEY_COUNT = 0;                     //EC11按鍵動(dòng)作計(jì)數(shù)器
	EC11_KEY_DoubleClick_Count = 0;         //EC11按鍵雙擊動(dòng)作計(jì)數(shù)器
	FLAG_EC11_KEY_ShotClick = 0;            //EC11按鍵短按動(dòng)作標(biāo)志
	FLAG_EC11_KEY_LongClick = 0;            //EC11按鍵長(zhǎng)按動(dòng)作標(biāo)志
	FLAG_EC11_KEY_DoubleClick = 0;          //EC11按鍵雙擊動(dòng)作標(biāo)志
		
	TIM4_Int_Init(9,7199);	//初始化定時(shí)器4 1ms中斷 
}



//*******************************************************************/
//功能:對(duì)EC11旋轉(zhuǎn)編碼器的動(dòng)作進(jìn)行分析,并作出相應(yīng)的動(dòng)作處理代碼
//形參:無(wú)
//返回:char AnalyzeResult = 0;目前無(wú)用。若在該函數(shù)里做了動(dòng)作處理,則函數(shù)的返回值無(wú)需理會(huì)
//詳解:對(duì)EC11旋轉(zhuǎn)編碼器的動(dòng)作進(jìn)行模式分析,是單擊還是雙擊還是長(zhǎng)按松手還是一直按下。形參從 [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] 函數(shù)傳入。在本函數(shù)內(nèi)修改需要的動(dòng)作處理代碼
//*******************************************************************/
char Encoder_EC11_Analyze(char EC11_Value)
{
	char AnalyzeResult = 0;
  static unsigned int TMP_Value = 0;  //中間計(jì)數(shù)值,用于連續(xù)長(zhǎng)按按鍵的動(dòng)作延時(shí)間隔
  //>>>>>>>>>>>>>>>>編碼器正轉(zhuǎn)處理程序<<<<<<<<<<<<<<<<//
  if(EC11_Value == 1) //正轉(zhuǎn)
  {
      //--------編碼器正轉(zhuǎn)動(dòng)作代碼--------//
     printf("正轉(zhuǎn)?。?)
  }
  //>>>>>>>>>>>>>>>>編碼器反轉(zhuǎn)處理程序<<<<<<<<<<<<<<<<//
  if(EC11_Value == 8)    //反轉(zhuǎn)
  {
      //--------編碼器反轉(zhuǎn)動(dòng)作代碼--------//
     printf("反轉(zhuǎn)?。?);
  }

	//>>>>>>>>>>>>>>>>編碼器按鍵按下并正轉(zhuǎn)處理程序<<<<<<<<<<<<<<<<//
	if(EC11_Value == 3)
	{
		//--------編碼器按鍵按下并正轉(zhuǎn)動(dòng)作代碼--------//
			
	}

	//>>>>>>>>>>>>>>>>編碼器按鍵按下并反轉(zhuǎn)處理程序<<<<<<<<<<<<<<<<//
	if(EC11_Value == 9)
	{
		//--------編碼器按鍵按下并反轉(zhuǎn)動(dòng)作代碼--------//
//		printf("按下反轉(zhuǎn)??!");
	}
	//>>>>>>>>>>>>>>>>編碼器按鍵按下處理程序<<<<<<<<<<<<<<<<//
	if(EC11_Value == 2)     //====檢測(cè)到按鍵按下====//
	{
		if(EC11_KEY_COUNT<10000)    //打開按鍵按下時(shí)間定時(shí)器
			 EC11_KEY_COUNT++;
		if(EC11_KEY_COUNT == KEY_COUNT_DESHAKING)   //按下按鍵時(shí)間到達(dá)消抖時(shí)間時(shí)
		{                                           //置位短按按鍵標(biāo)志
			FLAG_EC11_KEY_ShotClick = 1;	
		}
		if((EC11_KEY_DoubleClick_Count > 0)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME))   //松開按鍵后,又在定時(shí)器在雙擊時(shí)間內(nèi)按下按鍵
		{                                                                                               //置位雙擊按鍵標(biāo)志
			FLAG_EC11_KEY_DoubleClick = 1;
		}

		if(EC11_KEY_COUNT == KEY_COUNT_LONGTIME)    //按下按鍵時(shí)間到達(dá)長(zhǎng)按時(shí)間
		{                                           //置位長(zhǎng)按按鍵標(biāo)志并復(fù)位短按按鍵標(biāo)志
			FLAG_EC11_KEY_LongClick = 1;
			FLAG_EC11_KEY_ShotClick = 0;
		}
	}
	else                    //====檢測(cè)到按鍵松開====//     
	{
		if(EC11_KEY_COUNT < KEY_COUNT_DESHAKING)    //沒到消抖時(shí)長(zhǎng)就松開按鍵,復(fù)位所有定時(shí)器和按鍵標(biāo)志
		{	
			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)        //短按按鍵定時(shí)有效期間
      {
				if((FLAG_EC11_KEY_DoubleClick == 0)&&(EC11_KEY_DoubleClick_Count >= 0)) 
						EC11_KEY_DoubleClick_Count++;
				if((FLAG_EC11_KEY_DoubleClick == 1)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME))   //如果在規(guī)定雙擊時(shí)間內(nèi)再次按下按鍵
        {                                                                                               //認(rèn)為按鍵是雙擊動(dòng)作
					FLAG_EC11_KEY_DoubleClick = 2;
        }   
        if((FLAG_EC11_KEY_DoubleClick == 0)&&(EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME))    //如果沒有在規(guī)定雙擊時(shí)間內(nèi)再次按下按鍵
            FLAG_EC11_KEY_ShotClick = 0;                                                                //認(rèn)為按鍵是單擊動(dòng)作
       }
       if(FLAG_EC11_KEY_LongClick == 1)        //檢測(cè)到長(zhǎng)按按鍵松開
			 {
        FLAG_EC11_KEY_LongClick = 0;
			 }
     }
	}
    //>>>>>>>>>>>>>>>>編碼器按鍵分析處理程序<<<<<<<<<<<<<<<<//
	
	if(EC11_KEY_COUNT > KEY_COUNT_DESHAKING)    //短按按鍵延時(shí)到了時(shí)間
	{
		//短按按鍵動(dòng)作結(jié)束代碼
		if((FLAG_EC11_KEY_ShotClick == 0)&&(EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME)&&(EC11_KEY_COUNT < KEY_COUNT_LONGTIME))   //短按按鍵動(dòng)作結(jié)束代碼
    {
      //--------短按按鍵動(dòng)作結(jié)束代碼--------//
			EC11_NUM_SW++;
			if(EC11_NUM_SW >= 4)
				 EC11_NUM_SW = 1;
			AnalyzeResult = 1;
			
			//--------清除標(biāo)志位--------//
			EC11_KEY_COUNT = 0;
			EC11_KEY_DoubleClick_Count = 0;
			FLAG_EC11_KEY_DoubleClick = 0;
		}
    //雙擊按鍵動(dòng)作結(jié)束代碼
		if((FLAG_EC11_KEY_DoubleClick == 2)&&(EC11_KEY_DoubleClick_Count > 0)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //雙擊按鍵動(dòng)作結(jié)束代碼
    {
			//--------雙擊按鍵動(dòng)作結(jié)束代碼--------//
			if(EC11_NUM_SW == 5)
				 EC11_NUM_SW = 0;
			if(EC11_NUM_SW == 4)
				 EC11_NUM_SW = 5;
			if(EC11_NUM_SW <4)
			{
				EC11_NUM_SW = 4;
			}
			AnalyzeResult = 2;
			//--------清除標(biāo)志位--------//
			EC11_KEY_COUNT = 0;
			EC11_KEY_DoubleClick_Count = 0;
			FLAG_EC11_KEY_ShotClick = 0;
			FLAG_EC11_KEY_DoubleClick = 0;    
		}

		//連續(xù)長(zhǎng)按按鍵按下代碼
		if((FLAG_EC11_KEY_LongClick == 1)&&(EC11_KEY_COUNT >= KEY_COUNT_LONGTIME))  //連續(xù)長(zhǎng)按按鍵按下代碼
    {
			TMP_Value ++;
			if(TMP_Value % KEY_LONG_REPEAT_TIME == 0)
			{
				TMP_Value = 0;
				//-------連續(xù)長(zhǎng)按按鍵按下代碼--------//
				AnalyzeResult = 4;
			}
		}

		//長(zhǎng)按按鍵動(dòng)作結(jié)束代碼
		if((FLAG_EC11_KEY_LongClick == 0)&&(EC11_KEY_COUNT >= KEY_COUNT_LONGTIME))  //長(zhǎng)按按鍵動(dòng)作結(jié)束代碼
		{                                                                           
			//--------長(zhǎng)按按鍵按下動(dòng)作結(jié)束代碼--------//
			EC11_NUM_SW = 0;
			AnalyzeResult = 3;
			//--------清除標(biāo)志位--------//
			EC11_KEY_COUNT = 0;
		}
	}
	return AnalyzeResult;
}

//*******************************************************************/
//功能:掃描EC11旋轉(zhuǎn)編碼器的動(dòng)作并將參數(shù)返回給動(dòng)作分析函數(shù)使用
//形參:EC11旋轉(zhuǎn)編碼器的類型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對(duì)應(yīng)一脈沖;1(或非0)----兩定位對(duì)應(yīng)一脈沖
//返回:EC11旋轉(zhuǎn)編碼器的掃描結(jié)果-->>  char ScanResult  -->>  0:無(wú)動(dòng)作;1:正轉(zhuǎn); -1:反轉(zhuǎn);2:只按下按鍵;3:按著按鍵正轉(zhuǎn);-3:按著按鍵反轉(zhuǎn)
//詳解:只掃描EC11旋轉(zhuǎn)編碼器有沒有動(dòng)作,不關(guān)心是第幾次按下按鍵或長(zhǎng)按或雙擊。返回值直接作為形參傳給 [ void Encoder_EC11_Analyze(char EC11_Value); ] 函數(shù)使用
//*******************************************************************/
char Encoder_EC11_Scan()
{
		//以下儲(chǔ)存A、B上一次值的變量聲明為靜態(tài)全局變量,方便對(duì)EC11對(duì)應(yīng)的IO口做初始化
		//  static char EC11_A_Last = 0;
		//  static char EC11_B_Last = 0;
	char ScanResult = 0;    //返回編碼器掃描結(jié)果,用于分析編碼器的動(dòng)作
                          //返回值的取值:   0:無(wú)動(dòng)作;      1:正轉(zhuǎn);           8:反轉(zhuǎn);  
                          //                 2:只按下按鍵;  3:按著按鍵正轉(zhuǎn);   9:按著按鍵反轉(zhuǎn)
                          //======================================================//
	if(EC11_Type == 0)      //================一定位對(duì)應(yīng)一脈沖的EC11================//
	{                     	//======================================================//
		if(EC11_A_Now != EC11_A_Last)   //以A為時(shí)鐘,B為數(shù)據(jù)。正轉(zhuǎn)時(shí)AB反相,反轉(zhuǎn)時(shí)AB同相
		{
			if(EC11_A_Now == 0)
			{
				if(EC11_B_Now ==1)      //只需要采集A的上升沿或下降沿的任意一個(gè)狀態(tài),若A下降沿時(shí)B為1,正轉(zhuǎn)                    
					 ScanResult = 1;     //正轉(zhuǎn)
				else                    //反轉(zhuǎn)
					 ScanResult = 8;
			}
			EC11_A_Last = EC11_A_Now;   //更新編碼器上一個(gè)狀態(tài)暫存變量
			EC11_B_Last = EC11_B_Now;   //更新編碼器上一個(gè)狀態(tài)暫存變量
		}
	}   
                          //======================================================//
	else                    //================兩定位對(duì)應(yīng)一脈沖的EC11================//
	{                       //======================================================//
		if(EC11_A_Now !=EC11_A_Last)        //當(dāng)A發(fā)生跳變時(shí)采集B當(dāng)前的狀態(tài),并將B與上一次的狀態(tài)進(jìn)行對(duì)比。
		{                                   //若A 0->1 時(shí),B 1->0 正轉(zhuǎn);若A 1->0 時(shí),B 0->1 正轉(zhuǎn);
                                        //若A 0->1 時(shí),B 0->1 反轉(zhuǎn);若A 1->0 時(shí),B 1->0 反轉(zhuǎn)
			if(EC11_A_Now == 1)     					//EC11_A和上一次狀態(tài)相比,為上升沿
			{
				if((EC11_B_Last == 1)&&(EC11_B_Now == 0))   //EC11_B和上一次狀態(tài)相比,為下降沿
						ScanResult = 1;                         //正轉(zhuǎn)
        if((EC11_B_Last == 0)&&(EC11_B_Now == 1))   //EC11_B和上一次狀態(tài)相比,為上升沿               
            ScanResult = 8;                        //反轉(zhuǎn)
                //>>>>>>>>>>>>>>>>下面為正轉(zhuǎn)一次再反轉(zhuǎn)或反轉(zhuǎn)一次再正轉(zhuǎn)處理<<<<<<<<<<<<<<<<//
        if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))  //A上升沿時(shí),采集的B不變且為0
            ScanResult = 1;                                 //正轉(zhuǎn)
        if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))  //A上升沿時(shí),采集的B不變且為1
            ScanResult = 8;                                 //反轉(zhuǎn)
			}
			else                    //EC11_A和上一次狀態(tài)相比,為下降沿
			{
				if((EC11_B_Last == 1)&&(EC11_B_Now == 0))   //EC11_B和上一次狀態(tài)相比,為下降沿
						ScanResult = 8;                        //反轉(zhuǎn)
				if((EC11_B_Last == 0)&&(EC11_B_Now == 1))   //EC11_B和上一次狀態(tài)相比,為上升沿
						ScanResult = 1;                         //正轉(zhuǎn)
				//>>>>>>>>>>>>>>>>下面為正轉(zhuǎn)一次再反轉(zhuǎn)或反轉(zhuǎn)一次再正轉(zhuǎn)處理<<<<<<<<<<<<<<<<//
				if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))  //A上升沿時(shí),采集的B不變且為0
						ScanResult = 8;                                //反轉(zhuǎn)
				if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))  //A上升沿時(shí),采集的B不變且為1   
						ScanResult = 1;                                 //正轉(zhuǎn)
			}               
				EC11_A_Last = EC11_A_Now;   //更新編碼器上一個(gè)狀態(tài)暫存變量
				EC11_B_Last = EC11_B_Now;   //更新編碼器上一個(gè)狀態(tài)暫存變量
		}
	}                                                                       
	if(EC11_Key == 0)   //如果EC11的按鍵按下,并且沒有EC11沒有轉(zhuǎn)動(dòng),
	{
//		if(ScanResult == 0)         //按下按鍵時(shí)未轉(zhuǎn)動(dòng)
			 ScanResult = 2;         //返回值為2
//		else
//		{
//			if(ScanResult == 1)     //按下按鍵時(shí)候正轉(zhuǎn)
//				 ScanResult = 3;     //返回值為3
//			if(ScanResult == 8)    //按下按鍵時(shí)候反轉(zhuǎn)
//				 ScanResult = 9;    //返回值為-3
//		}
	}
    return ScanResult;      //返回值的取值:   0:無(wú)動(dòng)作;      1:正轉(zhuǎn);           8:反轉(zhuǎn);
}                           //             		 2:只按下按鍵;  3:按著按鍵正轉(zhuǎn);   9:按著按鍵反轉(zhuǎn)


#ifndef __ec11_H
#define __ec11_H


#include "sys.h"
#include "stm32f10x.h"

//----------------IO口定義----------------//
#define EC11_A_Now           PBin(9)                             //EC11的A引腳,視為時(shí)鐘線
#define EC11_B_Now           PBin(8)                           	 //EC11的B引腳,視為信號(hào)線
#define	EC11_Key             PBin(7)                           	 //EC11的按鍵


//----------------編碼器動(dòng)作代碼相關(guān)定義----------------//

static unsigned char EC11_NUM_SW = 0;

//----------------編碼器參數(shù)微調(diào)宏定義----------------//
#define EC11_SCAN_PERIOD_MS            1                            //EC11編碼器掃描周期
#define KEY_COUNT_DESHAKING         ( 10/EC11_SCAN_PERIOD_MS)       //按鍵消抖時(shí)間
#define KEY_COUNT_LONGTIME          (150/EC11_SCAN_PERIOD_MS)       //長(zhǎng)按按鍵判斷時(shí)間
#define KEY_COUNT_DUALCLICKTIME     (150/EC11_SCAN_PERIOD_MS)       //雙擊按鍵判斷時(shí)間
#define KEY_LONG_REPEAT_TIME        (200/EC11_SCAN_PERIOD_MS)       //長(zhǎng)按按鍵的回報(bào)率的倒數(shù),即一直長(zhǎng)按按鍵時(shí)響應(yīng)的時(shí)間間隔

//----------------局部文件內(nèi)變量列表----------------//
static  char    EC11_A_Last = 0;                        //EC11的A引腳上一次的狀態(tài)
static  char    EC11_B_Last = 0;                        //EC11的B引腳上一次的狀態(tài)
static  char    EC11_Type = 1;                          //定義變量暫存EC11的類型---->>>>----  0:一定位對(duì)應(yīng)一脈沖;  1:兩定位對(duì)應(yīng)一脈沖
//所謂一定位對(duì)應(yīng)一脈沖,是指EC11旋轉(zhuǎn)編碼器每轉(zhuǎn)動(dòng)一格,A和B都會(huì)輸出一個(gè)完整的方波。
//而  兩定位對(duì)應(yīng)一脈沖,是指EC11旋轉(zhuǎn)編碼器每轉(zhuǎn)動(dòng)兩格,A和B才會(huì)輸出一個(gè)完整的方波,只轉(zhuǎn)動(dòng)一格只輸出A和B的上升沿或下降沿

static   int    EC11_KEY_COUNT = 0;                     //EC11按鍵動(dòng)作計(jì)數(shù)器
static   int    EC11_KEY_DoubleClick_Count = 0;         //EC11按鍵雙擊動(dòng)作計(jì)數(shù)器
static  char    FLAG_EC11_KEY_ShotClick = 0;            //EC11按鍵短按動(dòng)作標(biāo)志
static  char    FLAG_EC11_KEY_LongClick = 0;            //EC11按鍵長(zhǎng)按動(dòng)作標(biāo)志
static  char    FLAG_EC11_KEY_DoubleClick = 0;          //EC11按鍵雙擊動(dòng)作標(biāo)志

//----------------函數(shù)快速調(diào)用(復(fù)制粘貼)列表----------------//
//
/*******************************************************************
void Encoder_EC11_Init(unsigned char Set_EC11_TYPE);        //初始化EC11旋轉(zhuǎn)編碼器IO口和類型以及變量初始化
char Encoder_EC11_Scan();                                   //掃描旋轉(zhuǎn)編碼器的動(dòng)作
void Encoder_EC11_Analyze(char EC11_Value);                 //分析EC11旋轉(zhuǎn)編碼器的動(dòng)作以及動(dòng)作處理代碼
******************************************************************/
//-------->>>>>>>>--------注意事項(xiàng):EC11旋轉(zhuǎn)編碼器的掃描時(shí)間間隔控制在1~4ms之間,否則5ms及以上的掃描時(shí)間在快速旋轉(zhuǎn)時(shí)可能會(huì)誤判旋轉(zhuǎn)方向--------<<<<<<<<--------//
//-------->>>>>>>>--------注意事項(xiàng):EC11旋轉(zhuǎn)編碼器的掃描時(shí)間間隔控制在1~4ms之間,否則5ms及以上的掃描時(shí)間在快速旋轉(zhuǎn)時(shí)可能會(huì)誤判旋轉(zhuǎn)方向--------<<<<<<<<--------//
//-------->>>>>>>>--------注意事項(xiàng):EC11旋轉(zhuǎn)編碼器的掃描時(shí)間間隔控制在1~4ms之間,否則5ms及以上的掃描時(shí)間在快速旋轉(zhuǎn)時(shí)可能會(huì)誤判旋轉(zhuǎn)方向--------<<<<<<<<--------//

//----------------函數(shù)聲明列表----------------//
//
//*******************************************************************/
//功能:初始化EC11旋轉(zhuǎn)編碼器相關(guān)參數(shù)
//形參:EC11旋轉(zhuǎn)編碼器的類型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對(duì)應(yīng)一脈沖;1(或非0)----兩定位對(duì)應(yīng)一脈沖。
//返回:無(wú)
//詳解:對(duì)EC11旋轉(zhuǎn)編碼器的連接IO口做IO口模式設(shè)置。以及將相關(guān)的變量進(jìn)行初始化
//*******************************************************************/
void EC11_Init(unsigned char Set_EC11_TYPE);

//*******************************************************************/
//功能:掃描EC11旋轉(zhuǎn)編碼器的動(dòng)作并將參數(shù)返回給動(dòng)作分析函數(shù)使用
//形參:EC11旋轉(zhuǎn)編碼器的類型-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對(duì)應(yīng)一脈沖;1(或非0)----兩定位對(duì)應(yīng)一脈沖
//返回:EC11旋轉(zhuǎn)編碼器的掃描結(jié)果-->>  char ScanResult  -->>  0:無(wú)動(dòng)作;1:正轉(zhuǎn); -1:反轉(zhuǎn);2:只按下按鍵;3:按著按鍵正轉(zhuǎn);-3:按著按鍵反轉(zhuǎn)
//詳解:只掃描EC11旋轉(zhuǎn)編碼器有沒有動(dòng)作,不關(guān)心是第幾次按下按鍵或長(zhǎng)按或雙擊。返回值直接作為形參傳給 [ void Encoder_EC11_Analyze(char EC11_Value); ] 函數(shù)使用
//*******************************************************************/

char Encoder_EC11_Scan(void);

//*******************************************************************/
//功能:對(duì)EC11旋轉(zhuǎn)編碼器的動(dòng)作進(jìn)行分析,并作出相應(yīng)的動(dòng)作處理代碼
//形參:無(wú)
//返回:char AnalyzeResult = 0;目前無(wú)用。若在該函數(shù)里做了動(dòng)作處理,則函數(shù)的返回值無(wú)需理會(huì)
//詳解:對(duì)EC11旋轉(zhuǎn)編碼器的動(dòng)作進(jìn)行模式分析,是單擊還是雙擊還是長(zhǎng)按松手還是一直按下。形參從 [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] 函數(shù)傳入。在本函數(shù)內(nèi)修改需要的動(dòng)作處理代碼
//*******************************************************************/
char Encoder_EC11_Analyze(char EC11_Value);

#endif

這個(gè)程序我只做了正轉(zhuǎn),反轉(zhuǎn)和按下,有需要自行修改,我這里利用的是定時(shí)器1毫秒掃描,所以刷新函數(shù)Encoder_EC11_Analyze(Encoder_EC11_Scan());我寫在中斷里面,初始化函數(shù) EC11_Init(1);在這里需要注意一定位對(duì)應(yīng)一脈沖;1(或非0)----兩定位對(duì)應(yīng)一脈沖,前面有說(shuō)過(guò)了,放心食用

轉(zhuǎn)自:https://www.jianshu.com/p/41fa67ecb248文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-781068.html

到了這里,關(guān)于STM32 EC11 旋轉(zhuǎn)編碼器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32單片機(jī)(五)第二節(jié):EXTI外部中斷練習(xí)2(旋轉(zhuǎn)編碼器計(jì)次)

    STM32單片機(jī)(五)第二節(jié):EXTI外部中斷練習(xí)2(旋轉(zhuǎn)編碼器計(jì)次)

    ?? 專欄簡(jiǎn)介:本專欄記錄了從零學(xué)習(xí)單片機(jī)的過(guò)程,其中包括51單片機(jī)和STM32單片機(jī)兩部分;建議先學(xué)習(xí)51單片機(jī),其是STM32等高級(jí)單片機(jī)的基礎(chǔ);這樣再學(xué)習(xí)STM32時(shí)才能融會(huì)貫通。 ?? 專欄適用人群 :適用于想要從零基礎(chǔ)開始學(xué)習(xí)入門單片機(jī),且有一定C語(yǔ)言基礎(chǔ)的的童鞋

    2024年02月11日
    瀏覽(25)
  • STM32單片機(jī)(五)第二節(jié):EXTI外部中斷練習(xí)(對(duì)射式紅外傳感器計(jì)次和旋轉(zhuǎn)編碼器計(jì)次)

    STM32單片機(jī)(五)第二節(jié):EXTI外部中斷練習(xí)(對(duì)射式紅外傳感器計(jì)次和旋轉(zhuǎn)編碼器計(jì)次)

    ?? 專欄簡(jiǎn)介:本專欄記錄了從零學(xué)習(xí)單片機(jī)的過(guò)程,其中包括51單片機(jī)和STM32單片機(jī)兩部分;建議先學(xué)習(xí)51單片機(jī),其是STM32等高級(jí)單片機(jī)的基礎(chǔ);這樣再學(xué)習(xí)STM32時(shí)才能融會(huì)貫通。 ?? 專欄適用人群 :適用于想要從零基礎(chǔ)開始學(xué)習(xí)入門單片機(jī),且有一定C語(yǔ)言基礎(chǔ)的的童鞋

    2024年02月09日
    瀏覽(28)
  • STM32移植LVGL+旋轉(zhuǎn)編碼器接口對(duì)接

    STM32移植LVGL+旋轉(zhuǎn)編碼器接口對(duì)接

    寫在前面:本菜鳥結(jié)合了許多大佬的文章,成功實(shí)現(xiàn)了基于LVGL的GUI設(shè)計(jì),小開心~淺淺記錄一下!~ 本文以單片機(jī)STM32F103VET6為核心,利用ST7796芯片驅(qū)動(dòng)分辨率為480*320的LCD液晶屏模塊,移植LVGL,對(duì)接顯示接口,對(duì)接外部接口——旋轉(zhuǎn)編碼器,完成以上兩步,就可以實(shí)現(xiàn)LVGL的顯

    2024年02月10日
    瀏覽(45)
  • STM32-微項(xiàng)目07-旋轉(zhuǎn)編碼器計(jì)數(shù)及測(cè)速

    STM32-微項(xiàng)目07-旋轉(zhuǎn)編碼器計(jì)數(shù)及測(cè)速

    一、微項(xiàng)目實(shí)現(xiàn)目標(biāo): 檢測(cè)旋轉(zhuǎn)編碼器模式下,檢測(cè)旋轉(zhuǎn)編碼器的轉(zhuǎn)動(dòng)計(jì)數(shù)值及轉(zhuǎn)速。并且區(qū)分轉(zhuǎn)向,一側(cè)轉(zhuǎn)動(dòng)增加cout,轉(zhuǎn)速值為正,一側(cè)轉(zhuǎn)動(dòng)減少count,轉(zhuǎn)速值為負(fù); ? 二、微項(xiàng)目硬件配置需求: 1,stm32F103C8T6核心板一塊 2,0.96寸OLED顯示,用于顯示計(jì)數(shù) 3,旋轉(zhuǎn)編碼器,

    2024年02月08日
    瀏覽(24)
  • 關(guān)于stm32旋轉(zhuǎn)編碼器計(jì)次亂跳問題(消抖)

    旋轉(zhuǎn)編碼器A口接GPIOB0,B口接GPIOB1。設(shè)置中斷類型為上升下降沿均觸發(fā)。 輸出是用0.96寸oled輸出 A腳設(shè)置為上升下降沿均會(huì)進(jìn)中斷,下降上升一個(gè)變換周期,判斷這個(gè)周期的A腳,B腳的始末狀態(tài),來(lái)判斷正反轉(zhuǎn)一次。 A口輸出的波形用來(lái)中斷,B口輸出的波形用來(lái)判斷正轉(zhuǎn)還是反轉(zhuǎn)

    2024年02月16日
    瀏覽(29)
  • 【STM32】HAL庫(kù)自學(xué)記錄-旋轉(zhuǎn)編碼器的使用

    【STM32】HAL庫(kù)自學(xué)記錄-旋轉(zhuǎn)編碼器的使用

    通過(guò)本文可學(xué)會(huì)兩種實(shí)現(xiàn)判斷旋轉(zhuǎn)編碼器正轉(zhuǎn)反轉(zhuǎn)的方法,可根據(jù)自己的應(yīng)用場(chǎng)景來(lái)選擇使用哪種方法。 1、芯片:STM32F103RCT6 2、STM32CubeMx軟件 3、IDE: MDK-Keil軟件 4、旋轉(zhuǎn)編碼器模塊 5、XCOM V1.4串口軟件 圖中C端為GND。 方向 :A相和B相相差一個(gè)相位,一般來(lái)說(shuō)是90°。A相信號(hào)在

    2024年02月11日
    瀏覽(27)
  • 【STM32】STM32學(xué)習(xí)筆記-對(duì)射式紅外傳感器計(jì)次 旋轉(zhuǎn)編碼器計(jì)次(12)

    【STM32】STM32學(xué)習(xí)筆記-對(duì)射式紅外傳感器計(jì)次 旋轉(zhuǎn)編碼器計(jì)次(12)

    相關(guān)頭文件: misc.h 1.1 NVIC_PriorityGroupConfig函數(shù) 1.2 NVIC_PriorityGroup類型 1.3 NVIC_Init函數(shù) 1.4 NVIC_InitTypeDef類型 NVIC_IRQChannel取值 成員NVIC_IRQChannelPreemptionPriority可賦的值:最大取值15,具體有上面設(shè)置的優(yōu)先級(jí)組中規(guī)定的位數(shù)決定 成員NVIC_IRQChannelSubPriority可賦的值:最大取值15,具體有

    2024年01月15日
    瀏覽(17)
  • stm32f103單片機(jī)—編碼器測(cè)速

    stm32f103單片機(jī)—編碼器測(cè)速

    stm32f103ZET6開發(fā)板(非指定) MG513P3012V型號(hào)電機(jī)(帶霍爾編碼器)(非指定) 此種測(cè)速方法要求單片機(jī)的定時(shí)器具有編碼器模式,對(duì)于stm32f1系列,具備編碼器模式的定時(shí)器有TIM1/2/3/4/5/8, 定時(shí)器使用通道1、2來(lái)實(shí)現(xiàn)編碼器功能 ,接線時(shí)注意把A/B相接到定時(shí)器通道1/2的引腳。 電

    2024年02月06日
    瀏覽(33)
  • (STM32)PWM輸出控制電機(jī)旋轉(zhuǎn)并且使用編碼器讀取脈沖數(shù)

    (STM32)PWM輸出控制電機(jī)旋轉(zhuǎn)并且使用編碼器讀取脈沖數(shù)

    目錄 ?前言 一、pwm輸出讓電機(jī)轉(zhuǎn)? 1.電機(jī)的接線說(shuō)明 2.驅(qū)動(dòng)的接線說(shuō)明 3.pwm輸出代碼 ?pwm.c pwm.h 4.輸出pwm控制電機(jī)旋轉(zhuǎn) 二、配置定時(shí)器編碼器模式 1.定時(shí)器編碼器模式 編碼器原理 編碼器相關(guān)的概念 2.編碼器模式——代碼部分 3.獲取脈沖數(shù) 三、定時(shí)讀取編碼器讀取的脈沖數(shù)

    2024年02月03日
    瀏覽(29)
  • STM32第五課:對(duì)射式紅外線傳感器計(jì)數(shù)和旋轉(zhuǎn)編碼器計(jì)數(shù)

    STM32第五課:對(duì)射式紅外線傳感器計(jì)數(shù)和旋轉(zhuǎn)編碼器計(jì)數(shù)

    1.1 產(chǎn)品特性 ?????????使用ITR9606高靈敏度槽型光耦器件,它由一個(gè)紅外發(fā)光二極管和一個(gè)NPN光電三極管組成,槽寬度為5mm。傳感器特設(shè)M3固定安裝孔,調(diào)節(jié)方向與固定方便易用,使用寬電壓LM393比較器,信號(hào)干凈,波形好,驅(qū)動(dòng)能力強(qiáng),超過(guò)15mA。廣泛用于電機(jī)轉(zhuǎn)速檢測(cè),

    2024年02月20日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包