【STM32学习】(22)STM32实现360度旋转编码器
360度 旋轉編碼器實物如下:
KY-040旋轉編碼器模塊
?工作電壓:5V
一圈脈沖數:20
旋轉編碼器可通過旋轉可以計數正方向和反方向轉動過程中輸出脈沖的次數,旋轉計數不像電位計,這種轉動計數是沒有限制的。配合旋轉編碼器上的按鍵,可以復位到初始狀態,即從0開始計數。
?工作原理:增量編碼器是一種將旋轉位移轉換為一連串數字脈沖信號的旋轉式傳感器。這些脈沖用來控制角位移。在Eltra編碼器中角位移的轉換采用了光電掃描原理。讀數系統以由交替的透光窗口和不透光窗口構成的徑向分度盤(碼盤)的旋轉為依據,同時被一個紅外光源垂直照射,光把碼盤的圖像投射到接收器表面上。接收器覆蓋著一層衍射光柵,它具有和碼盤相同的窗口寬度。接收器的工作是感受光盤轉動所產生的變化,然后將光變化轉換成相應的電變化。再使低電平信號上升到較高電平,并產生沒有任何干擾的方形脈沖,這就必須用電子電路來處理。讀數系統通常采用差分方式,即將兩個波形一樣但相位差為180°的不同信號進行比較,以便提高輸出信號的質量和穩定性。讀數是再兩個信號的差別基礎上形成的,從而消除了干擾。
增量編碼器給出兩相方波,它們的相位差90°,通常稱為A通道和B通道。其中一個通道給出與轉速相關的信息,與此同時,通過兩個通道信號進行順序對比,得到旋轉方向的信息。還有一個特殊信號稱為Z或零通道,該通道給出編碼器的絕對零位,此信號是一個方波與A通道方波的中心線重合。
?
現在實現檢測這個增量編碼器正轉還是反轉
我們這里用讀取IO的方式來讀取數據,來判斷是正轉還是反轉。
單片機型號:STM32L052K8*
接線:CLK? 接? PA0
? ? ? ? ? ? DT? ?接? PA1
? ? ? ? ? ? SW? 接? PA2
int main(void) {/* USER CODE BEGIN 1 */unsigned char dt;unsigned char clk,key;/* 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 */printf("\n\r****wantin****\n\r");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */printf("\n\**************\n\r");clk = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin);dt = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin);key = HAL_GPIO_ReadPin(SW_GPIO_Port,SW_Pin);if(1 == clk){printf("\n\clk == 1\n\r");}else{printf("\n\clk == 0\n\r");}if(1 == dt){printf("\n\dt == 1\n\r");}else{printf("\n\dt == 0\n\r");}if(1 == key){printf("\n\key == 1\n\r");}else{printf("\n\key == 0\n\r");}HAL_Delay(1000);}/* USER CODE END 3 */ }?
實現效果來看,不理想:
不管你正轉還是反轉,CLK和DT這兩個引腳的電平,都是成0、1交替,而且兩個的電平一致,根本無法區分正轉還是反轉。
隨后,將其插上電源,用示波器測試了一下這兩個引腳產生的波形。效果如下:
采集中斷0口,接的clk信號
正轉的波形圖:黃色的線為clk,藍色的線為dt
下降沿觸發,采集到的電平? 都為低電平? clk = 0? ?dt = 0;
反轉的波形圖:黃色的線為clk,藍色的線為dt
下降沿觸發,采集到的電平??clk = 0? ?dt = 1;
通過波形可以看出,正反轉是有波形區別的,如何實現正反轉檢測,可以使用中斷的方式來實現。
采用下降沿觸發方式來采集波形的變化。
int main(void) {/* USER CODE BEGIN 1 */unsigned char dt;unsigned char clk,key;/* 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 */printf("\n\r****wantin****\n\r");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */printf("\n\**************\n\r");if(10 == spped_counter){printf("\n\***正轉***\n\r");}else{printf("\n\***反轉***\n\r");} // clk = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin); // dt = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin); // key = HAL_GPIO_ReadPin(SW_GPIO_Port,SW_Pin); // if(1 == clk) // { // printf("\n\clk == 1\n\r"); // } // else // { // printf("\n\clk == 0\n\r"); // } // if(1 == dt) // { // printf("\n\dt == 1\n\r"); // } // else // { // printf("\n\dt == 0\n\r"); // } // if(1 == key) // { // printf("\n\key == 1\n\r"); // } // else // { // printf("\n\key == 0\n\r"); // }HAL_Delay(1000);}/* USER CODE END 3 */ } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //外部中斷 回調函數 {if(GPIO_Pin == CLK_Pin) //檢測到有變化就進來處理{if(HAL_GPIO_ReadPin(CLK_GPIO_Port,CLK_Pin) == HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin)) //clk pb0 == dt pb1spped_counter=10; // 表示 正轉elsespped_counter=100; // 表示 反轉} }?
?
效果如下:
?
?
?
總結
以上是生活随笔為你收集整理的【STM32学习】(22)STM32实现360度旋转编码器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工具使用:利用SRS和FFmpeg搭建流
- 下一篇: zigbee协议栈初使用(四)无线串口透