如何使用数字旋转编码开关

单片机相关 徐 自远 531℃

数字旋转编码器在现在的工控领域运用广泛,跑步机的旋钮,控制器的旋钮,音响的音量控制旋钮,都是数字旋转编码器的典型应用。

看一个数字旋转编码器的视频,加深一下理解。

5脚的数字旋转编码器:

图 1 旋转编码器的实物图

具有左转,右转,按下三个功能。4、5脚是中间按下去的开关接线 1 2 3脚 一般是中间2脚接地,1、3脚上拉电阻后,当左转、右转旋纽时,在1、3脚就有脉冲信号输出了。

着这是标准资料:

图2 旋转编码器的结构图

在单片机编程时,左转和右转的判别是难点,用示波器观察这种开关左转和右转时两个输出脚的信号有个相位差,见下图:

图3 旋转编码器在旋转的时候的输出波形

由此可见,如果输出1为高电平时,输出2出现一个高电平,这时开关就是向顺时针旋转; 当输出1 为高电平,输出2出现一个低电平,这时就一定是逆时针方向旋转。

所以,在单片机编程时只需要判断当输出1为高电平时,输出2当时的状态就可以判断出是左旋转或是右旋转了。

还有另外一种3脚的,除了不带按钮开关外,和上面是一样的使用。

图4 三个脚的旋转编码器

  1. 参考程序:
  2. #include “reg51.h”
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. sbit Rotation_Key_A = P1_1; //定义旋转编码器的方向判断A口
  6. sbit Rotation_Key_B = P1_2; //定义旋转编码器的方向判断B口
  7. uint CodingsWitchPolling()//
  8. {
  9. static uchar A_Last_State,B_Last_State; //定义了两个变量用来储蓄上一次调用此方法是编码开关两引脚的电平
  10. static uchar High_Last_State;//定义了一个变量用来储蓄以前是否出现了两个引脚都为高电平的状态
  11. uint tmp = 0;
  12. if(Rotation_Key_A&&Rotation_Key_B)
  13. High_Last_State = 1; //
  14. if(High_Last_State) //如果High_Last_State为1执行下面的步骤
  15. {
  16. if(Rotation_Key_A==0&&Rotation_Key_B==0) //如果当前编码开关的两个引脚都为底电平执行下面的步骤
  17. {
  18. if(B_Last_State) //为高说明编码开关在向加大的方向转
  19. {
  20. High_Last_State = 0;
  21. tmp++; //
  22. }
  23. if(A_Last_State) //为高说明编码开关在向减小的方向转
  24. {
  25. High_Last_State = 0;
  26. tmp–; //设返回值
  27. }
  28. }
  29. }
  30. A_Last_State = Rotation_Key_A; //储存A口的当前状态
  31. B_Last_State = Rotation_Key_B; //储存B口的当前状态
  32. return tmp; //
  33. }
  34. //编码器计数程序
  35. void encoder_cnt(void)
  36. {
  37. uchar Reade_Io_Data;
  38. Reade_Io_Data = PIND; //取端口D管脚信号
  39. Reade_Clr_Signal = (Reade_Io_Data & 0x08); //读取编码器清零信号
  40. if(Reade_Clr_Signal != false) //有编码器清零信号
  41. {
  42. couch_num = 0; //水平床码清零
  43. }
  44. else
  45. {
  46. if(encoder_cnt_en == false) //编码器计数模块没有启动
  47. {
  48. pr_couch_ba = Reade_Io_Data & 0x03; //取编码器A、B相电平信号
  49. }
  50. else
  51. {
  52. couch_ba = Reade_Io_Data & 0x03; //取编码器A、B相电平信号
  53. if(pr_couch_ba == 0x00)
  54. {
  55. if(couch_ba == 0x01)
  56. {
  57. couch_num++; //水平床码加1
  58. }
  59. else if(couch_ba == 0x10)
  60. {
  61. couch_num–; //水平床码减1
  62. }
  63. }
  64. else if(pr_couch_ba == 0x01)
  65. {
  66. if(couch_ba == 0x11)
  67. {
  68. couch_num++; //水平床码加1
  69. }
  70. else if(couch_ba == 0x00)
  71. {
  72. couch_num–; //水平床码减1
  73. }
  74. }
  75. else if(pr_couch_ba == 0x10)
  76. {
  77. if(couch_ba == 0x00)
  78. {
  79. couch_num++; //水平床码加1
  80. }
  81. else if(couch_ba == 0x11)
  82. {
  83. couch_num–; //水平床码减1
  84. }
  85. }
  86. else if(pr_couch_ba == 0x11)
  87. {
  88. if(couch_ba == 0x10)
  89. {
  90. couch_num++; //水平床码加1
  91. }
  92. else if(couch_ba == 0x01)
  93. {
  94. couch_num–; //水平床码减1
  95. }
  96. }
  97. }
  98. pr_couch_ba = couch_ba;
  99. }
  100. }
  101. 编码器及其计数模块原理
  102. 旋转编码器的检测程序(基于51单片机)
  103. //旋转编码器检测程序,A/B信号分别接在了INT0和INT1上
  104. //2005年3月27用KEIL编译、硬件测试通过
  105. //注意:编码器的信号,程序未做消抖处理。测试中,A/B信号上各
  106. //接了一只104的瓷片电容,工作很正常。如果不接电容,请自行编
  107. //写信号消抖程序。
  108. #include <at89x51.h>
  109. sbit led=0xB1;//有一只LED接在了RXD引脚上,用来指示正反转;
  110. main()
  111. {
  112. EA=1; //总中断允许
  113. EX0=1; //外部中断0允许
  114. IT0=1; //外部中断0为边沿触发方式
  115. while(1);;
  116. }
  117. /*********************
  118. 编码器中断函数
  119. 入口:无
  120. 出口:无
  121. *********************/
  122. void encoder(void) interrupt 0
  123. { //外部中断0
  124. if (INT1)
  125. {
  126. led=1;
  127. }
  128. else
  129. {
  130. led=0;
  131. }
  132. }
  133. whimsy 的AVR程序
  134. //外部中断0,用于编码开关解码,解码图: A接中断脚(AVR的PD2),以此为基准,B用来判断方向(连到AVR的PA1), C接地
  135. //A -|
  136. // | —–|__________|———-|____________
  137. //C -|
  138. //
  139. //B -|
  140. // | ———-|__________|———-|____________
  141. //C -|
  142. // CW ===>>> ROTATION
  143. //外部中断设置(ISC01=0,ISC00=1): INT0 引脚上任意的逻辑电平变化都将引发中断
  144. #pragma interrupt_handler int0_isr:2
  145. void int0_isr(void)
  146. {
  147. //external interupt on INT0
  148. GICR=0; //禁止外部中断
  149. if ((PIND & 0x04)==0) //先判断是高电平产生的中断还是低点平的中断
  150. {
  151. if ((PINA & 0x02)==0) //再判断B线上的电平
  152. {
  153. keycounter–;
  154. keydirection=0;
  155. }
  156. else
  157. {
  158. keycounter++;
  159. keydirection=1;
  160. }
  161. else
  162. if ((PINA & 0x02)==0)
  163. {
  164. keycounter++;
  165. keydirection=1;
  166. }
  167. else
  168. {
  169. keycounter–;
  170. keydirection=0;
  171. }
  172. GICR=0x40;
  173. }
  174. }

复制代码

以上图文内容均转载自订阅号:电子工程世界(微信搜索 eeworldbbs 关注)

欢迎微博@EEWORLD

如果您也写过此类原创干货欢迎将您的原创发至:bbs_service@eeworld.com.cn,一经入选,我们将帮你登上头条!

与更多行业内网友进行交流请登陆EEWorld论坛。

 

如何使用数字旋转编码开关http://t.jinritoutiao.js.cn/ePaE3g/

转载请注明:徐自远的乱七八糟小站 » 如何使用数字旋转编码开关

喜欢 (0)

苏ICP备18041234号-1 bei_an 苏公网安备 32021402001397号