久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2238|回復: 24
打印 上一主題 下一主題
收起左側

單片機旋轉編碼器旋轉速度的問題請教一下

  [復制鏈接]
跳轉到指定樓層
樓主
普通51單片機用旋轉編碼器控制數碼管顯示數字的增減,步進值固定為1(數碼管顯示的數字都是逐一增加,不出現跳數)。當旋轉速度快時,顯示數字加減就快;旋轉速度慢時,顯示數字加減就慢(比如同樣旋轉90°,時間為2s數字就加5,時間為1s就加10,且顯示不出現跳數的情況)

請問各位大佬有沒有實現這個功能的思路,謝謝。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:857072 發表于 2024-4-7 11:09 來自手機 | 只看該作者
天問51的庫函數搬來你看看,也可以自己去翻代碼全開源的。


#ifndef _EC11_51_H_
#define _EC11_51_H_


//----------------編碼器參數微調宏定義----------------//
#ifndef KEY_COUNT_DESHAKING
#define KEY_COUNT_DESHAKING      15      //按鍵消抖時間15
#endif
#ifndef KEY_COUNT_LONGT
#define KEY_COUNT_LONGT          1500    //長按按鍵判斷時間1500
#endif
#ifndef KEY_COUNT_DUAL
#define KEY_COUNT_DUAL           180     //雙擊按鍵判斷時間180
#endif
#ifndef KEY_LONG_REPEAT
#define KEY_LONG_REPEAT          200     //長按按鍵的回報率的倒數,即一直長按按鍵時響應的時間間隔200
#endif

//----------------重入緩存結構體----------------//
typedef struct tongdaoHC {
        unsigned char    EC11_A_dq;                         //EC11的A引腳讀到的當前狀態
        unsigned char    EC11_B_dq;                         //EC11的B引腳讀到的當前狀態
        unsigned char    EC11_D_dq;                         //EC11的D引腳讀到的當前狀態
        unsigned char    EC11_A_Last;                       //EC11的A引腳上一次的狀態
        unsigned char    EC11_B_Last;                       //EC11的B引腳上一次的狀態
        unsigned char    EC11_IN_Click;                                //EC11按鍵狀態機動作標志
        unsigned char    EC11_j_km;                         //EC11判斷轉動快慢的計數器
        unsigned int     EC11_j_COUNT;                      //EC11按鍵動作計數器       
       
}tongdaoHC;

//----------------函數聲明列表----------------//
unsigned char Encoder_EC11_Scan(tongdaoHC *HC);

//*******************************************************************/
//功能:掃描EC11旋轉編碼器的動作并動作分析
//形參:無
//返回:EC11動作返回 0無動作 1正轉 2反轉 3按著按鍵正轉 4按著按鍵反轉 5短按 6雙擊 7長按 8長按松開
//詳解:對EC11旋轉編碼器的動作進行模式分析
//*******************************************************************/
unsigned char Encoder_EC11_Scan(tongdaoHC *HC)
{
    unsigned char ScanResult = 0;    //用于分析編碼器動作的變量
        if(HC->EC11_j_km)
        HC->EC11_j_km--;
        if(!HC->EC11_A_dq && !HC->EC11_A_Last && !HC->EC11_B_dq && HC->EC11_B_Last)   //A相當前狀態和上次狀態都為低電平時,抓B相上次狀態為高當前狀態為低的下降沿。
                {                    
                        ScanResult = 1;     //正轉
                }
        else if(!HC->EC11_A_dq && HC->EC11_A_Last && !HC->EC11_B_dq && !HC->EC11_B_Last)  //B相當前狀態和上次狀態都為低電平時,抓A相上次狀態為高當前狀態為低的下降沿。
                {
                        ScanResult = 2;     //反轉
                }
                HC->EC11_A_Last = HC->EC11_A_dq;   //更新編碼器上一個狀態暫存變量
                HC->EC11_B_Last = HC->EC11_B_dq;   //更新編碼器上一個狀態暫存變量
               
    if(HC->EC11_D_dq == 0)          //如果EC11的按鍵按下,
    {
        if(ScanResult == 0)         //狀態記錄值為0表示EC11沒有轉動
                {
            ScanResult = 5;         //返回值為5
                }       
        else
        {
            if(ScanResult == 1)     //按下按鍵時候正轉
                                {
                                        HC->EC11_IN_Click = 7;
                                        return 3;       //編碼器按鍵按下并正轉返回值為3
                                }       
            if(ScanResult == 2)     //按下按鍵時候反轉
                                {
                                        HC->EC11_IN_Click = 7;
                                        return 4;       //編碼器按鍵按下并反轉返回值為4
                                }       
        }
    }
        else                         //如果EC11的按鍵沒有按下,
        {
        if(ScanResult==1)
                return 1;                //編碼器正轉返回值為1
                else if(ScanResult==2)
                return 2;                //編碼器反轉返回值為2
        }               

        if(HC->EC11_IN_Click = 7)//有旋轉動作等待釋放
        {
                if(ScanResult==0) //按鍵被釋放
                        {
                                HC->EC11_IN_Click = 0;   //按鍵狀態機清零
                        }
        }               
        else           //沒有旋轉動作等待進入按鍵處理
        {
                if(HC->EC11_j_COUNT<3000)    //打開按鍵按下時間定時器
                HC->EC11_j_COUNT++;
                switch (HC->EC11_IN_Click) //狀態機
                {
                   case 0://初始狀態
                                if(ScanResult==5)
                                        {
                                                HC->EC11_IN_Click = 1;   //進入狀態1有鍵按下
                                                HC->EC11_j_COUNT = 0; //復位計時器
                                        }
                        break;
                   case 1://有鍵按下狀態
                                if(ScanResult==5 && HC->EC11_j_COUNT > KEY_COUNT_DESHAKING)//按下消抖時間結束
                                        {
                                                HC->EC11_IN_Click = 2;   //進入狀態2按鍵以穩定按下。
                                        }
                        break;               
                   case 2://按鍵以穩定按下。
                  
                           if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==0)//按鍵釋放且計時小于180MS
                                   {
                                           HC->EC11_IN_Click = 3;//進入狀態3按鍵雙擊等待狀態。
                                           HC->EC11_j_COUNT = 0; //復位計時器
                                   }
                           else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==5)//按鍵按下且計時大于180MS
                                   {
                                           HC->EC11_IN_Click = 5;//進入狀態5按鍵長按等待狀態。
                                   }
                        break;
                   case 3://按鍵雙擊等待狀態。
                           if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==5)//按鍵按下且計時重新計數小于180MS
                                   {
                                           HC->EC11_IN_Click = 4;//進入狀態4按鍵雙擊二次按下狀態。
                                           HC->EC11_j_COUNT = 0; //復位計時器
                                   }
                           else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==0)//按鍵釋放且計時重新計數大于180MS
                                   {
                                           HC->EC11_IN_Click = 0;   //按鍵狀態機清零
                                           return 5;//單擊返回5

                                   }
                        break;
                        case 4://按鍵雙擊二次按下狀態。
                           if(HC->EC11_j_COUNT > KEY_COUNT_DESHAKING && ScanResult==0)//按下消抖時間結束且按鍵被釋放
                                   {
                                           HC->EC11_IN_Click = 0;   //按鍵狀態機清零
                                           return 6;        //雙擊返回鍵值6       
                                   }                           
                        break;
                        case 5://按鍵長按等待狀態。
                           if(HC->EC11_j_COUNT <KEY_COUNT_LONGT && ScanResult==0)//按鍵被釋放且計時小于1600MS
                                   {
                                           HC->EC11_IN_Click = 0;   //按鍵狀態機清零
                                           return 5;//單擊返回5
                                   }
                           else if(HC->EC11_j_COUNT >=KEY_COUNT_LONGT && ScanResult==5)//記錄鍵值在按下鍵值表里且計時大于1600MS
                                   {
                                                HC->EC11_IN_Click = 6;//進入狀態6按鍵長按時間到達狀態。
                                                HC->EC11_j_COUNT = 0; //復位計時器
                                                return 7;//連續按下返回鍵值
                                   }                  
                        break;
                        case 6://按鍵長按時間以到達。
                           if(ScanResult==0) //按鍵被釋放
                                   {
                                                HC->EC11_IN_Click = 0;   //按鍵狀態機清零
                                                return 8;//連續按下松開返回鍵值
                                   }
                           else if(HC->EC11_j_COUNT >=KEY_LONG_REPEAT && ScanResult==5)//記錄鍵值在按下鍵值表里大于200MS
                                   {
                                           HC->EC11_j_COUNT = 0; //復位計時器
                                                return 7;//連續按下返回鍵值
                                   }
                        break;
                }
        }       
        return 0;//沒有按鍵返回0
}   

#endif

12~80TSX9$`AQJIHGRXKD6B.png (336.83 KB, 下載次數: 58)

12~80TSX9$`AQJIHGRXKD6B.png
回復

使用道具 舉報

板凳
ID:883242 發表于 2024-4-7 13:51 | 只看該作者
編碼器的分辨率是多少?
回復

使用道具 舉報

地板
ID:857072 發表于 2024-4-7 18:45 | 只看該作者
Hephaestus 發表于 2024-4-7 13:51
編碼器的分辨率是多少?

手調的編碼器,一圈十幾二十步的,又不是電機編碼器還講分辨率。。
回復

使用道具 舉報

5#
ID:213173 發表于 2024-4-7 18:53 | 只看該作者
如果發現正常手速旋轉會丟數,大概率是程序寫的有毛病。
回復

使用道具 舉報

6#
ID:213173 發表于 2024-4-7 20:36 | 只看該作者
a185980800 發表于 2024-4-7 18:45
手調的編碼器,一圈十幾二十步的,又不是電機編碼器還講分辨率。。

EC11或EC16,只要軟件硬件配合的好,每秒轉20圈的速度不影響正確計數和判斷正反轉,
回復

使用道具 舉報

7#
ID:1034262 發表于 2024-4-7 23:26 | 只看該作者
一般手動編碼器是20脈沖一圈,假設轉1圈耗時200ms(這個應該算很快的了),則10ms一個脈沖,對于單片機來說,10ms還是很慢的,所以做到+1沒有問題。
回復

使用道具 舉報

8#
ID:1109793 發表于 2024-4-8 07:27 | 只看該作者
我在哪個帖子里面回過一種方法,比較直觀,也是網上找到的。你搜索一下能找到。
回復

使用道具 舉報

9#
ID:883242 發表于 2024-4-8 07:59 | 只看該作者
a185980800 發表于 2024-4-7 18:45
手調的編碼器,一圈十幾二十步的,又不是電機編碼器還講分辨率。。

用中斷,一只引腳做中斷觸發,發生中斷查另一只引腳電平就能知道旋轉方向。poll方式效率太低了。
回復

使用道具 舉報

10#
ID:88256 發表于 2024-4-8 08:00 | 只看該作者
我估計大家都理解錯了樓主的問題,樓主的想法應該和這樣類似的,假如屏幕顯示97.5 ,慢速旋轉步進是0.1 ,快速旋轉并且脈沖數達到10個后,步進是1 ;如果持續快速旋轉并且達到一定的脈沖數,步進數是10 。
回復

使用道具 舉報

11#
ID:680429 發表于 2024-4-8 08:59 | 只看該作者
hhdsdy 發表于 2024-4-8 08:00
我估計大家都理解錯了樓主的問題,樓主的想法應該和這樣類似的,假如屏幕顯示97.5 ,慢速旋轉步進是0.1 , ...

步進值是固定的都是1,但是比如旋轉同樣角度,快旋加5,慢旋只加1,而且快旋加5是0、1、2、3、4、5這樣加上去,而不是0直接到5,把中間的1、2、3、4這幾個數丟了
回復

使用道具 舉報

12#
ID:680429 發表于 2024-4-8 09:04 | 只看該作者
coody_sz 發表于 2024-4-7 23:26
一般手動編碼器是20脈沖一圈,假設轉1圈耗時200ms(這個應該算很快的了),則10ms一個脈沖,對于單片機來說 ...

現在能做到+1,但是就是快旋和慢旋沒區別,有沒有辦法做到區分快、慢旋,并且顯示上不丟數
回復

使用道具 舉報

13#
ID:680429 發表于 2024-4-8 09:06 | 只看該作者
wulin 發表于 2024-4-7 18:53
如果發現正常手速旋轉會丟數,大概率是程序寫的有毛病。

現在能正確計數,正反判斷也正常,也不會丟數,就是區分不了快慢旋
回復

使用道具 舉報

14#
ID:680429 發表于 2024-4-8 09:08 | 只看該作者
xiaobendan001 發表于 2024-4-8 07:27
我在哪個帖子里面回過一種方法,比較直觀,也是網上找到的。你搜索一下能找到。

好像沒有找到帖子。。
回復

使用道具 舉報

15#
ID:857072 發表于 2024-4-8 13:06 來自手機 | 只看該作者
快慢轉的判斷就是建立一個用于計時的變量,然后在掃描的定時器中斷里判斷這個變量不為零就一直自減。然后在旋轉的函數里判斷這個值為零就是,慢轉不為零就是快轉,判斷完以后給這個變量賦一個值,這個值就是你判斷快慢轉的間隔時間
回復

使用道具 舉報

16#
ID:1109793 發表于 2024-4-8 15:29 | 只看該作者
要快轉+5還得一個一個加,那就是要在慢的時候5個信號加1了,這樣就得提高編碼器分辨率了。每個信號設置一次定時器,時間到達之前信號又來了說明是快的,否則就是慢的。
回復

使用道具 舉報

17#
ID:213173 發表于 2024-4-8 21:34 | 只看該作者
zjy597662225 發表于 2024-4-8 09:06
現在能正確計數,正反判斷也正常,也不會丟數,就是區分不了快慢旋

樓主的意思是不是快轉比慢轉計數增/減量翻倍,但還要在數碼管上呈現連續數字?
回復

使用道具 舉報

18#
ID:384109 發表于 2024-4-8 21:57 | 只看該作者
樓主還沒搞懂旋轉編碼器的結構和原理
回復

使用道具 舉報

19#
ID:680429 發表于 2024-4-9 09:09 | 只看該作者
wulin 發表于 2024-4-8 21:34
樓主的意思是不是快轉比慢轉計數增/減量翻倍,但還要在數碼管上呈現連續數字?

嗯,是這樣的
回復

使用道具 舉報

20#
ID:996773 發表于 2024-4-9 09:15 | 只看該作者
樓主沒懂旋轉編碼器是什么東東,估計也沒用過,建議樓主拆一個旋轉編碼器看看,旋轉90度?

單片機能知道它轉了90度嗎?
回復

使用道具 舉報

21#
ID:1109793 發表于 2024-4-9 09:21 | 只看該作者
hi等你 發表于 2024-4-9 09:15
樓主沒懂旋轉編碼器是什么東東,估計也沒用過,建議樓主拆一個旋轉編碼器看看,旋轉90度?

單片機能知道 ...

只要知道了分辨率,當然可以知道度數啊。獲得Z軸信號還能知道絕對角度呢。如果是絕對值編碼器,那就更容易了。
回復

使用道具 舉報

22#
ID:996773 發表于 2024-4-9 13:15 | 只看該作者
xiaobendan001 發表于 2024-4-9 09:21
只要知道了分辨率,當然可以知道度數啊。獲得Z軸信號還能知道絕對角度呢。如果是絕對值編碼器,那就更容 ...

其實我也不懂分辨率,也不懂z信號,絕對角度我也不懂,但我會寫,其實編碼器兩腳就相當于

兩個位,01或10,轉了之后變00,啥時候變00就是你的手速,搞個定時器,01時候開始計時,

定時時間短一些看看有沒有到00,到了說明手速快,屏顯加10或者寄存器加10去執行,如果還沒

到00繼續計時,又等了一會看看到了00了,說明手速慢,屏顯加1或者寄存器加1,這種思路去

寫的編碼器程序絲滑無比
回復

使用道具 舉報

23#
ID:1109793 發表于 2024-4-9 14:10 | 只看該作者
hi等你 發表于 2024-4-9 13:15
其實我也不懂分辨率,也不懂z信號,絕對角度我也不懂,但我會寫,其實編碼器兩腳就相當于

兩個位,01 ...

你說的大概就是這樣的吧,這個方法還是不錯的。雖然我沒有實際測試過。
  1. static uchar temp;
  2. temp <<= 2;
  3. if(sig_a)temp += 2;
  4. if(sig_b)temp += 1;
  5. switch(temp&0x0f){
  6.         case 2:case 4:case 11:case 13:
  7.         counter++;                        //脈沖數增加
  8.         break;
  9.         case 1:case 7:case 8:case 14:
  10.         counter--;                //脈沖數減少
  11.         break;
  12.         case 3:case 6:case 9:case 12:
  13.         break;
  14.         }
復制代碼
回復

使用道具 舉報

24#
ID:213173 發表于 2024-4-12 07:17 | 只看該作者

用定時器判斷A脈沖間距以判斷轉速,小于某轉速只計A脈沖數,大于等于參考轉速A、B脈沖都計數。就可以實現快速旋轉編碼器時計數值翻倍并在數碼管上呈現連續數字。
回復

使用道具 舉報

25#
ID:680429 發表于 2024-4-23 13:40 | 只看該作者
wulin 發表于 2024-4-12 07:17
用定時器判斷A脈沖間距以判斷轉速,小于某轉速只計A脈沖數,大于等于參考轉速A、B脈沖都計數。就可以實現 ...

好的我試試,謝謝大佬
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 黄色在线免费观看视频网站 | 久久成人午夜 | 久久久久久久久久久91 | 欧美日韩精品一区二区天天拍 | 欧美三级视频 | 日本欧美国产 | 偷拍自拍在线观看 | 中文字幕乱码一区二区三区 | 久久久久久免费看 | 亚洲乱码一区二区三区在线观看 | 四虎影院在线免费观看 | 成人激情视频在线 | 亚洲精选一区二区 | 一级大片网站 | 亚洲网站在线观看 | 天天爱爱网 | 性一区| 久久中文字幕电影 | 国产美女免费视频 | 365夜爽爽欧美性午夜免费视频 | 最新中文字幕第一页视频 | 久久九七| 中文在线一区二区 | 视频一二三区 | 亚洲444kkkk在线观看最新 | 一级毛片免费视频 | 日韩欧美国产一区二区 | 久久久久国产一区二区三区四区 | www.久草.com | 欧美激情国产精品 | 欧美精品1区2区3区 精品国产欧美一区二区 | 欧美精品一区二区免费视频 | 久久久久9999亚洲精品 | a级在线免费视频 | 亚洲一区免费在线 | av大片 | 狠狠操天天干 | 久久久久亚洲精品中文字幕 | 日韩在线观看网站 | 中文字幕在线播放第一页 | 久久久久国产精品一区二区 |