1. 程式人生 > >旋轉編碼器與PIC微控制器介面

旋轉編碼器與PIC微控制器介面

轉載於www.viadean.com
在這裡插入圖片描述
旋轉編碼器 是一種輸入裝置,其幫助使用者與系統進行互動。它看起來更像是一個無線電電位器旋轉編碼器是一種輸入裝置, 可幫助使用者與系統互動。它看起來更像是一個無線電電位器, 但它輸出一系列脈衝, 這使得它的應用獨特。當編碼器的旋鈕旋轉時, 它以小步的形式旋轉, 這有助於它用於 stepper/servo 電機控制。

在本文中,我們將瞭解不同型別的旋轉編碼器及其工作原理。我們還將它與PIC微控制器PIC16F877A連線,並通過旋轉編碼器控制整數值,並在16 * 2 LCD螢幕上顯示其值。在本教程的最後, 您將會很樂意為您的專案使用旋轉編碼器。所以讓我們開始吧…。

旋轉編碼器及其型別

旋轉編碼器通常稱為軸編碼器。它是一個機電感測器, 這意味著它將機械運動轉換為電子脈衝, 或者換句話說, 它將角度位置或運動或軸位置轉換為數字或模擬訊號。它由一個旋鈕組成, 當旋轉時, 它將逐步移動, 併產生每個步驟具有預定寬度的脈衝列車序列。

市場上有很多種型別的旋轉編碼器, 設計師可以根據自己的應用選擇一種。下面列出了最常見的型別

增量編碼器

絕對編碼器

磁性編碼器

光學編碼器

鐳射編碼器

這些編碼器是基於輸出訊號和感測技術進行分類的, 增量編碼器和絕對編碼器是根據輸出訊號進行分類的, 磁編碼器和鐳射編碼器是基於感測技術進行分類的。此處使用的編碼器是增量型別的編碼器。

絕對編碼器即使在斷電後也會儲存位置資訊, 當我們再次對其通電時, 位置資訊也會可用。

另一種基本型別, 增量編碼器提供資料時, 編碼器更改它的位置。它無法儲存倉位資訊。

ky-040 旋轉編碼器夾頭及說明

ky-040 增量型旋轉編碼器的針腳如下所示。在這個專案中, 我們將與來自微晶片的流行微控制器 pic16f877a 介面這個旋轉編碼器。
在這裡插入圖片描述
前兩個引腳 (接地和 vcc) 用於為編碼器供電, 通常使用 + 5v 電源。除了以順時針和逆時針方向旋轉旋鈕外, 編碼器還具有一個開關 (活動低), 可通過按內旋鈕進行按壓。此開關的訊號是通過引腳 3 (sw) 獲得的。最後, 它有兩個輸出引腳 (dt 和 clk), 產生波形, 如下所述。我們以前把這個旋轉編碼器與 arduino 介面過。

旋轉編碼器的工作原理

輸出完全取決於內部銅墊, 提供與 gnd 和 vcc 與軸的連線。
在這裡插入圖片描述
旋轉編碼器有兩個部分。軸輪, 它與軸連線, 並根據軸的旋轉和完成電氣連線的底座順時針或逆時針旋轉。基座具有連線到 dt 或 clk 的埠或點, 這樣當軸輪旋轉時, 它將連線基點, 並在 dt 和 clk 埠上提供方波。

輸出將像軸旋轉時
在這裡插入圖片描述
兩個埠提供方波,但時序略有不同。因此,如果我們接受輸出為1和0,則只能有四個狀態,0 0,1 0,1 1,0 1.二進位制輸出的序列決定順時針轉動或逆時針轉動。例如,如果旋轉編碼器在空閒狀態下提供1 0並在此之後提供1 1,則意味著編碼器將其位置向順時針方向改變一步,但如果在空閒1 0之後提供0 0,則意味著軸一步一步地沿逆時針方向轉動其位置。
所需元件

現在是確定我們需要什麼介面旋轉編碼器與 pic 微控制器的時候了,

PIC16F877A

電阻器

1k電阻器

10k

4.7k電容器33pF陶瓷圓盤電容器 - 2個

20Mhz晶體

16x2顯示

旋轉編碼器

5V介面卡。

麵包板

連線線。

PIC16F877A旋轉編碼器介面電路圖
在這裡插入圖片描述

下面是根據電路圖連線元件後的最終設定圖:
在這裡插入圖片描述

在這裡插入圖片描述

我們使用單個1K電阻來代替LCD的對比度,而不是使用電位計。

程式碼說明

完整的PIC程式碼 在本專案的最後給出了 演示視訊,這裡我們將解釋程式碼的一些重要部分。如果您是PIC微控制器的就遵循我們的 新手,請PIC教程 從一開始。

正如我們之前討論的那樣,我們需要 檢查輸出並區分DT和CLK的二進位制輸出,因此我們建立了一個 if-else為操作部分。

if (Encoder_CLK != position){

            if (Encoder_DT != position){

           // lcd_com (0x01);

            counter++; // Increase the counter which will be printed on the lcd

            lcd_com (0xC0);

            lcd_puts("            ");

            lcd_com (0xC0);

            lcd_bcd(1,counter);

            }



            else{

          // lcd_com (0x01);

            lcd_com (0xC0);

            counter--; // decrease the counter

            lcd_puts("            ");

            lcd_com (0xC0);

            lcd_bcd(1,counter);

            //lcd_puts("Left");

            }       

        }

我們還需要在每一步上儲存位置。為此, 我們使用了一個儲存當前位置的變數 “position”。

position = Encoder_CLK; // It is to store the encoder clock position on the variable. Can be 0 or 1 

除此之外,還提供了一個選項,用於 通知開關按壓LCD上的。

if (Encoder_SW == 0)

{             

    sw_delayms(20); //debounce delay            

    if (Encoder_SW == 0)

          {                //lcd_com(1);                

                          //lcd_com(0xC0);                

                         lcd_puts ("switch pressed");

//                itoa(counter, value, 10);

//                lcd_puts(value);

            }

}

系統 _ init 函式用於初始化引腳 ito 操作、lcd 和儲存旋轉編碼器位置。

void system_init() 

    {    

        TRISB = 0x00; // PORT B as output, This port is used for LCD        

        TRISDbits.TRISD2 = 1;    

        TRISDbits.TRISD3 = 1;    

        TRISCbits.TRISC4 = 1;    

        lcd_init(); // This will Initialize the LCD    

       position = Encoder_CLK;// Sotred the CLK position on system init, before the while loop start.

}

lcd 功能寫在 lcd. h 庫上, 其中聲明瞭 lcd _ put ()、lcd _ cmd ()。

完整程式碼:


/*

 * File:   main.c

 * Author: Sourav Gupta

 *

 * Created on 18 Dec 2018, 18:57

 */



/*

 * Configuration Related settings. Specific for microcontroller unit.

 */

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)

#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)

#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)

#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)

#pragma config LVP = OFF         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)

#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)

#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)

#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000

/*

 * System Header files inclusions

 */



#include <xc.h>

//#include <string.h>

#include <stdlib.h>

#include "supporting c files/lcd.h"



#define Encoder_SW PORTDbits.RD2

#define Encoder_DT PORTDbits.RD3

#define Encoder_CLK PORTCbits.RC4



/*

 * Program flow related functions

 */

int counter; // It will hold the count of rotary encoder.

int position; // It will store the rotary encoder position.

void sw_delayms(unsigned int d);

int value[7];



/*

 * System Init Function

 */



void system_init ();



/* Main function single Thread*/

void main(void) {

    system_init();

    lcd_puts ("Circuit Digest");

    lcd_com(0xC0);

    counter = 0;

    while(1){

        lcd_com(0xC0);

        if (Encoder_SW == 0){

            sw_delayms(20);

            if (Encoder_SW == 0){

                //lcd_com(1);

                //lcd_com(0xC0);

                lcd_puts ("switch pressed");

//                itoa(counter, value, 10);

//                lcd_puts(value);

            }

        }                       

       if (Encoder_CLK != position){

            if (Encoder_DT != position){

               // lcd_com (0x01);

                counter++;

                lcd_com (0xC0);

                lcd_puts("                ");

                lcd_com (0xC0);

                lcd_bcd(1,counter);

            }

            else{

               // lcd_com (0x01);

                lcd_com (0xC0);

                counter--;

                lcd_puts("                ");

                lcd_com (0xC0);

                lcd_bcd(1,counter);

                //lcd_puts("Left");

            }           

        }

        position = Encoder_CLK;                



}



    return;

}



void sw_delayms(unsigned int d){

int x, y;

for(x=0;x<d;x++)

for(y=0;y<=1275;y++);

}



void system_init(){

    TRISB = 0x00; // PORT B as output, This port is used for LCD    

    TRISDbits.TRISD2 = 1;

    TRISDbits.TRISD3 = 1;

    TRISCbits.TRISC4 = 1;

    lcd_init(); // This will Initialize the LCD

    position = Encoder_CLK;// Sotred the CLK position on system init, before the while loop start.

}