標(biāo)題: 飛梭旋鈕快旋和慢旋的單片機(jī)代碼思路要怎么寫? [打印本頁(yè)]

作者: 1314love    時(shí)間: 2023-3-1 13:57
標(biāo)題: 飛梭旋鈕快旋和慢旋的單片機(jī)代碼思路要怎么寫?
各位大伙,飛梭旋鈕快旋和慢旋的單片機(jī)代碼思路要怎么寫?快旋每次讓數(shù)碼管顯示的數(shù)字加5,,慢旋每次讓數(shù)碼管顯示的數(shù)字加1.

作者: hi等你    時(shí)間: 2023-3-1 14:40
這個(gè)有點(diǎn)難講,我做過,沒有做過得人也很難理解,旋轉(zhuǎn)編碼器無非是讀取io口11,開始進(jìn)入

延時(shí)等待變成10,這個(gè)第1階段延時(shí)得自己摸索手速延時(shí)多少,延時(shí)后加個(gè)識(shí)別10指令,如果

這時(shí)候旋轉(zhuǎn)編碼器轉(zhuǎn)到10,說明你手速快,轉(zhuǎn)到數(shù)值加5子程序,如果你手速慢,旋轉(zhuǎn)編碼器

還是剛開始的11,那么執(zhí)行第二階段延時(shí),再加第二個(gè)識(shí)別10指令,如果這時(shí)候旋轉(zhuǎn)編碼器

轉(zhuǎn)到了10,那么執(zhí)行加1子程序。反正這種程序關(guān)鍵靠延時(shí),摸索自己手速來調(diào)整延時(shí)
作者: hi等你    時(shí)間: 2023-3-1 14:48


順便發(fā)個(gè)圖,發(fā)現(xiàn)我做的東西很多是別人問的,我這個(gè)就是用上了旋轉(zhuǎn)編碼器,

慢轉(zhuǎn)和快轉(zhuǎn)就用了兩段延時(shí)思路

作者: diyage    時(shí)間: 2023-3-1 16:47
我做過一個(gè)
搞個(gè)定時(shí)器中斷,最大值和最小值時(shí)檢查編碼器數(shù)值,根據(jù)數(shù)值差,差值大于某個(gè)數(shù)就啟動(dòng)快步進(jìn),快件停下5秒就恢復(fù)慢步進(jìn),一直快進(jìn)就一直保持。
以前用pic,最大延時(shí)1.6秒輕松判斷,改51后最大延時(shí)只有100毫秒左右
作者: wulin    時(shí)間: 2023-3-1 20:47
快旋每次讓數(shù)碼管顯示的數(shù)字加5,慢旋每次讓數(shù)碼管顯示的數(shù)字加1。不如選一圈多脈沖的旋轉(zhuǎn)編碼器來的方便。

作者: a399288395    時(shí)間: 2023-3-1 22:39
是不是你的程序反應(yīng)不靈敏; 放到中斷里面10毫秒掃描一次,我感覺一個(gè)脈沖數(shù)字加1 挺快的, EC12 ,30脈沖的轉(zhuǎn)一圈可以加到30;
如果要每次加5,可以做個(gè)設(shè)置,比如步進(jìn)1 ;步進(jìn)5 ;收到一個(gè)脈沖數(shù)字加1 或者數(shù)字加5; 另外一種方法就是類似于按鍵長(zhǎng)按短按;每次收到編碼的時(shí)候數(shù)字加1,同時(shí)用一個(gè)變量存儲(chǔ)這個(gè)脈沖做判斷;如果連續(xù)收到超過5個(gè)編碼后,接下來的連續(xù)脈沖就每個(gè)脈沖加5; 如果沒有繼續(xù)收到脈沖 就把變量標(biāo)志清零;等待下次的脈沖;這樣LED顯示就比較順滑,先是從1-2-3-4-5-10-15-20-25; 下次又是26-27-28-29-30-35-40-45-50;




作者: 人中狼    時(shí)間: 2023-3-2 07:55
不難的東西,老早就做過了,類似地板的做法,但是感覺地板做法復(fù)雜了,其實(shí)就是一個(gè)編碼器計(jì)數(shù),加一個(gè)定時(shí)器就可以了
作者: coody_sz    時(shí)間: 2023-3-2 10:46
檢測(cè)脈沖速度,超過某個(gè)速度的N個(gè)脈沖開始每個(gè)脈沖表示5個(gè),我常用此方法,操作順滑。
作者: 1314love    時(shí)間: 2023-3-2 14:28
coody_sz 發(fā)表于 2023-3-2 10:46
檢測(cè)脈沖速度,超過某個(gè)速度的N個(gè)脈沖開始每個(gè)脈沖表示5個(gè),我常用此方法,操作順滑。

你好,請(qǐng)問你有一段源碼嗎?能否看看

作者: a185980800    時(shí)間: 2023-3-2 19:08
哪有那么懸啊就是拿一個(gè)全局變量讓他在掃描編碼器的定時(shí)器里一直自減,然后你正常檢測(cè)編碼器的旋轉(zhuǎn)每次檢測(cè)到旋轉(zhuǎn)的時(shí)候就讀這個(gè)變量里面的值如果是零的話就是慢轉(zhuǎn)不是零的話就是快轉(zhuǎn),讀完后給它的值重置一下。給你看看我的庫(kù)文件

單片機(jī)源程序如下:
  1. #ifndef _EC11_51_H_
  2. #define _EC11_51_H_


  3. //----------------編碼器參數(shù)微調(diào)宏定義----------------//
  4. #ifndef KEY_COUNT_DESHAKING
  5. #define KEY_COUNT_DESHAKING 15 //按鍵消抖時(shí)間15
  6. #endif
  7. #ifndef KEY_COUNT_LONGT
  8. #define KEY_COUNT_LONGT 1500 //長(zhǎng)按按鍵判斷時(shí)間1500
  9. #endif
  10. #ifndef KEY_COUNT_DUAL
  11. #define KEY_COUNT_DUAL 180 //雙擊按鍵判斷時(shí)間180
  12. #endif
  13. #ifndef KEY_LONG_REPEAT
  14. #define KEY_LONG_REPEAT 200 //長(zhǎng)按按鍵的回報(bào)率的倒數(shù),即一直長(zhǎng)按按鍵時(shí)響應(yīng)的時(shí)間間隔200
  15. #endif

  16. //----------------重入緩存結(jié)構(gòu)體----------------//
  17. typedef struct tongdaoHC {
  18. unsigned char EC11_A_dq; //EC11的A引腳讀到的當(dāng)前狀態(tài)
  19. unsigned char EC11_B_dq; //EC11的B引腳讀到的當(dāng)前狀態(tài)
  20. unsigned char EC11_D_dq; //EC11的D引腳讀到的當(dāng)前狀態(tài)
  21. unsigned char EC11_A_Last; //EC11的A引腳上一次的狀態(tài)
  22. unsigned char EC11_B_Last; //EC11的B引腳上一次的狀態(tài)
  23. unsigned char EC11_IN_Click; //EC11按鍵狀態(tài)機(jī)動(dòng)作標(biāo)志
  24. unsigned char EC11_j_km; //EC11判斷轉(zhuǎn)動(dòng)快慢的計(jì)數(shù)器
  25. unsigned int EC11_j_COUNT; //EC11按鍵動(dòng)作計(jì)數(shù)器        

  26. }tongdaoHC;

  27. //----------------函數(shù)聲明列表----------------//
  28. unsigned char Encoder_EC11_Scan(tongdaoHC *HC);

  29. //*******************************************************************/
  30. //功能:掃描EC11旋轉(zhuǎn)編碼器的動(dòng)作并動(dòng)作分析
  31. //形參:無
  32. //返回:EC11動(dòng)作返回 0無動(dòng)作 1正轉(zhuǎn) 2反轉(zhuǎn) 3按著按鍵正轉(zhuǎn) 4按著按鍵反轉(zhuǎn) 5短按 6雙擊 7長(zhǎng)按 8長(zhǎng)按松開
  33. //詳解:對(duì)EC11旋轉(zhuǎn)編碼器的動(dòng)作進(jìn)行模式分析
  34. //*******************************************************************/
  35. unsigned char Encoder_EC11_Scan(tongdaoHC *HC)
  36. {
  37. unsigned char ScanResult = 0; //用于分析編碼器動(dòng)作的變量
  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相當(dāng)前狀態(tài)和上次狀態(tài)都為低電平時(shí),抓B相上次狀態(tài)為高當(dāng)前狀態(tài)為低的下降沿。
  41. {
  42. ScanResult = 1; //正轉(zhuǎn)
  43. }
  44. else if(!HC->EC11_A_dq && HC->EC11_A_Last && !HC->EC11_B_dq && !HC->EC11_B_Last) //B相當(dāng)前狀態(tài)和上次狀態(tài)都為低電平時(shí),抓A相上次狀態(tài)為高當(dāng)前狀態(tài)為低的下降沿。
  45. {
  46. ScanResult = 2; //反轉(zhuǎn)
  47. }
  48. HC->EC11_A_Last = HC->EC11_A_dq; //更新編碼器上一個(gè)狀態(tài)暫存變量
  49. HC->EC11_B_Last = HC->EC11_B_dq; //更新編碼器上一個(gè)狀態(tài)暫存變量

  50. if(HC->EC11_D_dq == 0) //如果EC11的按鍵按下,
  51. {
  52. if(ScanResult == 0) //狀態(tài)記錄值為0表示EC11沒有轉(zhuǎn)動(dòng)
  53. {
  54. ScanResult = 5; //返回值為5
  55. }        
  56. else
  57. {
  58. if(ScanResult == 1) //按下按鍵時(shí)候正轉(zhuǎn)
  59. {
  60. HC->EC11_IN_Click = 7;
  61. return 3; //編碼器按鍵按下并正轉(zhuǎn)返回值為3
  62. }        
  63. if(ScanResult == 2) //按下按鍵時(shí)候反轉(zhuǎn)
  64. {
  65. HC->EC11_IN_Click = 7;
  66. return 4; //編碼器按鍵按下并反轉(zhuǎn)返回值為4
  67. }        
  68. }
  69. }
  70. else //如果EC11的按鍵沒有按下,
  71. {
  72. if(ScanResult=1)
  73. return 1; //編碼器正轉(zhuǎn)返回值為1
  74. else if(ScanResult=2)
  75. return 2; //編碼器正轉(zhuǎn)返回值為1
  76. }        

  77. if(HC->EC11_IN_Click = 7)//有旋轉(zhuǎn)動(dòng)作等待釋放
  78. {
  79. if(ScanResult==0) //按鍵被釋放
  80. {
  81. HC->EC11_IN_Click = 0; //按鍵狀態(tài)機(jī)清零
  82. }
  83. }        
  84. else //沒有旋轉(zhuǎn)動(dòng)作等待進(jìn)入按鍵處理
  85. {
  86. if(HC->EC11_j_COUNT<3000) //打開按鍵按下時(shí)間定時(shí)器
  87. HC->EC11_j_COUNT++;
  88. switch (HC->EC11_IN_Click) //狀態(tài)機(jī)
  89. {
  90. case 0://初始狀態(tài)
  91. if(ScanResult==5)
  92. {
  93. HC->EC11_IN_Click = 1; //進(jìn)入狀態(tài)1有鍵按下
  94. HC->EC11_j_COUNT = 0; //復(fù)位計(jì)時(shí)器
  95. }
  96. break;
  97. case 1://有鍵按下狀態(tài)
  98. if(ScanResult==5 && HC->EC11_j_COUNT > KEY_COUNT_DESHAKING)//按下消抖時(shí)間結(jié)束
  99. {
  100. HC->EC11_IN_Click = 2; //進(jìn)入狀態(tài)2按鍵以穩(wěn)定按下。
  101. }
  102. break;        
  103. case 2://按鍵以穩(wěn)定按下。

  104. if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==0)//按鍵釋放且計(jì)時(shí)小于180MS
  105. {
  106. HC->EC11_IN_Click = 3;//進(jìn)入狀態(tài)3按鍵雙擊等待狀態(tài)。
  107. HC->EC11_j_COUNT = 0; //復(fù)位計(jì)時(shí)器
  108. }
  109. else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==5)//按鍵按下且計(jì)時(shí)大于180MS
  110. {
  111. HC->EC11_IN_Click = 5;//進(jìn)入狀態(tài)5按鍵長(zhǎng)按等待狀態(tài)。
  112. }
  113. break;
  114. case 3://按鍵雙擊等待狀態(tài)。
  115. if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==5)//按鍵按下且計(jì)時(shí)重新計(jì)數(shù)小于180MS
  116. {
  117. HC->EC11_IN_Click = 4;//進(jìn)入狀態(tài)4按鍵雙擊二次按下狀態(tài)。
  118. HC->EC11_j_COUNT = 0; //復(fù)位計(jì)時(shí)器
  119. }
  120. else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==0)//按鍵釋放且計(jì)時(shí)重新計(jì)數(shù)大于180MS
  121. {
  122. HC->EC11_IN_Click = 0; //按鍵狀態(tài)機(jī)清零
  123. return 5;//單擊返回1

  124. }
  125. break;
  126. case 4://按鍵雙擊二次按下狀態(tài)。
  127. if(HC->EC11_j_COUNT > KEY_COUNT_DESHAKING && ScanResult==0)//按下消抖時(shí)間結(jié)束且按鍵被釋放
  128. {
  129. HC->EC11_IN_Click = 0; //按鍵狀態(tài)機(jī)清零
  130. return 6;        //雙擊返回鍵值        
  131. }
  132. break;
  133. case 5://按鍵長(zhǎng)按等待狀態(tài)。
  134. if(HC->EC11_j_COUNT <KEY_COUNT_LONGT && ScanResult==0)//按鍵被釋放且計(jì)時(shí)小于1600MS
  135. {
  136. HC->EC11_IN_Click = 0; //按鍵狀態(tài)機(jī)清零
  137. return 5;//單擊返回1
  138. }
  139. else if(HC->EC11_j_COUNT >=KEY_COUNT_LONGT && ScanResult==5)//記錄鍵值在按下鍵值表里且計(jì)時(shí)大于1600MS
  140. {
  141. HC->EC11_IN_Click = 6;//進(jìn)入狀態(tài)6按鍵長(zhǎng)按時(shí)間到達(dá)狀態(tài)。
  142. HC->EC11_j_COUNT = 0; //復(fù)位計(jì)時(shí)器
  143. return 7;//連續(xù)按下返回鍵值
  144. }        
  145. break;
  146. case 6://按鍵長(zhǎng)按時(shí)間以到達(dá)。
  147. if(ScanResult==0) //按鍵被釋放
  148. {
  149. HC->EC11_IN_Click = 0; //按鍵狀態(tài)機(jī)清零
  150. return 8;//連續(xù)按下松開返回鍵值
  151. }
  152. else if(HC->EC11_j_COUNT >=KEY_LONG_REPEAT && ScanResult==5)//記錄鍵值在按下鍵值表里大于200MS
  153. {
  154. HC->EC11_j_COUNT = 0; //復(fù)位計(jì)時(shí)器
  155. return 7;//連續(xù)按下返回鍵值
  156. }
  157. break;
  158. }
  159. }        
  160. return 0;//沒有按鍵返回0
  161. }

  162. #endif
復(fù)制代碼


作者: amwbsrhk    時(shí)間: 2023-3-3 10:52
慢旋加1快旋加5少了中間的數(shù)值,慢旋加1慢,快旋加1變快
作者: 君工創(chuàng)    時(shí)間: 2023-3-3 11:08
如果你已經(jīng)能正確讀取編碼器并顯示的話,就是加上時(shí)間識(shí)別就可以了。
作者: Y_G_G    時(shí)間: 2023-3-3 21:44
這種功能是真的雞肋,甚至是反人類設(shè)計(jì)
優(yōu)利德示波器用的就是這種設(shè)計(jì),要測(cè)量電壓,時(shí)間數(shù)據(jù),扭半天都扭不到位置,扭慢了一動(dòng)不動(dòng)的,一扭快了就飛到另一邊去
調(diào)個(gè)位置像做賊一樣,得一下一下扭...........
作者: bfdz    時(shí)間: 2023-3-4 10:08
接觸過幾臺(tái)用飛梭旋鈕的設(shè)備,飛梭旋鈕帶按壓開關(guān)的

按一下飛梭旋鈕,旋轉(zhuǎn)飛梭快進(jìn),再按一下飛梭旋鈕,旋轉(zhuǎn)飛梭慢進(jìn),感覺挺方便的
作者: yuxuesuixing    時(shí)間: 2023-3-4 11:56
根據(jù)狀態(tài)機(jī)思想編程實(shí)際可用的代碼需要占用一個(gè)外部中斷一個(gè)定時(shí)器。
外部中斷負(fù)責(zé)判斷旋鈕左右旋轉(zhuǎn),記得旋鈕硬件并聯(lián)22nf電容來硬件濾波,這樣單片機(jī)不用消抖了。
旋鈕方向代碼如下
void INT0_Isr() interrupt 0 using 1
{ //必須加消抖電容22nf
  bit bZZ = 0;//使用該臨時(shí)變量是為了加快端口讀取過程
        if (KL) {if (!KR) bZZ = 1;} //上跳
        else{if (KR) bZZ = 1;} //下跳
        if (bZZ) KT++; //正傳
        else KT--; //反轉(zhuǎn)
}
定時(shí)器呢負(fù)責(zé)判斷快旋轉(zhuǎn)慢旋轉(zhuǎn),定時(shí)器觸發(fā)時(shí)記錄當(dāng)前的旋鈕值,當(dāng)前旋鈕值與上次旋鈕值比較,如果差距大就將旋轉(zhuǎn)值乘以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旋轉(zhuǎn)值大于2說明旋轉(zhuǎn)的比較快  ,旋轉(zhuǎn)值乘以5,注意這里KT是有符號(hào)變量 可以為負(fù)值

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





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1