本文隶属于AVR单片机教程系列。

 

好久没写这个系列了。今天讲讲旋转编码器。

旋转编码器好像不是单片机玩家很常用的器件,但是我们的开发板上有,原因如下:

  1. 旋转编码器挺好用的。电位器能旋转的角度有限,旋转编码器可以无限圈旋转;旋转时不连续,有卡点,适合对应离散数据。

  2. 开发板上选用的旋转编码器,使用起来简单、方便。

  3. 本来旁边的电位器(旋钮,以后会讲)一枝独秀,挺孤单的,我就配一个高度大致相同的旋转编码器陪伴它。

今天我想写旋转编码器,于是在网络上搜索了一下,相关资料很少。最基本地,旋转编码器的作用是将角位移、角速度等机械量转换为电信号。本文不求成为旋转编码器的百科全书,但会把 触点电刷式 增量式 旋转编码器的原理讲清楚。这里出现了两个定语,是对类别的限定;关于旋转编码器的分类,请自行百度。

开发板上的旋转编码器是从淘宝买的,淘宝商家提供了资料,这是本讲的主题。为避免广告嫌疑,我不能放链接上来,所以我就把它转换成图片放在文章里(请在新页面中查看):

我们从旋转编码器的原理开始。旋转编码器的内部是触点与电刷,可以看作按键:当两者接触时,开关闭合;反之断开。实际上它们的本质是一样的。在旋转时,按键会周期性地闭合、断开;如果一端接地,另一端接上拉电阻,就会有周期性高、低电平的脉冲信号产生。我们使用的旋转编码器每转过一圈会输出24个脉冲。

通过对脉冲进行计数,可以知道编码器转过的角度。如果不管方向,测量角度或角加速度等,用一个输出就够了。但是如果考虑方向,无论是顺时针还是逆时针转动,电平都是“高低高低高……”。为了获得方向的信息,需要使用两个输出,它们的相位相差90°,如图所示:

A和B是两个输出端,C端接地。当程序检测到A端由高电平变为低电平时(方法在按键那里讲过了),如果检测到B端是高电平(这就更简单了),那就是顺时针旋转;如果是低电平,那就是逆时针旋转。实际上不一定要检测A端的下降沿,只要按照这张图来,怎么都对。

库函数使用的检测方法是:A、B端由低低变为高低时,判为顺时针转过一格;由低低变为低高时,判为逆时针转过一格。这不是最好的方法(你可以想一下怎样改进,但是不要低估它的难度),但从实际使用上来看,只要用户不故意在两个卡点之间扭来扭去,这种方法是可以胜任的。

我们写一个用旋转编码器控制数码管显示数字的程序,也可以理解为对旋转编码器进行计数并用数码管显示。旋转编码器A和B端分别连接端口4和5,数码管连接6和7。程序的思路是:每隔一毫秒调用rotary_rotated(它和button_pressed函数类似——如果你还记得的话)检测编码器是否被转动以及转动的方向,并根据方向对计数器变量num进行增减。(为什么让numuint8_t类型?)为了凸显旋转编码器的主题,数码管就用segment_auto来解决了。

#include <ee1/delay.h>
#include <ee1/rotary.h>
#include <ee1/segment.h> int main()
{
rotary_init(PIN_4, PIN_5);
segment_init(PIN_6, PIN_7);
segment_auto();
uint8_t num = 0;
while (1)
{
switch (rotary_rotated())
{
case ROTARY_CW:
++num;
break;
case ROTARY_ACW:
--num;
break;
default:
break;
}
segment_hex(num);
delay(1);
}
}

注意相邻卡点之间挤了4个AB端口的状态,因此延时不能过长。你可以试试更长的间隔。

作业:对于旋转编码器,直接检测IO口电平;对于数码管,使用“原始”的动态扫描,即不要用segment_auto();重写样例。(提示:你可以分别完成两个要求,然后合并。)

AVR单片机教程——旋转编码器的更多相关文章

  1. AVR单片机教程——串口发送

    本文隶属于AVR单片机教程系列.   到目前为止,我们的开发板只能处理很小量的数据:读取几个引脚电平,输出几个LED,顶多用数码管显示一个两位数字.至于输入一个指令.输出一条调试信息,甚至用scanf ...

  2. AVR单片机教程——蜂鸣器

    本文隶属于AVR单片机教程系列.   引子 定时/计数器(简称定时器)是单片机编程中至关重要的一部分,再简单的单片机也会带有定时器. 也许你会觉得我们已经在delay函数中接触过定时器了,然而并不是, ...

  3. AVR单片机教程——第三期导语

    背景(一) 寒假里做了一个灯带控制器: 理想情况下我应该在一个星期内完成这个项目,但实际上它耗费了我几乎一整个寒假,因为涉及到很多未曾尝试的方案.在这种不是很赶时间的.可以自定目标.自由发挥的项目中, ...

  4. AVR单片机教程——ADC

    ADC 计算机的世界是0和1的.单片机可以通过读取0和1来确定按键状态,也可以输出0和1来控制LED.即使是看起来不太0和1的PWM,好像可以输出0到5V之间的电压一样,达到0和1之间的效果,但本质上 ...

  5. AVR单片机教程——示波器

    本文隶属于AVR单片机教程系列.   在用DAC做了一个稍大的项目之后,我们来拿ADC开开刀.在本讲中,我们将了解0.96寸OLED屏,移植著名的U8g2库到我们的开发板上,学习在屏幕上画直线的算法, ...

  6. AVR单片机教程——数码管

    先解答之前一个思考题:如果不把引脚配置为输出而写高电平,连接LED会怎样? 实验结果是,LED会亮,但相比于输出高电平的情况,亮度很低.这是为什么呢? 通过上一篇教程我们知道,引脚输入输出模式是由寄存 ...

  7. AVR单片机教程——数字输出

    从上一篇教程中我们了解到,按键与开关的输入本质上就是数字信号的读取.这一篇教程要讲的是,控制LED的原理是数字信号的输出.数字IO是单片机编程之有别于桌面编程的各项内容中最简单.最基础的. 在讲数字信 ...

  8. AVR单片机教程——数字输入

    我们已经学习了如何使用按键和拨动开关,不知你有没有好奇 button_down 和 switch_status 等函数是如何实现的.本篇教程带你一探究竟,让我们从按键的原理开始. 在原理图中,按键的符 ...

  9. AVR单片机教程——拨动开关

    在按键的上方有4个拨动开关.开关与按键,在原理和使用方法上都是很类似的,但有不同的用途——按键按下后松开就会弹起,而开关可以保存其状态. <switch.h> 定义了与开关相关的函数.sw ...

随机推荐

  1. 07-图5 Saving James Bond - Hard Version (30 分)

    This time let us consider the situation in the movie "Live and Let Die" in which James Bon ...

  2. [golang]数据库字典生成器-dataDictionary

    dataDictionary 介绍 生成数据字典 应用场景 根据mysql数据库生成html格式数据字典,目前仅支持macos/linux/windows 使用步骤 运行程序 windows: dat ...

  3. Pytorch中ndarray tensor list互转

    1.ndarray->tensor : b=torch.from_numpy(a) 2.tensor->ndarray: b=a.numpy() ''' 但这么写会报错-- Runtime ...

  4. Map、Set、List是否有序

    首先我们应该清楚这个概念:这里的有序和无序不是指集合中的排序,而是是否按照元素添加的顺序来存储对象. list是按照元素的添加顺序来存储对象的,因此是有序的.他的实现类ArrayList.Linked ...

  5. Spring Cloud 学习--Hystrix应用

    上一篇介绍了Hystrix基本功能和单独使用的方式,今天继续学习如何将Hystrix融入SpringCloud组件中去. 在Ribbon上使用熔断器 在 pom.xml 文件中引入 hystrix 的 ...

  6. convmv 解决GBK 迁移到 UTF-8 ,中文 文件名乱码

    yum install convmv 命令: convmv -f GBK -t UTF-8 -r --nosmart --notest <目标目录> -f from -t to --nos ...

  7. A Survey of Visual Attention Mechanisms in Deep Learning

    A Survey of Visual Attention Mechanisms in Deep Learning 2019-12-11 15:51:59 Source: Deep Learning o ...

  8. Mysql 排序规则选择

    排序规则:是指对指定字符集下不同字符的比较规则.其特征有以下几点: 1. 两个不同的字符集不能有相同的排序规则 2. 两个字符集有一个默认的排序规则 3. 有一些常用的命名规则.如_ci结尾表示大小写 ...

  9. 使用NPOI或EPPlus来导出Excel文件实例,可在Excel文件加密

    使用NPOI.dll组件来导出Excel文件,并设置样式,Nuget引用即可. packages\NPOI.2.1.3.1\lib\net20\NPOI.dll #region Excel prote ...

  10. wordpress 获取指定作者的所有 post meta

    $args = array( 'post_type' => array( 'post','knowledgebase'), 'post_status' => 'publish', 'aut ...