旋轉編碼器是一種將旋轉位移轉換為一連串數字脈沖信號的旋轉式傳感器。這些脈沖用來控制角位移。讀數系統通常采用差分方式,即將兩個波形一樣但相位差為180°的不同信號進行比較,以便提高輸出信號的質量和穩定性。讀數是在兩個信號的差別基礎上形成的,從而消除了干擾。
1.模塊來源
模塊實物展示:
資料下載鏈接:https://pan.baidu.com/s/18pp1KaT2V_llizWvdIXtKA?pwd=8889
資料提取碼:8889
>>>
模塊的廠家資料下載請查看百度網盤鏈接
工作電壓:5V
工作電流:1MA
模塊尺寸:18 x 25 mm
旋轉角度: 360度
通信協議:相位差
3.移植過程
我們的目標是在立創·CW32F030C8T6開發板上能夠判斷旋轉方向、旋轉次數和是否按下的功能。首先要獲取資料,查看數據手冊應如何實現,再移植至我們的工程。
3.1查看資料
旋轉編碼器是通過兩個引腳的相位差,實現的旋轉方向判斷(以后的CLK引腳統一稱呼為A相,DT引腳為B相)
當是順時針旋轉時,A相超前B相90度,即A相為下降沿時,B相為低電平;A相為上升沿時,B相為高電平。
當是逆時針旋轉時,B相超前A相90度,即A相為下降沿時,B相為高電平;A相為上升沿時,B相為低電平。
而EC11按旋轉的輸出動作可以分為兩種。
一種是轉兩格,A、B端輸出一個完整脈沖(轉一格就只是由低電平->高電平或由高電平->低電平);
一種就是轉一格,A、B對C端輸出一個完整脈沖。
轉一格半個脈沖
轉一格完整脈沖
因此我們只需檢測A相或者B相有發生高低電平跳變時,就判斷另一相狀態,來決定旋轉方向。根據以下真值表,可以發現:
當兩相同時為上升沿或者同時為下降沿時,則為順時針;
當兩相不同時為上升沿或者不同時為下降沿時,則為逆時針;
下B相 右A相 | 上升沿 | 下降沿 |
---|---|---|
上升沿 | 順時針 | 逆時針 |
下降沿 | 逆時針 | 順時針 |
旋轉編碼器是機械結構的,是機械結構就避免不了在旋轉或者按下時有抖動,這里采用定時器每隔10ms掃描一次編碼器是否有動作,實現10ms內的消抖。
在中斷服務函數中,根據真值表確定旋轉的方向。
3.2引腳選擇
該模塊有5個引腳,具體引腳連接見 表 各引腳連接。
3.3移植至工程
打開自己的工程。(這里工程參考見入門手冊工程模板)
移植步驟中的導入.c和.h文件與第二章的第1小節【DHT11溫濕度傳感器】相同,只是將.c和.h文件更改為ec11.c與ec11.h。這里不再過多講述,移植完成后面修改相關代碼。
在文件ec11.c中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-19 LCKFB-LP first version */ #include "ec11.h" #include "stdio.h" /****************************************************************** * 函 數 名 稱:Encoder_GPIO_Init * 函 數 說 明:旋轉編碼器引腳初始化 * 函 數 形 參:無 * 函 數 返 回:無 * 作 者:LC * 備 注:使用定時器每10Ms掃描一次是否有旋轉,即通過定時器進行消抖 ******************************************************************/ void Encoder_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結構體 BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct; // 定時器初始化結構體 RCC_GPIO_ENABLE(); // 使能GPIO時鐘 BTIM_RCC_ENABLE(); // 使能BTIM時鐘 // 禁止中斷,以安全地配置NVIC __disable_irq(); // 開啟BTIM1中斷,并關聯到NVIC NVIC_EnableIRQ(BSP_TIMER_IRQ); // 允許中斷,恢復中斷狀態 __enable_irq(); GPIO_InitStruct.Pins = GPIO_ENCODER_SW| // GPIO引腳 GPIO_ENCODER_LCK| GPIO_ENCODER_DT; GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉輸入 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 輸出速度高 GPIO_Init(PORT_GPIO, &GPIO_InitStruct); // 初始化 // 配置定時器模式、周期和預分頻器 BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER; // 設置為定時器模式 BTIM_TimeBaseInitStruct.BTIM_Period = 625 - 1; // 設置周期,使得定時器每10ms產生一次溢出中斷 BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV1024; // 預分頻器設置為1024,以降低時鐘頻 // 使用上述配置初始化定時器BTIM1 BTIM_TimeBaseInit(BSP_TIMER, &BTIM_TimeBaseInitStruct); // 使能BTIM1的溢出中斷 BTIM_ITConfig(BSP_TIMER, BTIM_IT_OV, ENABLE); // 啟動定時器BTIM1 BTIM_Cmd(BSP_TIMER, ENABLE); } /****************************************************************** * 函 數 名 稱:Encoder_Scanf * 函 數 說 明:判斷旋轉編碼器是否有往哪一個方向旋轉 * 函 數 形 參:無 * 函 數 返 回:1=正轉 2=反轉 * 作 者:LC * 備 注:哪一邊正轉哪一邊反轉不需要太在意,你說的算 ******************************************************************/ char Encoder_Scanf(void) { static GPIO_PinState EC11_CLK_Last= GPIO_Pin_RESET; //EC11的LCK引腳上一次的狀態(A相) static GPIO_PinState EC11_DT_Last = GPIO_Pin_RESET; //EC11的DT引腳上一次的狀態(B相) char ScanResult = 0; //當A發生跳變時采集B當前的狀態,并將B與上一次的狀態進行對比。 if(GET_CLK_STATE !=EC11_CLK_Last) { //若A 0->1 時,B 1->0 正轉;若A 1->0 時,B 0->1 正轉; //若A 0->1 時,B 0->1 反轉;若A 1->0 時,B 1->0 反轉 if(GET_CLK_STATE == 1) //EC11_A和上一次狀態相比,為上升沿 { //EC11_B和上一次狀態相比,為下降沿 if((EC11_DT_Last == 1)&&(GET_DT_STATE == 0)) ScanResult = 1; //正轉 //EC11_B和上一次狀態相比,為上升沿 if((EC11_DT_Last == 0)&&(GET_DT_STATE == 1)) ScanResult = 2; //反轉 //>>>>>>>>>>>>>>>>下面為正轉一次再反轉或反轉一次再正轉處理<<<<<<< >>>>>>>>>>>>>>>下面為正轉一次再反轉或反轉一次再正轉處理<<<<<<<
在文件ec11.h中,編寫如下代碼。
/* * Change Logs: * Date Author Notes * 2024-06-19 LCKFB-LP first version */ #ifndef _BSP_ENCODER_H_ #define _BSP_ENCODER_H_ #include "board.h" #define RCC_GPIO_ENABLE() __RCC_GPIOA_CLK_ENABLE() #define PORT_GPIO CW_GPIOA //SW引腳 #define GPIO_ENCODER_SW GPIO_PIN_7 //CLK引腳 #define GPIO_ENCODER_LCK GPIO_PIN_6 //DT引腳 #define GPIO_ENCODER_DT GPIO_PIN_4 //獲取CLK引腳的狀態 #define GET_CLK_STATE GPIO_ReadPin(PORT_GPIO, GPIO_ENCODER_LCK) //獲取DT引腳的狀態 #define GET_DT_STATE GPIO_ReadPin(PORT_GPIO, GPIO_ENCODER_DT) //獲取SW引腳的狀態 #define GET_SW_STATE GPIO_ReadPin(PORT_GPIO, GPIO_ENCODER_SW) //定時器掃描 #define BTIM_RCC_ENABLE() __RCC_BTIM_CLK_ENABLE() // 使能定時器時鐘 #define BSP_TIMER CW_BTIM1 // 定時器 #define BSP_TIMER_IRQ BTIM1_IRQn // 定時器中斷 #define BSP_TIMER_IRQHANDLER BTIM1_IRQHandler // 定時器中斷服務函數 void Encoder_GPIO_Init(void);//旋轉編碼器初始化 unsigned char Encoder_Sw_Down(void);//編碼器是否按下 int Encoder_Rotation_left(void);//左轉服務函數 int Encoder_Rotation_right(void);//右轉服務函數 #endif
4.移植驗證
在自己工程中的main主函數中,編寫如下。
/* * Change Logs: * Date Author Notes * 2024-06-19 LCKFB-LP first version */ #include "board.h" #include "stdio.h" #include "bsp_uart.h" #include "ec11.h" int32_t main(void) { board_init(); // 開發板初始化 uart1_init(115200); // 串口1波特率115200 Encoder_GPIO_Init(); printf("encoder demo startrn"); while(1) { if( Encoder_Sw_Down() == 1 )//旋轉編碼器被按下 { printf("Encoder downrn"); } } }
移植現象:向右旋轉10次,向左旋轉10次,按下一次。
模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/18_4-IfR_pzyy1QvyQE7XkQ?pwd=LCKF
提取碼:LCKF
審核編輯 黃宇
-
旋轉編碼器
+關注
關注
5文章
156瀏覽量
25889 -
EC11
+關注
關注
0文章
5瀏覽量
8868 -
CW32
+關注
關注
1文章
168瀏覽量
502
發布評論請先 登錄
相關推薦
評論