历史上的今天
返回首页

历史上的今天

今天是:2025年01月31日(星期五)

2020年01月31日 | 旋转编码器与PIC单片机接口

2020-01-31 来源:eefocus

在这里插入图片描述

旋转编码器 是一种输入装置,其帮助用户与系统进行交互。它看起来更像是一个无线电电位器旋转编码器是一种输入设备, 可帮助用户与系统交互。它看起来更像是一个无线电电位器, 但它输出一系列脉冲, 这使得它的应用独特。当编码器的旋钮旋转时, 它以小步的形式旋转, 这有助于它用于 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


//#include


#include


#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

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.


}

推荐阅读

史海拾趣

e2v technologies公司的发展小趣事

在医疗领域,e2v也积极发挥其作用。公司针对放射治疗系统提供了价格合理、易于运输和安装的国内制造设备,支持中国各地医院和诊所的放射治疗工作。这些设备不仅提高了放射治疗的效果和效率,也为患者带来了更好的治疗体验。

Chyao Shiunn Electronic Industrial Ltd公司的发展小趣事

在电子行业的初期,Chyao Shiunn Electronic Industrial Ltd还是一家名不见经传的小公司。然而,凭借着对技术创新的执着追求,公司成功研发出一款高效能的芯片,这款芯片不仅性能卓越,而且成本相对较低。这一技术突破迅速吸引了市场的关注,公司借此机会积极拓展市场,逐渐在电子行业中崭露头角。

Chips And Technologies Inc公司的发展小趣事

C&T始终坚持品质至上的原则,从原材料的采购到产品的生产、测试,每一个环节都严格把控。这种对品质的执着追求,使得C&T的产品在市场上赢得了良好的口碑。许多知名电脑制造商都选择与C&T合作,将其产品作为首选的半导体解决方案。

星海公司的发展小趣事

随着国内市场的饱和,星海公司开始实施国际化战略,积极拓展海外市场。公司积极参加国际展览和比赛,展示星海钢琴的品质和实力。同时,星海公司还与国际知名音乐院校和乐团建立合作关系,推动星海钢琴在国际市场的知名度和影响力。目前,星海钢琴已出口到世界60多个国家和地区,成为国际市场上备受瞩目的中国品牌。

汇科公司的发展小趣事

2010年,山东汇科电气技术有限公司在山东淄博成立,标志着汇科公司在电子行业迈出了坚实的第一步。创立之初,公司就确定了以节能环保为发展核心的战略方向。2011年,汇科与日本富士等国内外一线品牌建立了战略合作关系,成为富士一级代理及指定维修中心,这一举措为公司的技术积累和市场拓展奠定了坚实基础。

AMS公司的发展小趣事

2010年,山东汇科电气技术有限公司在山东淄博成立,标志着汇科公司在电子行业迈出了坚实的第一步。创立之初,公司就确定了以节能环保为发展核心的战略方向。2011年,汇科与日本富士等国内外一线品牌建立了战略合作关系,成为富士一级代理及指定维修中心,这一举措为公司的技术积累和市场拓展奠定了坚实基础。

问答坊 | AI 解惑

CSR-HF主要部分的说明

CVC-OMS:OMS处理过程是一个实时的处理过程,它采用语音抽取技术来选择并获取感兴趣的语音信息,从而减小了背景噪音的干扰。在捕获有小的失真的语音信息的时候,容易产生在统计上相对比较稳定的非白噪声(Colored Noise),OMS对这类信号尤其有用,对 ...…

查看全部问答>

如何看待就业中“国进民退”

国家公务员考试11月29日开考,共有104万人争1.5万职位,又创历史新高,成为名副其实的国家第一考。 金融危机以来,有关“国进民退”的问题引起了企业、舆论和市场的关注与担忧。但与此同时,还有一种“国进民退”少受到人们的重视,这就是就业中的 ...…

查看全部问答>

与世隔绝手机袋,让你成功的躲开手机的"追踪"。

手机休息袋:这个小袋子能按照你自己的意愿,给你一个不被打扰的时间,让你离开手机的控制,真正做回你自己。能在下班后坐在咖啡厅里跟你聊一会儿天而不被打扰。能自由自在控制自己的时间和生活。        “手机休息袋”应用先进的纳 ...…

查看全部问答>

ARM与FPGA之间通信

目前想做arm嵌入linux将FPGA做为一个数据处理功能,请教大家有没有好的方法呢!…

查看全部问答>

电力行业企业高薪招聘嵌入式开发人员!!

    欢迎满足以下条件之一的有识之士与我们联系,公司网址:     www.nerc.com.cn,发送简历邮箱地址:whl668@epri.ac.cn。     1.具有2年以上电力行业嵌入式产品开发经验。         2. ...…

查看全部问答>

算时间问题

一个延时函数: void delay_8us(unsigned int us) { while(--us);   } 生成汇编 C:0x0023    7FF4     MOV      R7,#0xF4 C:0x0025    7E01      ...…

查看全部问答>

串口 数据位

为什么我把串口调试助手的数据位设为8、7,结束位设为1、2都可以正常通行呢?…

查看全部问答>

请问MAXIM的工程师,这个驱动方案可以吗?

max16804, 12v输入,3个LED为一串,共6串并连,每串用一小电阻做均流,这个方案可否?    …

查看全部问答>

DE0板的Flash下载工程

以前从网上找DE0 的flash下载,好久都没找到,最后自己还是弄出来了。希望对需要的人有帮助。…

查看全部问答>

关于real6410下MFC硬编解码的问题

最近需要使用摄像头去视频,并通过硬编码器编码显示在本地并同时上传服务器,开到这款开发板有MFC硬解码支持,但是需自己添加相关的组建,根据三星提供的手册重新制作了NK.BIN,但是编译的时候出错,不知道哪位大侠有这方面的经验,看看以下问题怎 ...…

查看全部问答>