国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee

ELEOK

標題: 一定位一脈沖的EC11旋轉編碼器最簡潔的單片機驅動代碼 [打印本頁]

作者: eng    時間: 2021-7-6 17:10
標題: 一定位一脈沖的EC11旋轉編碼器最簡潔的單片機驅動代碼
  1. if(!PinA && PinA_O && PinB) {
  2.                 Now++;
  3.             }PinA_O = PinA;               
  4.             if(!PinB && PinB_O && PinA) {
  5.                 Now--;
  6.             }PinB_O = PinB;   
復制代碼
只有六行代碼就能用EC11對Now進行加減操作

為什么這樣寫呢?
上時序圖
順時針轉:


逆時針轉:


我們看到,當順時針轉時
Pin A會早于Pin B 轉低電平,反之亦然

代碼解讀:
!PinA && PinA_O && PinB//當Pin A 為低電平而之前為高電平(即下降沿)并且Pin B為高電平
這一句就捕捉到順時針轉時序圖中箭指著的那一剎那的情況
于是Now加1

!PinB && PinB_O && PinA//當Pin B 為低電平而之前為高電平(即下降沿)并且Pin A為高電平
這一句就捕捉到逆時針轉時序圖中箭指著的那一剎那的情況
于是Now減1

如果編碼器不加電容消抖
就用軟件消抖
  1.         if(ScanCount++ > 50) {        //其數值按單片機速度加減
  2.             ScanCount = 0;
  3.             if(PinA && !PinA_O && PinB) {
  4.                 Now++;
  5.             }PinA_O = PinA;               
  6.             if(PinB && !PinB_O && PinA) {
  7.                 Now--;
  8.             }PinB_O = PinB;                        
  9.             Now>9? Now = 0:_nop_();
  10.             Now<0? Now = 9:_nop_();
  11.         }
復制代碼
現附上小應用實例一則
基如STC15F104E的EC11軟串口六位密碼檢查程序
如發現順逆時針相反,對調PinA/PinB 定義腳即可

  1. #include <STC15F104E.H>
  2. #include "intrins.h"
  3. #include <stdio.h>
  4. #include <string.h>

  5. #define BAUD  0xFF40                  //19200bps @ 11.0592MHz

  6. typedef         bit BOOL;
  7. typedef         unsigned char BYTE;
  8. typedef         unsigned int WORD;

  9. typedef         signed char                s8;  //–128 to 127
  10. typedef         unsigned char        u8;  //0 to 255
  11. typedef         signed int                s16;  //-32768 — 32767
  12. typedef         unsigned int        u16;  //0 — 65535
  13. typedef         signed long                s32;  //-2147483648 — 2147483647
  14. typedef         unsigned long        u32;  //0 — 4294967295

  15. sbit RXB = P3^0;                        //define UART TX/RX port
  16. sbit TXB = P3^1;
  17. sbit PinA = P3^3;
  18. sbit PinB = P3^4;
  19. sbit Enter = P3^2;

  20. BYTE TBUF,RBUF;
  21. BYTE TDAT,RDAT;
  22. BYTE TCNT,RCNT;
  23. BYTE TBIT,RBIT;
  24. BOOL TING,RING;
  25. BOOL TEND,REND;

  26. void UART_INIT();
  27. void SendString(char *s);
  28. void SendData(BYTE dat);
  29. void Delayms(u16 i);

  30. u32 PW = 0;
  31. u16 BuffIndex;
  32. BYTE t, r;
  33. char buf[30];
  34. bit PinA_O= 1;
  35. bit PinB_O= 1;
  36. bit EnterOns= 1;
  37. unsigned int ScanCount = 0;

  38. void main(void) {
  39.     s16 Now = 5;
  40.     s16 Now_O = 0;
  41.     PinA = 1;
  42.     Enter = 1;
  43.     PinB = 1;
  44.     UART_INIT();
  45.     Delayms(1000);
  46.     while (1)
  47.     {   //user's function
  48.         if(ScanCount++ > 50) {
  49.             ScanCount = 0;
  50.             if(!PinA && PinA_O && PinB) {
  51.                 Now++;
  52.             }PinA_O = PinA;               
  53.             if(!PinB && PinB_O && PinA) {
  54.                 Now--;
  55.             }PinB_O = PinB;                        
  56.             Now>9? Now = 0:_nop_();
  57.             Now<0? Now = 9:_nop_();
  58.             if(!Enter && EnterOns) {
  59.                 //EnterOns = 1;
  60.                 BuffIndex++;
  61.                 sprintf (buf, "PW%u = %d\r\n",BuffIndex & 0xFF, Now);
  62.                 SendString(buf);
  63.                 PW = PW *10 + Now;
  64.                 if(BuffIndex == 6) {
  65.                     sprintf (buf, "PW input = %Ld\r\nPW is ",PW);
  66.                     SendString(buf);
  67.                     PW == 12398?SendString("Correct!\r\n"):SendString("Wrong!\r\n");
  68.                     PW = 0;
  69.                     BuffIndex = 0;
  70.                 }
  71.                 Now = 5;
  72.             }
  73.             EnterOns = Enter;
  74.         }
  75.         if(Now != Now_O)
  76.         {
  77.             sprintf (buf, "Now = %d\r\n", Now);
  78.             SendString(buf);
  79.         }
  80.         Now_O = Now;

  81.     }
  82. }
  83. void Delayms(u16 i)                //@ 11.0592MHz
  84. {
  85.     u8 j, k;
  86.     do
  87.     {
  88.                         j = 11;
  89.                         k = 190;
  90.                         do
  91.                         {
  92.                                 while (--k);
  93.                         } while (--j);
  94.     } while (--i);
  95. }
  96. //-----------------------------------------
  97. //Timer interrupt routine for UART

  98. void tm0() interrupt 1 using 1
  99. {
  100.     if (--TCNT == 0)
  101.     {
  102.         TCNT = 3;                       //reset send baudrate counter
  103.         if (TING)                       //judge whether sending
  104.         {
  105.             if (TBIT == 0)
  106.             {
  107.                 TXB = 0;                //send start bit
  108.                 TDAT = TBUF;            //load data from TBUF to TDAT
  109.                 TBIT = 9;               //initial send bit number (8 data bits + 1 stop bit)
  110.             }
  111.             else
  112.             {
  113.                 TDAT >>= 1;             //shift data to CY
  114.                 if (--TBIT == 0)
  115.                 {
  116.                     TXB = 1;
  117.                     TING = 0;           //stop send
  118.                     TEND = 1;           //set send completed flag
  119.                 }
  120.                 else
  121.                 {
  122.                     TXB = CY;           //write CY to TX port
  123.                 }
  124.             }
  125.         }
  126.     }
  127. }

  128. //-----------------------------------------
  129. //initial UART module variable

  130. void UART_INIT()
  131. {
  132.     TMOD = 0x00;                        //timer0 in 16-bit auto reload mode
  133.     AUXR = 0x80;                        //timer0 working at 1T mode
  134.     TL0 = BAUD;
  135.     TH0 = BAUD>>8;                      //initial timer0 and set reload value
  136.     TR0 = 1;                            //tiemr0 start running
  137.     ET0 = 1;                            //enable timer0 interrupt
  138.     PT0 = 1;                            //improve timer0 interrupt priority
  139.     EA = 1;                             //open global interrupt switch
  140.     TING = 0;
  141.     RING = 0;
  142.     TEND = 1;
  143.     REND = 0;
  144.     TCNT = 0;
  145.     RCNT = 0;
  146. }
  147. void SendData(BYTE dat)
  148. {

  149.     TEND = 0;
  150.     TBUF = dat;
  151.     TING = 1;
  152. }

  153. /*----------------------------
  154. 發送字符串
  155. ----------------------------*/
  156. void SendString(char *s)
  157. {
  158.     while (*s)                  //檢測字符串結束標志
  159.     {   if (TEND)
  160.         {
  161.             SendData(*s++);         //發送當前字符
  162.         }
  163.     }
  164. }
復制代碼





歡迎光臨 ELEOK (http://m.afoofa.cn/) Powered by Discuz! X5.0