国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee
ELEOK
標題:
一定位一脈沖的EC11旋轉編碼器最簡潔的單片機驅動代碼
[打印本頁]
作者:
eng
時間:
2021-7-6 17:10
標題:
一定位一脈沖的EC11旋轉編碼器最簡潔的單片機驅動代碼
if(!PinA && PinA_O && PinB) {
Now++;
}PinA_O = PinA;
if(!PinB && PinB_O && PinA) {
Now--;
}PinB_O = PinB;
復制代碼
只有六行代碼就能用EC11對Now進行加減操作
為什么這樣寫呢?
上時序圖
順時針轉:
183024pg6gp8tozykosyz2.png
(6.8 KB)
下載附件
2021-7-6 17:10 上傳
逆時針轉:
183023fnznnonnsqo79mxo.png
(6.8 KB)
下載附件
2021-7-6 17:10 上傳
我們看到,當順時針轉時
Pin A會早于Pin B 轉低電平,反之亦然
代碼解讀:
!PinA && PinA_O && PinB//當Pin A 為低電平而之前為高電平(即下降沿)并且Pin B為高電平
這一句就捕捉到順時針轉時序圖中箭指著的那一剎那的情況
于是Now加1
!PinB && PinB_O && PinA//當Pin B 為低電平而之前為高電平(即下降沿)并且Pin A為高電平
這一句就捕捉到逆時針轉時序圖中箭指著的那一剎那的情況
于是Now減1
如果編碼器不加電容消抖
就用軟件消抖
if(ScanCount++ > 50) { //其數值按單片機速度加減
ScanCount = 0;
if(PinA && !PinA_O && PinB) {
Now++;
}PinA_O = PinA;
if(PinB && !PinB_O && PinA) {
Now--;
}PinB_O = PinB;
Now>9? Now = 0:_nop_();
Now<0? Now = 9:_nop_();
}
復制代碼
現附上小應用實例一則
基如STC15F104E的EC11軟串口六位密碼檢查程序
如發現順逆時針相反,對調PinA/PinB 定義腳即可
#include <STC15F104E.H>
#include "intrins.h"
#include <stdio.h>
#include <string.h>
#define BAUD 0xFF40 //19200bps @ 11.0592MHz
typedef bit BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef signed char s8; //–128 to 127
typedef unsigned char u8; //0 to 255
typedef signed int s16; //-32768 — 32767
typedef unsigned int u16; //0 — 65535
typedef signed long s32; //-2147483648 — 2147483647
typedef unsigned long u32; //0 — 4294967295
sbit RXB = P3^0; //define UART TX/RX port
sbit TXB = P3^1;
sbit PinA = P3^3;
sbit PinB = P3^4;
sbit Enter = P3^2;
BYTE TBUF,RBUF;
BYTE TDAT,RDAT;
BYTE TCNT,RCNT;
BYTE TBIT,RBIT;
BOOL TING,RING;
BOOL TEND,REND;
void UART_INIT();
void SendString(char *s);
void SendData(BYTE dat);
void Delayms(u16 i);
u32 PW = 0;
u16 BuffIndex;
BYTE t, r;
char buf[30];
bit PinA_O= 1;
bit PinB_O= 1;
bit EnterOns= 1;
unsigned int ScanCount = 0;
void main(void) {
s16 Now = 5;
s16 Now_O = 0;
PinA = 1;
Enter = 1;
PinB = 1;
UART_INIT();
Delayms(1000);
while (1)
{ //user's function
if(ScanCount++ > 50) {
ScanCount = 0;
if(!PinA && PinA_O && PinB) {
Now++;
}PinA_O = PinA;
if(!PinB && PinB_O && PinA) {
Now--;
}PinB_O = PinB;
Now>9? Now = 0:_nop_();
Now<0? Now = 9:_nop_();
if(!Enter && EnterOns) {
//EnterOns = 1;
BuffIndex++;
sprintf (buf, "PW%u = %d\r\n",BuffIndex & 0xFF, Now);
SendString(buf);
PW = PW *10 + Now;
if(BuffIndex == 6) {
sprintf (buf, "PW input = %Ld\r\nPW is ",PW);
SendString(buf);
PW == 12398?SendString("Correct!\r\n"):SendString("Wrong!\r\n");
PW = 0;
BuffIndex = 0;
}
Now = 5;
}
EnterOns = Enter;
}
if(Now != Now_O)
{
sprintf (buf, "Now = %d\r\n", Now);
SendString(buf);
}
Now_O = Now;
}
}
void Delayms(u16 i) //@ 11.0592MHz
{
u8 j, k;
do
{
j = 11;
k = 190;
do
{
while (--k);
} while (--j);
} while (--i);
}
//-----------------------------------------
//Timer interrupt routine for UART
void tm0() interrupt 1 using 1
{
if (--TCNT == 0)
{
TCNT = 3; //reset send baudrate counter
if (TING) //judge whether sending
{
if (TBIT == 0)
{
TXB = 0; //send start bit
TDAT = TBUF; //load data from TBUF to TDAT
TBIT = 9; //initial send bit number (8 data bits + 1 stop bit)
}
else
{
TDAT >>= 1; //shift data to CY
if (--TBIT == 0)
{
TXB = 1;
TING = 0; //stop send
TEND = 1; //set send completed flag
}
else
{
TXB = CY; //write CY to TX port
}
}
}
}
}
//-----------------------------------------
//initial UART module variable
void UART_INIT()
{
TMOD = 0x00; //timer0 in 16-bit auto reload mode
AUXR = 0x80; //timer0 working at 1T mode
TL0 = BAUD;
TH0 = BAUD>>8; //initial timer0 and set reload value
TR0 = 1; //tiemr0 start running
ET0 = 1; //enable timer0 interrupt
PT0 = 1; //improve timer0 interrupt priority
EA = 1; //open global interrupt switch
TING = 0;
RING = 0;
TEND = 1;
REND = 0;
TCNT = 0;
RCNT = 0;
}
void SendData(BYTE dat)
{
TEND = 0;
TBUF = dat;
TING = 1;
}
/*----------------------------
發送字符串
----------------------------*/
void SendString(char *s)
{
while (*s) //檢測字符串結束標志
{ if (TEND)
{
SendData(*s++); //發送當前字符
}
}
}
復制代碼
歡迎光臨 ELEOK (http://m.afoofa.cn/)
Powered by Discuz! X5.0