國培期間時間相對而言比較充裕,于是就想寫點程序。來的時候帶了一個旋轉編碼開關,今天晚上寫了個程序測試了一下,通過了,程序能夠識別編碼開關的旋轉方向和旋轉次數,并且在數碼管上顯示出來。支持負數顯示。以下為源程序,程序在一職校開發板上運行成功,芯片為STC89C51RC。
#include < reg52.h> //頭文件
sbit anotherbit = P1^2; //旋轉編碼器另一腳
sbit rotation=P1^0; //旋轉編碼器中一腳
bit oldbit; //上一狀態暫存位
unsigned char led1,led2,led3,led4,ztj;//LED顯示緩存,掃描狀態機
int xuanzhuanzhi,ctemp;//旋轉值
unsigned char code ledseg[17]={0x88,0xBE,0xC4,0x94,0xB2,0x91,0x81,0xBC,0x80,
0x90,0xA0,0x83,0xC9,0x86,0xC1,0xE1,0xf7};
void init(void)
{
TMOD=0x11; //方式1
TR0=1; //啟動T0開始掃描數碼管
ET0=1; //打開中斷
EA=1;
}
void ledscan(void) //數碼管掃描程序
{
switch(ztj) //切換狀態機
{
case 0: //分支
P2=0xff; //關閉數碼管
P0=ledseg[led4];//查表得段碼數據
P2=0x7f; //打開數碼管
ztj=1; //轉移狀態
break; //分支結束
case 1:
P2=0xff;
P0=ledseg[led3];
P2=0xbf;
ztj=2;
break;
case 2:
P2=0xff;
P0=ledseg[led2];
P2=0xdf;
ztj=3;
break;
case 3:
P2=0xff;
P0=ledseg[led1];
P2=0xef;
ztj=0;
break;
default: //沒有找到分支
ztj=0; //狀態機復位
break; //分支結束
}
}
void timer0 (void) interrupt 1 using 1 //T0定時器中斷程序,定時時間到,自動運行此程序
{
TH0=(65536-5000)/256; //置定時值,每次時間到都要重新置定時值
TL0=(65536-5000)%256; //每5000us產生一次定時器定時中斷(12MHz)
ledscan(); //每5000us掃描一次LED(12MHz)
}
void main(void)
{
init(); //是初始化,打開中斷及定時器
while(1)
{
ctemp=xuanzhuanzhi; //復制計數值
if(ctemp<0) //判斷符號
{
ctemp=-ctemp; //如果為負數,取反
led4=16; //顯示負號
led3=ctemp%1000/100; //提取各位數值
led2=ctemp%100/10; //提取各位數值
led1=ctemp%10; //提取各位數值
}
else
{
led4=ctemp/1000; //提取各位數值
led3=ctemp%1000/100; //提取各位數值
led2=ctemp%100/10; //提取各位數值
led1=ctemp%10; //提取各位數值
}
if(oldbit==1&&rotation==0) //判斷前后狀態以識別是否發生下降沿
{
if(anotherbit) //判斷另一相電平
{
xuanzhuanzhi++; //為高,正轉
}
else
{
xuanzhuanzhi--; //為低,反轉
}
}
oldbit=rotation; //刷新位暫存值
}
}
