一定位一脉冲的EC11旋转编码器最简洁的单片机驱动代码

[复制链接]
查看5 | 回复0 | 2021-7-6 17:10:30 | 显示全部楼层 |阅读模式
  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進行加減操作

为什么这样写呢?
上时序图
顺时针转:
183024pg6gp8tozykosyz2.png

逆时针转:
183023fnznnonnsqo79mxo.png

我们看到,当顺时针转时
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. }
复制代码
回复

使用道具 举报

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

本版积分规则