irpro_ok=0;//處理完成標(biāo)志清零
}
void ircordpro(void)//紅外碼值處理函數(shù)
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;//從1開始,是引導(dǎo)碼以后的一幀所有數(shù)據(jù)
for(i=0;i<4;i++)//處理4個字節(jié)
{
for(j=0;j<8;j++) //處理1個字節(jié)8位
{
cord=irdata[k];
if(cord>7)//電平寬度大于某個值,可以判斷為1(2.25ms) 時間范圍要大點(diǎn),否則重復(fù)按鍵出現(xiàn)混亂
{
value|=0x80;//若為1則賦值
}
//其余情況可以判斷為0(是不是證明了,irdata接收的是引導(dǎo)碼之后的一幀所有電平?)
else
{
value=value;//若判斷為0則不變(移位后自然為0)
}
if(j<7)
{
value>>=1;//為什么|0X01 與<<1配合,不行。因為最后完成值要求最先寫入的最低位,用這個想法會反過來。
}
k++;
}
ircord[i]=value;
value=0;
} irpro_ok=1;//處理完畢標(biāo)志位置1
}
/////////////////////////////////////////////////////////////////
void main(void)
{
EX0init(); // 初始化中斷
TIM0init();//初始化定時器0
while(1)//主循環(huán)
{
if(irok)
{
ircordpro();//碼值處理
irok=0;
}
if(irpro_ok)//step press key
{
ir_work();//碼值識別散轉(zhuǎn)
}
}
}
程序基礎(chǔ)來自已有程序,在看完下面的說明后,就可以移植了,畢竟同一個解碼標(biāo)準(zhǔn),都是大同小異,甚至就算不同解碼標(biāo)準(zhǔn)也僅僅是判斷編碼的時間要求上長短不同。但為什么這是經(jīng)過我自己消化的呢,這里有個非常有趣的問題。
在我單獨(dú)實驗紅外模塊的時候(也就是上面的源程序),能夠正常運(yùn)行。但是移植入開啟了T2中斷的大程序里之后,紅外部分一點(diǎn)反應(yīng)也沒有。在接下來的調(diào)試過程中,因為不會使用DEBUG進(jìn)入外部中斷,在不斷地比對程序中浪費(fèi)了許多時間。當(dāng)我使用LED調(diào)試法時(把P1=0x55;插入任意想要檢驗的程序行,亮了就證明程序走到了這里),亮與不亮在這里分界了(紅色標(biāo)記):
void ex0_isr (void) interrupt 0 using 0//外部中斷0服務(wù)函數(shù)
{
unsigned char i;
bit startflag;
if(startflag)
{
TR0=0;
if(irtime<38&&irtime>=34)
i=0;
TR0=1;
irdata[i]=irtime;
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
恰好最近有重溫static定義變量的特點(diǎn),不然可能死得不明不白。因為抱著單獨(dú)運(yùn)行正常,移植整合之后也正常的想法,源程序的static unsigned char i;被我改為了uchar i;(我在自己程序里已做#define uchar unsigned char)。
答案清楚了:因為我不允許任何配角程序打擾T2時鐘工作,所以設(shè)置了最高優(yōu)先級(PT2=1;),這樣每次外部中斷0里面局部變量i的累加會被打斷,如果不能保值,就每次都被撤銷和重新構(gòu)建,或許永遠(yuǎn)達(dá)不到(i==33)要求。static按我的理解,最大的作用就是能夠保持上一次的值,至于其他作用印象就不大深刻了。
哈哈,有意思,記住 中斷里的局部變量定義 unsigned char i;要改為static unsigned char i;
評論