?? irrexample.c
字號(hào):
/////////////////////////////
以下程序是用掃描方法讀取紅外遙控器波形
若有條件(如使用AVR),可以使用捕獲脈寬中斷,更容易編程
//////////////////////////
//T1計(jì)數(shù)值,區(qū)分紅外傳輸?shù)奈恢?1個(gè)計(jì)數(shù)=2us(Fosc=4MHz)
#define IRR_DECODE_DELAY 120 //解碼延時(shí)限制,單位ms
#define IRR_H_DELAY 8 //高電平延時(shí)限制,單位ms
#define IRR_L_DELAY 5 //低電平延時(shí)限制,單位ms
#define IRR_HEAD_MINTIME 1950 //2250-300 //4500us, 300us為估計(jì)2次掃描之間最大延時(shí)
#define IRR_HEAD_MAXTIME 2550 //2250+300
#define IRR_0_MAXTIME 430 //280+150 //560us
#define IRR_0_MINTIME 130 //280-150
#define IRR_1_MAXTIME 1000 //850+150 //1700us
#define IRR_1_MINTIME 700 //850-150
/*********讀取紅外接收值IRR********/
//PA7
//TL1838B一體化紅外接收管:無(wú)接收,輸出H,接收到38kHz載波輸出L. 2套信號(hào)之間要求隔開25ms以上
//輸出:非零表示H,0表示L
unsigned char read_IRR(void)
{
return PINA&0x80; //PA7
}
/***********掃描紅外遙控器按鍵輸入IRR:PC2 解碼子程序***************
1)遙控器以u(píng)pd6121G或HT6221為主控芯片遙控器
2)發(fā)出的信號(hào)電平變化最小間隔為0.56ms.必須保證在0.56ms內(nèi)程序能夠至少掃描1次!
3)位定義:測(cè)量接收波形中高電平的脈寬:4.5ms為引導(dǎo)碼(起始),0: 0.56ms,1: 1.7ms
4)一次鍵碼共4Byte 32位:地址碼+地址碼反碼+鍵碼+鍵碼反碼; LSB(D0)先出
5)掃描的結(jié)果會(huì)把鍵值放在IRRkey
******注意2次掃描之間間隔應(yīng)該遠(yuǎn)小于0.56ms!!!
*/
void scan_IRR_decode(void)
{unsigned char i;
unsigned int tempt;
//不斷讀取1路IRR,獲取波形信息
newIRR=read_IRR();
if((!oldIRR)&&(newIRR)) //上升沿
{delay_IRR_L=0; //關(guān)閉低電平延時(shí)計(jì)時(shí)
delay_IRR_H=1; //開始高電平延時(shí)計(jì)時(shí)
//oldTCNT1=TIM16_ReadTCNT1(); //開始對(duì)高電平計(jì)時(shí)
TIM16_WriteTCNT1(0); //清零TIMER1,開始對(duì)高電平計(jì)時(shí)(可以節(jié)省運(yùn)算減法的時(shí)間)
}
else if((oldIRR)&&(!newIRR)) //下降沿
{delay_IRR_L=1; //開始低電平延時(shí)計(jì)時(shí)
delay_IRR_H=0; //關(guān)閉高電平延時(shí)計(jì)時(shí)
//計(jì)算此段低電平時(shí)間差
/*tempt=TIM16_ReadTCNT1();
if (tempt>oldTCNT1) IRRtime=tempt-oldTCNT1;
else IRRtime=0xffff-oldTCNT1+tempt+1;*/
IRRtime=TIM16_ReadTCNT1();
//判斷收到的位信息
if ((IRRtime>IRR_HEAD_MINTIME)||(IRRtime<IRR_0_MINTIME))
{//IRRbyte=0; //收到長(zhǎng)高電平(引導(dǎo)碼,4.5ms)或是干擾,復(fù)位
IRRbit_prt=0; //位指針清零
}
else //有效數(shù)據(jù)位
{
if (IRRtime<IRR_0_MAXTIME) IRRbit[IRRbit_prt]=0; //收到0
else if (IRRtime>IRR_1_MINTIME) IRRbit[IRRbit_prt]=0xff; //收到1
else IRRbit[IRRbit_prt]=2; //錯(cuò)碼
IRRbit_prt++;
if (IRRbit_prt==32) //已收滿32位,取鍵值
{IRRkey=judge_IRRkey();
//IRRbit_prt=0;
}
}
}
oldIRR=newIRR;
}
//已收滿32位,判斷鍵值
//無(wú)效鍵值:NOKEY=0xff
unsigned char judge_IRRkey(void)
{ unsigned char i,j;
//先判斷反碼
j=0;
for(i=0;i<8;i++)
{if (IRRbit[i+8]!=(~IRRbit[i]))
{j=1;
break;
}
if (IRRbit[i+24]!=(~IRRbit[i+16]))
{j=1;
break;
}
}
if(j) return NOKEY; //解碼錯(cuò)誤
//判斷地址碼是否正確
j=0;
for(i=0;i<8;i++)
{if(IRRbit[i]) j|=(1<<i); //低位先收
}
if (j!=IRR_CUSTOMCODE) return NOKEY; //地址碼錯(cuò)誤
//返回鍵值
j=0;
for(i=16;i<24;i++)
{if(IRRbit[i]) j|=(1<<(i-16));
}
return j;
}
//掃描紅外遙控器按鍵輸入
//先掃描紅外遙控器按鍵輸入引導(dǎo)區(qū): 低電平持續(xù)9ms
//只有探測(cè)到下降沿,且低電平>IRR_L_DELAY(5ms),即可能出現(xiàn)引導(dǎo)碼,才進(jìn)入掃描鍵盤子程序
void scan_IRRkey(void)
{
IRRkey=NOKEY; //上次掃描獲得的鍵值不保留,需馬上利用
//不斷讀取1路IRR,獲取波形信息
newIRR=read_IRR();
if((oldIRR)&&(!newIRR)) //下降沿
{delay_IRR_L=1; //開始低電平延時(shí)計(jì)時(shí)
}
else if(newIRR) delay_IRR_L=0; //關(guān)閉低電平延時(shí)計(jì)時(shí)
if (delay_IRR_L>IRR_L_DELAY) //可能進(jìn)入引導(dǎo)區(qū),開始連續(xù)掃描鍵盤
{delay_IRR_L=1; //開始低電平延時(shí)計(jì)時(shí)
delay_IRR_H=1; //開始高電平延時(shí)計(jì)時(shí)
delay_IRR_decode=1; //開始解碼延時(shí)計(jì)時(shí)
IRRbit_prt=0;
//開始解碼
//若低電平或高電平持續(xù)時(shí)間過(guò)長(zhǎng),或者解碼時(shí)間超出108ms,退出解碼程序
while((delay_IRR_L<=(IRR_L_DELAY*3))&&(delay_IRR_H<=IRR_H_DELAY)&&(delay_IRR_decode<=IRR_DECODE_DELAY)&&(IRRbit_prt<32))
{scan_IRR_decode(); //解碼后才獲得鍵值IRRkey
}
delay_IRR_L=0; //關(guān)閉低電平延時(shí)計(jì)時(shí)
delay_IRR_H=0; //關(guān)閉高電平延時(shí)計(jì)時(shí)
delay_IRR_decode=0; //關(guān)閉解碼延時(shí)計(jì)時(shí)
}
oldIRR=newIRR;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -