標(biāo)題: ec11編碼器誰有好用的單片機代碼?現(xiàn)在抖動嚴重,亂跳 中斷方式也步進丟失 [打印本頁]

作者: szqkfsskk    時間: 2022-5-7 18:41
標(biāo)題: ec11編碼器誰有好用的單片機代碼?現(xiàn)在抖動嚴重,亂跳 中斷方式也步進丟失
ec11編碼器誰有好用的代碼共享一下,現(xiàn)在的代碼抖動嚴重,亂跳。用過中斷方式也不好用,一樣會出現(xiàn)步進丟失。

作者: xuyaqi    時間: 2022-5-7 19:13
要在硬件上下功夫。
作者: w1179benp    時間: 2022-5-7 19:27
看看下面這個程序,我把它改在控制LED流水方向上,OK的。注意EC11幾個端子的電容是防抖動。
// Header:  編碼開關(guān)代碼   
// File Name: Encoder   
// Author:  李波   
// Date: 2009-04-19  20161129在開發(fā)板上完美運行:通過編碼器EC11控制流水燈流動
/*========================================  
本代碼為編碼開關(guān)代碼,編碼開關(guān)也就是數(shù)字音響中的  
360度旋轉(zhuǎn)的數(shù)字音量以及顯示器上用的(單鍵飛梭開  
關(guān))等類似鼠標(biāo)滾輪的手動計數(shù)輸入設(shè)備。  
我使用的編碼開關(guān)為5個引腳的,其中2個引腳為按下  
轉(zhuǎn)輪開關(guān)(也就相當(dāng)于鼠標(biāo)中鍵)一個接地,另一個P3.4。另外3個引腳用來  
檢測旋轉(zhuǎn)方向以及旋轉(zhuǎn)步數(shù)的檢測端。引腳分別為a,b,c  
b接地;a,c分別接到P3.3和P3.2口并分別接兩個10K上拉  
電阻,并且a,c需要分別對地接一個104的電容,否則  
因為編碼開關(guān)的觸點抖動會引起輕微誤動作。本程序不  
使用定時器,不占用中斷,不使用延時代碼,并對每個  
細分步數(shù)進行判斷,避免一切誤動作,性能超級穩(wěn)定。  
我使用的編碼器是APLS的EC11可以參照附件的時序圖  
編碼器控制流水燈最能說明問題,下面是以一段流水  
燈來演示。  
(單片機為STC89C52)=================*/   
#include <REGX52.H>   
#include <intrins.h>   
#define uint unsigned int   
#define uchar unsigned char   
#define NULL 0   

uchar x,WheelOld;   
uchar Led=0xfe;//LED流水燈初始化   

sbit SJ=P1^4;       //LED的使能端  YY開發(fā)板特有
sbit WEI=P2^1;      //74HC573的LE端 U4 LED的位選端 YY開發(fā)板特有,熄滅數(shù)碼管
   
/*定義一下端口為編碼器開關(guān)輸入端=========*/   
sbit PINA=P3^2;    //定義編碼器連接的IO   
sbit PINB=P3^3;    //定義編碼器連接的IO   
   
/*過程返回==========*/   
uchar WheelLeft()      
{      
     //左轉(zhuǎn)一步的操作   
        Led=_crol_(Led,1);         
    return(NULL);      
}     

uchar WheelRight()      
{      
     //右轉(zhuǎn)一步的操作   
     Led=_cror_(Led,1);   
     return(NULL);      
}     
   
/*編碼器過程====================*/   
uchar EncoderProcess()   
{      
     uchar keytmp,keytmp1,keytmp2,WheelNow;   
   
     PINA=1; //PINA至高電平   
     PINB=1;//PINB至高電平   
     if(PINA==1) //如果PINA為高電平   
         {   
         keytmp1=0x01;   
         }   
     else keytmp1=0;     
     if(PINB==1) //如果PINB為高電平   
         {   
         keytmp2=0x02;   
         }   
     else keytmp2=0;   
     WheelNow=keytmp1+keytmp2; //根據(jù)兩個IO組合成16進制數(shù)為0x00|0x01|0x02|0x03   
     keytmp=WheelNow;   
     keytmp^=WheelOld;  //判斷新數(shù)據(jù)同舊數(shù)據(jù)   
     if(keytmp==0) return(NULL); //如果新數(shù)據(jù)和原來的數(shù)據(jù)一樣 就直接退出   
     if(WheelOld==0 && WheelNow==0x01)   
         {   
         x=WheelNow;   
         }   
   
     if(WheelOld==0 && x==0x01 && WheelNow==0x03)   
         {   
         WheelOld=WheelNow;   
         x=0;   
         return(WheelLeft()); //左旋轉(zhuǎn)00 01 03   
         }   
   
     if(WheelOld==0x03 && WheelNow==0x02)   
         {   
         x=WheelNow;   
         }   
   
     if(WheelOld==0x03 && x==0x02 && WheelNow==0x00)   
         {   
         WheelOld=WheelNow;   
         x=0;   
         return(WheelLeft()); //左旋轉(zhuǎn)03 02 00   
         }   
   
     if(WheelOld==0 && WheelNow==0x02)   
         {   
         x=WheelNow;   
         }   
   
     if(WheelOld==0 && x==0x02 && WheelNow==0x03)   
         {   
         WheelOld=WheelNow;   
         x=0;           
         return(WheelRight());  //右旋轉(zhuǎn)00 02 03   
         }   
   
     if(WheelOld==0x03 && WheelNow==0x01)   
         {   
         x=WheelNow;   
         }   
   
     if(WheelOld==0x03 && x==0x01 && WheelNow==0x00)   
         {   
         WheelOld=WheelNow;   
         x=0;      
         return(WheelRight());  //右旋轉(zhuǎn)03 01 10   
         }   
   
}   

void main()   
{      
        SJ=0;        //開LED總使能 YY開發(fā)板特有   
    WEI=1;
        P0=0xff;
        WEI=0;   
    while (1)   
    {   
            EncoderProcess();   
            P0=Led; //流水燈連接的IO   
    }   
}

作者: szqkfsskk    時間: 2022-5-7 20:19
我天代碼這么長。
作者: 188610329    時間: 2022-5-7 20:56


  1. <p>sbit INT0 = P3^2;  //EC11 PinA
  2. sbit INT1 = P3^3;  //EC11 PinB
  3. unsigned char KeyValue;</p><p>
  4. </p><p>void main()
  5. {
  6. INT0 = 1;
  7. INT1 = 1;
  8. IE0 = 0;
  9. IE1 = 0;
  10. IT0 = 1;
  11. IT1 = 1;
  12. EX0 = 1;
  13. EX1 = 1;
  14. EA = 1;
  15. while(1);</p><p>}</p><p>
  16. void EC11_Reset()   //消抖
  17. {
  18. unsigned char i;
  19. while((IE0)||(IE1)||(!INT0)||(!INT1)) //等待 INT0, INT1 無抖動高電平
  20. {
  21.   IE0 = 0;
  22.   IE1 = 0;
  23.   i = 200; //根據(jù)需要定義
  24.   while(--i);
  25. }
  26. }</p><p>void EX_INT_0() interrupt 0
  27. {
  28. while(INT1);  //等待 INT1 低電平
  29. EC11_Reset();  //等待 EC11 回初始狀態(tài)
  30. KeyValue++;
  31. }</p><p>void EX_INT_1() interrupt 2
  32. {
  33. while(INT0);  //等待 INT0 低電平
  34. EC11_Reset();  //等待 EC11 回初始狀態(tài)
  35. KeyValue--;
  36. }</p>
復(fù)制代碼
優(yōu)點:開關(guān)未旋轉(zhuǎn)時,不占用系統(tǒng)資源。
缺點:旋轉(zhuǎn)時比較占用系統(tǒng)資源。
建議:如經(jīng)常旋轉(zhuǎn),并且系統(tǒng)比較繁忙,可以加定時器,編碼器觸發(fā)中斷后,先關(guān)閉外部中斷,通過定時器來等待編碼器復(fù)位后,重開外部中斷。



作者: wulin    時間: 2022-5-7 20:59
  1. //測試條件:TX-1C開發(fā)板
  2. //杜邦線直接連接ABC端,未接消抖電容
  3. //正�?炻炙傥匆娬`碼
  4. #include "reg51.h"

  5. typedef unsigned char uchar;
  6. typedef unsigned int  uint;

  7. sbit EC11_A=P3^2;
  8. sbit EC11_C=P3^3;
  9. sbit EC11_B=P3^4;

  10. sbit dula=P2^6;                                        //段
  11. sbit wela=P2^7;                                        //位
  12. //        共陰數(shù)碼管標(biāo)準(zhǔn)字庫       
  13. unsigned char code table[32]={                               
  14. //         0    1    2    3    4    5    6    7    8    9   10A  11B  12C  13D  14E  15F
  15.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  16. //  16黑  17- 18H   19J         20K  21L  22N        23o  24P  25U  26t 27G   28Q  29r  30M  31y
  17.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e};
  18. unsigned char  data dis_buf[4];                        //顯示緩存
  19. unsigned char count=50;
  20. unsigned char traitA,traitB;
  21. void display()
  22. {
  23.         static unsigned char  i;
  24.         P0=0x00;dula=1;dula=0;
  25.         P0=~(0x01<<i);wela=1;wela=0;
  26.         P0=dis_buf[i];dula=1;dula=0;
  27.         i=++i%4;
  28. }

  29. void main()
  30. {
  31.         EC11_C=0;
  32.         while (1)
  33.         {
  34.                 dis_buf[0]=table[17];
  35.                 dis_buf[1]=table[count/100%10];
  36.                 dis_buf[2]=table[count/10%10];
  37.                 dis_buf[3]=table[count%10];
  38.                 display();
  39.                 //順時針旋轉(zhuǎn),每圈進階20
  40.                 if(EC11_B && !EC11_A && traitA==0)          //第一特征碼,如不符合則立即進行反轉(zhuǎn)判斷
  41.                 {
  42.                         traitA=1;
  43.                 }
  44.                 else if(!EC11_B && !EC11_A && traitA==1)//第二特征碼
  45.                 {
  46.                         traitA=2;
  47.                 }
  48.                 else if(!EC11_B && EC11_A && traitA==2)//第三特征碼
  49.                 {
  50.                         if(count>0)count--;
  51.                         traitA=3;
  52.                 }
  53.                 else if(EC11_B && EC11_A)//第四特征碼
  54.                 {
  55.                         traitA=0;//清0
  56.                 }
  57.                 //逆時針旋轉(zhuǎn)
  58.                 if(!EC11_B && EC11_A && traitB==0)          //第一特征碼,如不符合則立即進行正轉(zhuǎn)判斷
  59.                 {
  60.                         traitB=1;
  61.                 }
  62.                 else if(!EC11_B && !EC11_A && traitB==1)//第二特征碼
  63.                 {
  64.                         traitB=2;
  65.                 }
  66.                 else if(EC11_B && !EC11_A && traitB==2)//第三特征碼
  67.                 {
  68.                         if(count<250)count++;
  69.                         traitB=3;
  70.                 }
  71.                 else if(EC11_B && EC11_A)//第四特征碼
  72.                 {
  73.                         traitB=0;//清0
  74.                 }
  75.         }
  76. }

復(fù)制代碼

作者: lkc8210    時間: 2022-5-7 23:20
szqkfsskk 發(fā)表于 2022-5-7 20:19
我天代碼這么長。


只有六行,夠短了吧
  1.             if(!PinA && PinA_O && PinB) {

  2.                  Now++;

  3.              }PinA_O = PinA;               

  4.              if(!PinB && PinB_O && PinA) {

  5.                  Now--;

  6.              }PinB_O = PinB;        
復(fù)制代碼




詳情請看我的貼子


作者: 人人學(xué)會單片機    時間: 2022-5-7 23:52
void ROTARY_ROTARY_Scan_Drive(void)
{
        static xdata u8 count=0,Rotary_Flag=0;
        if(count>30)
        {
                count=0;
                if((ROTARY_B==0)&&(Rotary_Flag==0))                        //如果按鍵B按下,且flag是0       
                {
                        Rotary_Flag=1;
                        Rotary_Read_Data_Rotary++;                                //按鍵值增加1
                }
                if((ROTARY_A==0)&&(Rotary_Flag==0))                        //如果按鍵A按下,且flag是0       
                {
                        Rotary_Flag=1;
                        Rotary_Read_Data_Rotary--;                                //按鍵值減少1
                }
                if((ROTARY_B!=0)&&(ROTARY_A!=0))                        //按鍵必須釋放,下次按鍵才有效
                {
                        Rotary_Flag=0;
                }
        }
        count++;
}

主函數(shù)直接循環(huán)掃描這個函數(shù)就行了,人人學(xué)會單片機!對付人手還是可以的,如果是光電編碼器 不適合此代碼。
作者: Y_G_G    時間: 2022-5-8 09:21
lkc8210 發(fā)表于 2022-5-7 23:20
只有六行,夠短了吧

經(jīng)過燒錄驗證,并不行
不用轉(zhuǎn)動,搖一下EC11的搖桿,NOW就會改變
轉(zhuǎn)一半,再不轉(zhuǎn),NOW也會改變
你帖子我看了,波形不需要分析,只看實際結(jié)果
作者: Y_G_G    時間: 2022-5-8 09:24
如果單片機不著急處理太多的東西,可以用定時器1mS掃描一次AB兩個IO來判斷轉(zhuǎn)動
不用加電容,不用加去抖動
作者: lkc8210    時間: 2022-5-8 10:12
Y_G_G 發(fā)表于 2022-5-8 09:21
經(jīng)過燒錄驗證,并不行
不用轉(zhuǎn)動,搖一下EC11的搖桿,NOW就會改變
轉(zhuǎn)一半,再不轉(zhuǎn),NOW也會改變

如果不分析波形,只看實際結(jié)果
有沒有可能…
你的實際和我的實際有點不一樣?

if(ScanCount++ > 50)//這里有調(diào)大一點嗎?
作者: Y_G_G    時間: 2022-5-8 11:12
lkc8210 發(fā)表于 2022-5-8 10:12
如果不分析波形,只看實際結(jié)果
有沒有可能…
你的實際和我的實際有點不一樣?

沒有調(diào)大,我只是復(fù)制驗證一下而已
并不是每次都會變動,單純的找BUG一樣去試的話,會有問題
如果只是正常使用,我轉(zhuǎn)了就不再調(diào)回來,那效果還是可以的
作者: zsttom    時間: 2022-7-1 21:23
wulin 發(fā)表于 2022-5-7 20:59

ytyt 放謝謝,很好用
作者: 1233389    時間: 2023-12-7 21:11
論證才有進步
作者: acben    時間: 2024-8-1 06:34
lkc8210 發(fā)表于 2022-5-7 23:20
只有六行,夠短了吧



以前看見過這個代碼,后來就找不到了,謝謝




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