編碼器涵蓋很多種類,不知你具體要求的哪種?我也曾折騰過一段時間EC11型的,給你個從網上找來的,參考吧(在我板上能運行)
//通過編碼開關(旋轉編碼器)控制數碼管的加減一
#include<AT89X52.H>
#define uchar unsigned char
#define uint unsigned int
#define cycle 1 //定義動作周期,編碼器旋轉多少格有效
#define NULL 0 //定義編碼器不動作時的還回值
#define E_RIGHT 0x0e //定義右旋轉還回值
#define E_LEFT 0x0f //定義左旋轉還回值
/*=====數碼管位及按鍵定義=====*/
sbit dula=P2^0; //數碼管段選,鎖存器控制信號
sbit wela=P2^1; //數碼管位選,鎖存器控制信號
sbit PINA = P1^0; //定義IO
sbit PINB = P1^1;
uchar WheelNow,WheelOld,RightCount,LeftCount;
/*=====0-9=====A-G=====*/
uchar a[16]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x00};
//數碼管顯示編碼
unsigned sled_bit_table[]={0x5f,0x6f,0x77,0x7b,0x7d,0x7e,0xff};
/*定義點亮的數碼管與數組的關系*/
/*=====四個數碼管顯示數據存放處=====*/
uchar one,two,three,four;
uint wc=0;
/*=====函數定義=====*/
void delay(uint x);
void display(void);
//void key();
void led_analyze(uint i);
/*====延時函數=====*/
void delay(uint x)
{
uint i;
for(i=0;i<x;i++);
}
/*====顯示函數=====*/
void display(void)
{
//送段碼
dula=0;
P0 =a[one];
dula=1;
dula=0;
//數碼管位選
wela=0;
P0=sled_bit_table[0]; //開顯示
wela=1;
wela=0;
delay(200); //調用鍵盤掃描
wela=0;
P0=sled_bit_table[6];
wela=1;
wela=0; //關顯示
dula=0;
P0=a[two];
dula=1;
dula=0;
//數碼管位選
wela=0;
P0=sled_bit_table[1]; //開顯示
wela=1;
wela=0;
delay(200); //調用鍵盤掃描
wela=0;
P0=sled_bit_table[6];
wela=1;
wela=0; //關顯示
dula=0;
P0=a[three];
dula=1;
dula=0;
//數碼管位選
wela=0;
P0=sled_bit_table[2]; //開顯示
wela=1;
wela=0;
delay(200); //調用鍵盤掃描
wela=0;
P0=sled_bit_table[6];
wela=1;
wela=0; //關顯示
dula=0;
P0=a[four];
dula=1;
dula=0;
//數碼管位選
wela=0;
P0=sled_bit_table[3]; //開顯示
wela=1;
wela=0;
delay(200); //調用鍵盤掃描
wela=0;
P0=sled_bit_table[6];
wela=1;
wela=0; //關顯示
}
/*====分解顯示數據=====*/
void led_analyze(uint i)
{
i=i%10000;
four=i/1000; // 千位
three=(i/100)%10; // 百位
two=(i%100)/10; // 十位
one=(i%100)%10; // 個位
}
//=================================================
uchar WheelRight()
{
LeftCount=0;
RightCount++;
if (RightCount>=cycle)
{
RightCount=0;
return(E_RIGHT);
}
else
return(NULL);
}
//=====================================================
uchar WheelLeft()
{
RightCount=0;
LeftCount++;
if (LeftCount>=cycle)
{
LeftCount=0;
return(E_LEFT);
}
else
return(NULL);
}
//=================================================================
uchar EncoderProcess()
{
uchar keytmp;
PINA = 1;
PINB = 1;
WheelNow=WheelNow<<1;
if (PINA==1) WheelNow=WheelNow+1; // 讀 PINA
WheelNow=WheelNow<<1;
if (PINB==1) WheelNow=WheelNow+1; // 讀 PINB
WheelNow=WheelNow & 0x03; // 將 WheelNow 的 2 - 7 位清零,保留 0 - 1 兩個位的狀態.
if (WheelNow==0x00) return(NULL); //當 PINA 和 PINB 都為低電平時退出,低電平區不做處理
keytmp=WheelNow;
keytmp ^=WheelOld; // 判斷新讀的數據同舊數據
if (keytmp==0) return(NULL); // 新讀的數據同舊數據一樣時退出.
if (WheelOld==0x01 && WheelNow==0x02)
{ // 是左旋轉否
WheelOld=WheelNow;
return(WheelLeft()); //左旋轉
}
else
if (WheelOld==0x02 && WheelNow==0x01)
{ // 是右旋轉否
WheelOld=WheelNow;
return(WheelRight()); //右旋轉
}
WheelOld=WheelNow; // 保存當前值
return(NULL); // 當 PINA 和 PINB 都為高電平時表示編碼器沒有動作,退出
}
//==========================================================================
void inc()
{
wc++;
if(wc>9999) wc=0;//如果WG大于9999則將它清零
led_analyze(wc);
} // 在此處設置斷點看 num 加的變化
//====================================================================
void dec()
{
wc--;
if(wc>9999) wc=9999;
led_analyze(wc);
} // 在此處設置斷點看 num 減的變化
//===========================================================================
void main()
{
while (1)
{
switch(EncoderProcess())
{
case E_RIGHT: inc(); break;
case E_LEFT: dec(); break;
}
display();
}
}
|