|
旋转编码器(Rotary Encoder)是一种帮助用户与系统交互的输入设备。它看起来更像是一个无线电电位器,但它输出一系列脉冲,使其应用独特。当旋转编码器的旋钮时,它以小步进的形式旋转,这有助于它用于步进/伺服电机控制、导航菜单序列和增加/减少数字的值等等。
在本篇文章中,我们将了解不同类型的旋转编码器及其工作原理。我们还将它连接到PIC单片机PIC16F877A,并通过旋转编码器控制整数值,然后在LCD液晶屏1602显示其值。在本文结束时,您将熟悉为项目使用旋转编码器。让我们开始吧......
旋转编码器及其类型 旋转编码器通常称为轴编码器。它是一种机电换能器,意味着它将机械运动转换为电子脉冲,或者换句话说,它将角位置或运动或轴位置转换为数字或模拟信号。它由旋钮组成,当旋转时,旋钮将逐步移动并产生一系列脉冲序列,每次步进具有预定义的宽度。
市场上有很多种类型的旋转编码器,设计师可以根据自己的应用选择一种。最常见的类型如下所示 ● 增量型编码器 ● 绝对值编码器 ● 磁编码器 ● 光学编码器 ● 激光编码器 这些编码器基于输出信号和传感技术进行分类,增量编码器和绝对编码器基于输出信号进行分类,磁、光和激光编码器基于传感技术进行分类。这里使用的编码器是增量型编码器。
绝对值编码器即使在断电后也会存储位置信息,当我们再次为其供电时,位置信息依然可用。
另一种基本类型,增量型编码器在编码器改变其位置时提供数据。它无法存储位置信息。
KY-040旋转编码器引脚和说明 KY-040增量式旋转编码器的引脚分布如下所示。在本文中,我们将该旋转编码器连接到Microchip公司的微控制器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单片机 ● 4.7k电阻 ● 1k电阻 ● 10k电位器 ● 33pF陶瓷电容 ● 20Mhz晶振 ● 1602显示屏 ● 旋转编码器 ● 5V适配器 ● 面包板 ● 连接导线
PIC16F877A旋转编码器接口电路图
下面是根据电路图连接组件后的最终设置图:
我们使用单个1K电阻来代替LCD的对比度,而不是使用电位计。
代码说明 在本文的末尾处给出了完整的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);
复制代码
system_init()函数用于初始化引脚I / O操作、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.c和lcd.h库中,其中声明了lcd_puts()、lcd_cmd()。有关变量声明、配置位和其他代码片段,请在参考下面完整的代码。
代码 以下是本篇文章使用的完整代码:
main.rar
(1.23 KB, 下载次数: 37)
|