找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1037|回复: 14
收起左侧

飞梭旋钮快旋和慢旋的单片机代码思路要怎么写?

  [复制链接]
ID:1041297 发表于 2023-3-1 13:57 | 显示全部楼层 |阅读模式
各位大伙,飞梭旋钮快旋和慢旋的单片机代码思路要怎么写?快旋每次让数码管显示的数字加5,,慢旋每次让数码管显示的数字加1.
回复

使用道具 举报

ID:996773 发表于 2023-3-1 14:40 | 显示全部楼层
这个有点难讲,我做过,没有做过得人也很难理解,旋转编码器无非是读取io口11,开始进入

延时等待变成10,这个第1阶段延时得自己摸索手速延时多少,延时后加个识别10指令,如果

这时候旋转编码器转到10,说明你手速快,转到数值加5子程序,如果你手速慢,旋转编码器

还是刚开始的11,那么执行第二阶段延时,再加第二个识别10指令,如果这时候旋转编码器

转到了10,那么执行加1子程序。反正这种程序关键靠延时,摸索自己手速来调整延时
回复

使用道具 举报

ID:996773 发表于 2023-3-1 14:48 | 显示全部楼层
TA8127x6a64.jpg

顺便发个图,发现我做的东西很多是别人问的,我这个就是用上了旋转编码器,

慢转和快转就用了两段延时思路
回复

使用道具 举报

ID:1053178 发表于 2023-3-1 16:47 | 显示全部楼层
我做过一个
搞个定时器中断,最大值和最小值时检查编码器数值,根据数值差,差值大于某个数就启动快步进,快件停下5秒就恢复慢步进,一直快进就一直保持。
以前用pic,最大延时1.6秒轻松判断,改51后最大延时只有100毫秒左右
回复

使用道具 举报

ID:213173 发表于 2023-3-1 20:47 | 显示全部楼层
快旋每次让数码管显示的数字加5,慢旋每次让数码管显示的数字加1。不如选一圈多脉冲的旋转编码器来的方便。
回复

使用道具 举报

ID:230500 发表于 2023-3-1 22:39 | 显示全部楼层
是不是你的程序反应不灵敏; 放到中断里面10毫秒扫描一次,我感觉一个脉冲数字加1 挺快的, EC12 ,30脉冲的转一圈可以加到30;
如果要每次加5,可以做个设置,比如步进1 ;步进5 ;收到一个脉冲数字加1 或者数字加5; 另外一种方法就是类似于按键长按短按;每次收到编码的时候数字加1,同时用一个变量存储这个脉冲做判断;如果连续收到超过5个编码后,接下来的连续脉冲就每个脉冲加5; 如果没有继续收到脉冲 就把变量标志清零;等待下次的脉冲;这样LED显示就比较顺滑,先是从1-2-3-4-5-10-15-20-25; 下次又是26-27-28-29-30-35-40-45-50;
ae8e98792edcbb5e63f048b04ab4fe6.jpg


回复

使用道具 举报

ID:384109 发表于 2023-3-2 07:55 | 显示全部楼层
不难的东西,老早就做过了,类似地板的做法,但是感觉地板做法复杂了,其实就是一个编码器计数,加一个定时器就可以了
回复

使用道具 举报

ID:1034262 发表于 2023-3-2 10:46 | 显示全部楼层
检测脉冲速度,超过某个速度的N个脉冲开始每个脉冲表示5个,我常用此方法,操作顺滑。
回复

使用道具 举报

ID:1041297 发表于 2023-3-2 14:28 | 显示全部楼层
coody_sz 发表于 2023-3-2 10:46
检测脉冲速度,超过某个速度的N个脉冲开始每个脉冲表示5个,我常用此方法,操作顺滑。

你好,请问你有一段源码吗?能否看看
回复

使用道具 举报

ID:857072 发表于 2023-3-2 19:08 来自手机 | 显示全部楼层
哪有那么悬啊就是拿一个全局变量让他在扫描编码器的定时器里一直自减,然后你正常检测编码器的旋转每次检测到旋转的时候就读这个变量里面的值如果是零的话就是慢转不是零的话就是快转,读完后给它的值重置一下。给你看看我的库文件

单片机源程序如下:
  1. #ifndef _EC11_51_H_
  2. #define _EC11_51_H_


  3. //----------------编码器参数微调宏定义----------------//
  4. #ifndef KEY_COUNT_DESHAKING
  5. #define KEY_COUNT_DESHAKING 15 //按键消抖时间15
  6. #endif
  7. #ifndef KEY_COUNT_LONGT
  8. #define KEY_COUNT_LONGT 1500 //长按按键判断时间1500
  9. #endif
  10. #ifndef KEY_COUNT_DUAL
  11. #define KEY_COUNT_DUAL 180 //双击按键判断时间180
  12. #endif
  13. #ifndef KEY_LONG_REPEAT
  14. #define KEY_LONG_REPEAT 200 //长按按键的回报率的倒数,即一直长按按键时响应的时间间隔200
  15. #endif

  16. //----------------重入缓存结构体----------------//
  17. typedef struct tongdaoHC {
  18. unsigned char EC11_A_dq; //EC11的A引脚读到的当前状态
  19. unsigned char EC11_B_dq; //EC11的B引脚读到的当前状态
  20. unsigned char EC11_D_dq; //EC11的D引脚读到的当前状态
  21. unsigned char EC11_A_Last; //EC11的A引脚上一次的状态
  22. unsigned char EC11_B_Last; //EC11的B引脚上一次的状态
  23. unsigned char EC11_IN_Click; //EC11按键状态机动作标志
  24. unsigned char EC11_j_km; //EC11判断转动快慢的计数器
  25. unsigned int EC11_j_COUNT; //EC11按键动作计数器        

  26. }tongdaoHC;

  27. //----------------函数声明列表----------------//
  28. unsigned char Encoder_EC11_Scan(tongdaoHC *HC);

  29. //*******************************************************************/
  30. //功能:扫描EC11旋转编码器的动作并动作分析
  31. //形参:无
  32. //返回:EC11动作返回 0无动作 1正转 2反转 3按着按键正转 4按着按键反转 5短按 6双击 7长按 8长按松开
  33. //详解:对EC11旋转编码器的动作进行模式分析
  34. //*******************************************************************/
  35. unsigned char Encoder_EC11_Scan(tongdaoHC *HC)
  36. {
  37. unsigned char ScanResult = 0; //用于分析编码器动作的变量
  38. if(HC->EC11_j_km)
  39. HC->EC11_j_km--;
  40. if(!HC->EC11_A_dq && !HC->EC11_A_Last && !HC->EC11_B_dq && HC->EC11_B_Last) //A相当前状态和上次状态都为低电平时,抓B相上次状态为高当前状态为低的下降沿。
  41. {
  42. ScanResult = 1; //正转
  43. }
  44. else if(!HC->EC11_A_dq && HC->EC11_A_Last && !HC->EC11_B_dq && !HC->EC11_B_Last) //B相当前状态和上次状态都为低电平时,抓A相上次状态为高当前状态为低的下降沿。
  45. {
  46. ScanResult = 2; //反转
  47. }
  48. HC->EC11_A_Last = HC->EC11_A_dq; //更新编码器上一个状态暂存变量
  49. HC->EC11_B_Last = HC->EC11_B_dq; //更新编码器上一个状态暂存变量

  50. if(HC->EC11_D_dq == 0) //如果EC11的按键按下,
  51. {
  52. if(ScanResult == 0) //状态记录值为0表示EC11没有转动
  53. {
  54. ScanResult = 5; //返回值为5
  55. }        
  56. else
  57. {
  58. if(ScanResult == 1) //按下按键时候正转
  59. {
  60. HC->EC11_IN_Click = 7;
  61. return 3; //编码器按键按下并正转返回值为3
  62. }        
  63. if(ScanResult == 2) //按下按键时候反转
  64. {
  65. HC->EC11_IN_Click = 7;
  66. return 4; //编码器按键按下并反转返回值为4
  67. }        
  68. }
  69. }
  70. else //如果EC11的按键没有按下,
  71. {
  72. if(ScanResult=1)
  73. return 1; //编码器正转返回值为1
  74. else if(ScanResult=2)
  75. return 2; //编码器正转返回值为1
  76. }        

  77. if(HC->EC11_IN_Click = 7)//有旋转动作等待释放
  78. {
  79. if(ScanResult==0) //按键被释放
  80. {
  81. HC->EC11_IN_Click = 0; //按键状态机清零
  82. }
  83. }        
  84. else //没有旋转动作等待进入按键处理
  85. {
  86. if(HC->EC11_j_COUNT<3000) //打开按键按下时间定时器
  87. HC->EC11_j_COUNT++;
  88. switch (HC->EC11_IN_Click) //状态机
  89. {
  90. case 0://初始状态
  91. if(ScanResult==5)
  92. {
  93. HC->EC11_IN_Click = 1; //进入状态1有键按下
  94. HC->EC11_j_COUNT = 0; //复位计时器
  95. }
  96. break;
  97. case 1://有键按下状态
  98. if(ScanResult==5 && HC->EC11_j_COUNT > KEY_COUNT_DESHAKING)//按下消抖时间结束
  99. {
  100. HC->EC11_IN_Click = 2; //进入状态2按键以稳定按下。
  101. }
  102. break;        
  103. case 2://按键以稳定按下。

  104. if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==0)//按键释放且计时小于180MS
  105. {
  106. HC->EC11_IN_Click = 3;//进入状态3按键双击等待状态。
  107. HC->EC11_j_COUNT = 0; //复位计时器
  108. }
  109. else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==5)//按键按下且计时大于180MS
  110. {
  111. HC->EC11_IN_Click = 5;//进入状态5按键长按等待状态。
  112. }
  113. break;
  114. case 3://按键双击等待状态。
  115. if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==5)//按键按下且计时重新计数小于180MS
  116. {
  117. HC->EC11_IN_Click = 4;//进入状态4按键双击二次按下状态。
  118. HC->EC11_j_COUNT = 0; //复位计时器
  119. }
  120. else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==0)//按键释放且计时重新计数大于180MS
  121. {
  122. HC->EC11_IN_Click = 0; //按键状态机清零
  123. return 5;//单击返回1

  124. }
  125. break;
  126. case 4://按键双击二次按下状态。
  127. if(HC->EC11_j_COUNT > KEY_COUNT_DESHAKING && ScanResult==0)//按下消抖时间结束且按键被释放
  128. {
  129. HC->EC11_IN_Click = 0; //按键状态机清零
  130. return 6;        //双击返回键值        
  131. }
  132. break;
  133. case 5://按键长按等待状态。
  134. if(HC->EC11_j_COUNT <KEY_COUNT_LONGT && ScanResult==0)//按键被释放且计时小于1600MS
  135. {
  136. HC->EC11_IN_Click = 0; //按键状态机清零
  137. return 5;//单击返回1
  138. }
  139. else if(HC->EC11_j_COUNT >=KEY_COUNT_LONGT && ScanResult==5)//记录键值在按下键值表里且计时大于1600MS
  140. {
  141. HC->EC11_IN_Click = 6;//进入状态6按键长按时间到达状态。
  142. HC->EC11_j_COUNT = 0; //复位计时器
  143. return 7;//连续按下返回键值
  144. }        
  145. break;
  146. case 6://按键长按时间以到达。
  147. if(ScanResult==0) //按键被释放
  148. {
  149. HC->EC11_IN_Click = 0; //按键状态机清零
  150. return 8;//连续按下松开返回键值
  151. }
  152. else if(HC->EC11_j_COUNT >=KEY_LONG_REPEAT && ScanResult==5)//记录键值在按下键值表里大于200MS
  153. {
  154. HC->EC11_j_COUNT = 0; //复位计时器
  155. return 7;//连续按下返回键值
  156. }
  157. break;
  158. }
  159. }        
  160. return 0;//没有按键返回0
  161. }

  162. #endif
复制代码
51hei图片20230302213848.png 51hei图片20230302213857.png
回复

使用道具 举报

ID:26645 发表于 2023-3-3 10:52 来自手机 | 显示全部楼层
慢旋加1快旋加5少了中间的数值,慢旋加1慢,快旋加1变快
回复

使用道具 举报

ID:965189 发表于 2023-3-3 11:08 | 显示全部楼层
如果你已经能正确读取编码器并显示的话,就是加上时间识别就可以了。
回复

使用道具 举报

ID:401564 发表于 2023-3-3 21:44 | 显示全部楼层
这种功能是真的鸡肋,甚至是反人类设计
优利德示波器用的就是这种设计,要测量电压,时间数据,扭半天都扭不到位置,扭慢了一动不动的,一扭快了就飞到另一边去
调个位置像做贼一样,得一下一下扭...........
回复

使用道具 举报

ID:477441 发表于 2023-3-4 10:08 | 显示全部楼层
接触过几台用飞梭旋钮的设备,飞梭旋钮带按压开关的

按一下飞梭旋钮,旋转飞梭快进,再按一下飞梭旋钮,旋转飞梭慢进,感觉挺方便的
回复

使用道具 举报

ID:1065084 发表于 2023-3-4 11:56 | 显示全部楼层
根据状态机思想编程实际可用的代码需要占用一个外部中断一个定时器。
外部中断负责判断旋钮左右旋转,记得旋钮硬件并联22nf电容来硬件滤波,这样单片机不用消抖了。
旋钮方向代码如下
void INT0_Isr() interrupt 0 using 1
{ //必须加消抖电容22nf
  bit bZZ = 0;//使用该临时变量是为了加快端口读取过程
        if (KL) {if (!KR) bZZ = 1;} //上跳
        else{if (KR) bZZ = 1;} //下跳
        if (bZZ) KT++; //正传
        else KT--; //反转
}
定时器呢负责判断快旋转慢旋转,定时器触发时记录当前的旋钮值,当前旋钮值与上次旋钮值比较,如果差距大就将旋转值乘以5
void tm0_isr() interrupt 1 using 0
{
        if(KT>KTL)
        {
                if(KT-KTL)>2
                KT=KT*5;
        }
        else
        {
                if(KTL-KT)>2
                KT=KT*5;
        }
        KTL=KT;
}
例如每20ms旋转值大于2说明旋转的比较快  ,旋转值乘以5,注意这里KT是有符号变量 可以为负值

加减速不好用,建议不搞,和人的手感不能相符。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表