旋转编码器

旋转编码器是一种可以左右旋转,同时也可以按下,也可以按下旋转的器件,通过左右旋转对应着内部不同开关的导通,同时按下也可以旋转,由此看来旋转编码器可以实现很复杂的功能,简单的通过左右旋转可以调节音量、亮暗等功能,按键可以发挥普通按键的作用,按下按键的同时左右旋转又可以区别普通旋转的按键,因此可以用一个旋转编码器同时调节音量和亮暗(举例),同时也可以通过不同的转速实现不同的功能,总之,功能很复杂,作为初学者,本次只介绍普通旋转和按键作用,同时分析卡死的问题。

开发板上的端口映射原理图如下:其中旋转编码器和模拟量摇杆线路复用,使用其中一个器件时,将对应的跳线帽断开即可。

旋转编码器的具体原理图如下所示,我们开发板中的1和4接地,如上图所示,按键按下时,开关1闭合,1和2接通,当向左右旋转时,开关2和3以一定的先后顺序闭合,也可能同时闭合,时序电路如下图所示,另外卡死是由于旋转编码器内部的机械结构不灵敏,正常情况下,每旋转一次,旋转编码器都会正常的咔哒一声,但是极少数情况下,会卡在咔哒声之前,即旋钮停在了两个格段之间,使得K2一直保持低电平,单片机退不出循环,从而导致卡死。




具体的程序如下,其中读取旋钮旋转的方向的方法有两种。1、同时读取两个按键的状态,如果同时读到K2是高电平、K3是低电平,则是方向1,如果同时读到K2是低电平、K3是高电平,则是方向2。2、只读取K2的状态,当K2的状态是低电平的时候,取一段及短的时间再判断K3的状态,若K3的状态是低电平,则是方向1,若K3的状态是高电平,则是方向2。卡死的状态变化通过标志位KUO以及累加COUT来判断。

读取程序如下:

u8 ENCODER_READ(void){ //接口初始化u8 a;//存放按键的值u8 kt;a=0;if(GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L))KUP=0; //判断旋钮是否解除锁死if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)&&KUP==0){ //判断是否旋转旋钮,同时判断是否有旋钮锁死delay_us(100);kt=GPIO_ReadInputDataBit(ENCODER_PORT_B,ENCODER_R); //把旋钮另一端电平状态记录delay_ms(3); //延时if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)){ //去抖if(kt==0){ //用另一端判断左或右旋转a=1;//右转}else{a=2;//左转}cou=0; //初始锁死判断计数器while(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_L)&&cou<60000){ //等待放开旋钮,同时累加判断锁死cou++;KUP=1;delay_us(20); //}}}if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D)&&KUP==0){ //判断旋钮是否按下  delay_ms(20);if(!GPIO_ReadInputDataBit(ENCODER_PORT_A,ENCODER_D)){ //去抖动a=3;//在按键按下时加上按键的状态值//while(ENCODER_D==0);   等等旋钮放开}}return a;
}
其中delay_us(100)是等待一小段时间,等待稳定之后检测K3的按键值,另外delay_ms(3)是消抖函数,因为在电平的变化时,会产生抖动,消抖之后如果仍然有效,则给相应的按键赋值。其中最后一段的锁死判断程序用了两个&&,即同时起作用,第一个条件是等待旋转之后的自动弹起,当弹起时,直接退出while语句这时KUP标志位为1,注意此时是正常的状态,通过单片机的不断扫描,下一次再进入读取函数后会通过第一个判断语句,将KUP清为0,如果真的是锁死状态则第一个条件恒为真,执行第二个为真的条件,这时延时大概1.2秒之后退出了循环(正常情况下,旋转的弹起时间必然小于1.2秒),这时仍然是锁死状态,单片机再次进入读取函数时KUP不会被清为0(因为锁死状态不满足if语句),因为一个KUP=1,所以以后的读取函数所有的语句都不被执行,这时单片机处于不被卡死的状态,即完成了卡死的程序处理。

主函数实例如下:

int main (void){//主程序u8 a=0,b=0,c=0x01;RCC_Configuration(); //系统时钟初始化 RTC_Config();  //RTC初始化ENCODER_Init(); //旋转编码器初始化TM1640_Init(); //TM1640初始化TM1640_display(0,a/10); //显示数值TM1640_display(1,a%10);TM1640_display(2,20);TM1640_display(3,20);TM1640_display(4,20);TM1640_display(5,20);TM1640_display(6,20);TM1640_display(7,20);while(1){b=ENCODER_READ();   //读出旋转编码器值  if(b==1){a++;if(a>99)a=0;} //分析按键值,并加减计数器值。if(b==2){if(a==0)a=100;a--;}if(b==3)a=0;if(b!=0){ //如果有旋转器的操作TM1640_display(0,a/10); //显示数值TM1640_display(1,a%10);}//        TM1640_led(c); //与TM1640连接的8个LED全亮
//      c<<=1; //数据左移 流水灯
//      if(c==0x00)c=0x01; //8个灯显示完后重新开始
//      delay_ms(150); //延时}
}
这里需要注意的是,如果同时将下面的流水灯程序打开之后,因为延时函数的存在,会使得旋转按钮便的不灵敏,这是因为延时函数占用了CPU空间,从而使得扫描的频率变慢,使得灵敏度降低,解决的方法有两种。1、在延时函数中加入读取按键旋转的函数,同时扫描读取显示即可。2、将K2开关接入外部中断触发,即将读取函数放入中断函数,一旦旋转按钮,则直接从延时函数进入中断读取,进而判断扫描显示,这也是方法2的优势,只占用了一个中断资源。

图中所有图片出自洋桃电子。

STM32学习100步之第四十七-四十八步——旋转编码器驱动程序相关推荐

  1. (十七 ~ 二十八)巴菲特与索罗斯的投资习惯:明确你的投资目标

    作者:chen_h 微信号 & QQ:862251340 微信公众号:coderpai (一)巴菲特与索罗斯的投资习惯:思考习惯的力量 (二)巴菲特与索罗斯的投资习惯:七种致命的投资信念 (三 ...

  2. 【Vue学习】—Vue UI组件库(二十八)

    [Vue学习]-Vue UI组件库(二十八) 一.移动端常用的UI组件库 二.PC端常用的UI组件库 三.具体使用自行查看文档,这里就不做概述了

  3. 读书笔记:汇编语言 第三版 王爽 清华出版社 章十六 章十七 章十八

    第十六章 直接定址表16.1 描述了单位长度的标号地址标号,表征了位置的偏移地址label:数据标号,表征了一段内存空间的物理地址和长度,增强型地址标号段地址,数据标号所在段的关联段寄存器,assum ...

  4. STM32学习100步之第七十二-七十六步——U盘、TF卡与单片机的通信(利用SPI总线通信)

    SPI通信 由图中可以看出,SPI有四条主要的信号线,即MISO(主机输入从机输出).MOSI(主机输出从机输入),CS是对于从机而言的,当为0时,允许通信,由主机控制是否选通,另外可以使用单片机的I ...

  5. STM32学习100步之第八十九步-第九十一步——加速度传感器MPU6050

    MPU6050传感器 MPU-6000 ( 605Q)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪鸟加速器时间轴之差的问题,减少了大量的封装空间.当连接到三轴磁强计时,MPU- ...

  6. STM32学习100步之第三十二步——MIDI音乐程序

    什么是MIDI音乐 MIDI音乐的产生原理 编写MIDI音乐 代码解读 什么是MIDI音乐 HIDI(Musical Instrument Digital Interface)乐器数字接口 是20世纪 ...

  7. PyTorch 学习笔记(六):PyTorch的十八个损失函数

    本文截取自<PyTorch 模型训练实用教程>,获取全文pdf请点击:https://github.com/tensor-yu/PyTorch_Tutorial 文章目录 1.L1loss ...

  8. 深入浅出CChart 每日一课——快乐高四第五十八课 大道至简,炫彩界面库之接口代码优化

    上节课对CChart在新版炫彩界面库中的使用进行了详细说明,大家看到CChart对炫彩界面库具有完美的兼容性. 但是呢,大家也发现了,要实现CChart的完整功能,需要用户编写的代码不少,杂七杂八地接 ...

  9. PostgreSQL的学习心得和知识总结(一百一十八)|深入理解PostgreSQL数据库 匿名块 的词法解析和语法解析流程(DRCLARE子句)

    目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.参考书籍:<PostgreSQL数据库内核分析> 2.参考书籍:<数据库事务处理的艺术:事务管理与并发 ...

最新文章

  1. ai皮肤检测分数_智能AI皮肤检测仪三步走话术
  2. wxWidgets:Sizer 概览
  3. Web服务安全性和SOA路线图的人为维度
  4. C++学习笔记1:virtual 继承
  5. 使用Xerte创建简单的在线学习资料的指南
  6. 如何删除尾随换行符?
  7. (Foxit PDF阅读器设置)禁止改变当前缩放比例,改善书签跳转阅读体验
  8. 【算法学习】纯高斯模糊算法处理灰度图片
  9. C中处理Python的Numpy数组的代码范例
  10. vant组件二次封装-下拉刷新列表组件
  11. bootstraptable 一条数据跨行_据说它是唐山市拥有奶茶店最多的一条街,你一定也逛过!...
  12. delphi 发送html邮件,delphi – 以HTML格式发送电子邮件
  13. vue嵌入app中——首次加载慢的动画
  14. Modesim仿真出现vlog-2388问题
  15. 用于信号处理的Xilinx FPGA XC7K325T PCIeX8 FMC处理板卡
  16. 大数据分析练习-第八届泰迪杯A题-基于数据挖掘的上市公司高送转预测
  17. Python实现AES中ECB模式pkcs5padding填充加密/解密(需要加密文档中可以有中文)
  18. Mysql内核查询成本计算
  19. Mybatis捕捉异常
  20. seo搜索引擎优化教程:新网站怎么做seo优化才能提高收录?

热门文章

  1. ubuntu16.04下配置samba共享服务支持Windows访问
  2. 问题解决FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEImHg8uh/django/contrib/auth/pas
  3. 苹果手机数据线充不了电_手机充不满电?教你四个办法解决!
  4. ROS Melodic中costmap2D详解
  5. Bregman Divergence
  6. bootstrap datetimepicker的时间变成1899年
  7. foxmail邮箱手机客户端设置
  8. ARM WFI和WFE
  9. 懒人笔记-mupdf篇<ubuntu>
  10. acw周赛 - 点的赋值 —— 二分图染色