樹莓派平臺的旋轉編碼開關編程使用例程

在電子產品的設計中,經常會用到旋轉編碼開關,也就是旋轉編碼器、數碼電位器、Rotary Encoder。它具有左轉、右轉功能,有些旋轉編碼開關還具有按下的功能。

樹莓派平臺的旋轉編碼開關編程使用例程

上圖就是一個帶有按鍵功能的旋轉編碼開關。上面的兩個引腳常態下是斷開的,當按下按鈕時這兩個引腳就接通了,所以可以當成普通的按鍵來用。下面的三個引腳中,一般是中間的引腳接地,兩邊的兩個引腳分別接上拉電阻後接MCU的兩個GPIO,當左右旋轉旋鈕時,這兩個引腳會有相應的脈衝輸出,MCU通過對這兩個脈衝判斷,可以獲取是正轉還是反轉,從而對設備進行相應的控制。

在本例程中,我將樹莓派的GPIO0,GPIO1,GPIO2配置成相應的功能,用來對旋轉編碼開關的狀態進行檢測。GPIO0檢測按鈕是否按下,GPIO1和GPIO2配合實現左右旋轉的檢測,在程序中分別命名為SWPin,RoAPin,RoBPin。下圖是樹莓派的GPIO引腳分配圖。

樹莓派平臺的旋轉編碼開關編程使用例程

實物圖如下:

樹莓派平臺的旋轉編碼開關編程使用例程

源代碼如下:

#include 
#include 
#include 
#include 
#include 
 
#define SWPin 0
#define RoAPin 1
#define RoBPin 2
 
static volatile int globalCounter = 0 ;
 
unsigned char flag;
unsigned char Last_RoB_Status;
unsigned char Current_RoB_Status;
 
void btnISR(void) //中斷服務程序(ISR),按下按鈕時出發中斷,該中斷服務的任務是對計數值進行清零
{
	globalCounter = 0;
}
 
void rotaryDeal(void)
{
	Last_RoB_Status = digitalRead(RoBPin);
 
	while(!digitalRead(RoAPin)){
		Current_RoB_Status = digitalRead(RoBPin);
		flag = 1;
	}
 
	if(flag == 1){
		flag = 0;
		if((Last_RoB_Status == 0)&&(Current_RoB_Status == 1)){
			globalCounter ++;	//向右旋轉一步,全局變量globalCounter加1
		}
		if((Last_RoB_Status == 1)&&(Current_RoB_Status == 0)){
			globalCounter --; //向左旋轉一步,全局變量globalCounter減1
		}
	}
}
 
int main(void)
{
	if(wiringPiSetup() < 0){
		fprintf(stderr, "Unable to setup wiringPi:%s\n",strerror(errno));
		return 1;
	}
 
	pinMode(SWPin, INPUT);
	pinMode(RoAPin, INPUT);
	pinMode(RoBPin, INPUT);
 
	pullUpDnControl(SWPin, PUD_UP); //將GPIO0設置為帶上拉電阻的模式
 
 if(wiringPiISR(SWPin, INT_EDGE_FALLING, &btnISR) < 0){ //設置中斷為下降沿觸發
		fprintf(stderr, "Unable to init ISR\n",strerror(errno));	
		return 1;
	}
	
	while(1){
		rotaryDeal();
		printf("%d\n", globalCounter);
	}
 
	return 0;
}

編譯程序:

gcc rotaryEncoder.c -lwiringPi

運行程序:

./a.out

當你順時針旋轉按鈕時,屏幕上打印出的globalCounter的值會增加;當你逆時針旋轉按鈕時,屏幕上打印出的globalCounter的值會減小;當你按下按鈕時,globalCounter的值會清零。


分享到:


相關文章: