旋转编码器与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.

}

猜你喜欢

转载自blog.csdn.net/jiyotin/article/details/85784034