以下為關(guān)鍵代碼解釋
int
main(void)
{
SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480), 50000000);
GPIOIntInitial();
GPIOInitial();
IntMasterEnable();
while(1)
{
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)//PN4 IR_RECEIVER
{
SysCtlDelay(2*50000000/3000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
IntEnable(INT_GPION);
}
}
}
初始化系統(tǒng)時(shí)鐘,初始化相應(yīng)的GPIO口和中斷兔朦。
如果有低電平(PN4為0偷线,PN4即IR_RECEIVER),按鍵消抖沽甥,延時(shí)再判斷声邦。使能中斷GPION,即進(jìn)入GPION()中斷服務(wù)程序摆舟。
中斷服務(wù)程序
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
LowTime = 1;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
}
}
else
LowTime = 0;
SysCtlDelay(3*50000000/3000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
HighTime = 1;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
if(count>0x200000)
{
count=0;
//return 0;
}
}
}
else
HighTime = 0;
先判斷PN4為低電平亥曹,LowTime置1;再判斷PN4為高電平恨诱,HighTime置1媳瞪。這需要了解到紅外傳感器的原理,書中寫到:
開始時(shí)會(huì)發(fā)射一個(gè)同步碼頭照宝,對(duì)于接收端就是一個(gè)9ms的低電平蛇受,和一個(gè)4.5ms的高電平,這個(gè)同步碼頭告訴程序從這以后開始接受數(shù)據(jù)厕鹃。
if((HighTime==1)&&(LowTime==1))
{
if(getdata()==1)
{
IrOutput();
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x02);//PF1,LED0
SysCtlDelay(500*(50000000/3000));//2
// for(i=0;i<1000;i++){;}
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x00);
SysCtlDelay(500*(50000000/3000));//2
}
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x02);
SysCtlDelay(500*(50000000/3000));
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 , 0x00);
SysCtlDelay(500*(50000000/3000));
}
如果HighTime和LowTime都為1兢仰,也就是接收到同步碼頭
那么開始解碼即執(zhí)行g(shù)etdata()函數(shù),
如果熊响,解碼正確返回1,才執(zhí)行IrOutput()輸出相應(yīng)的操作
否則诗赌,解碼不正確汗茄,顯示錯(cuò)誤信息,通過GPIOPinWrite()函數(shù)铭若,置PF1=1然后置0洪碳,也就是對(duì)應(yīng)的LED0燈亮一會(huì)
如果HighTime和LowTime不都為1,未接受到同步碼頭叼屠,也顯示錯(cuò)誤信息瞳腌,LED0亮一會(huì)
紅外解碼bool getdata()
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
temp = temp>>1;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x00)
{
}
SysCtlDelay(7*50000000/30000);
if((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
temp = temp|0x80;
while((GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_4)&0x10)==0x10)
{
count++;
if(count>0x200000)
{
count=0;
return 0;
}
}
}
else
{
temp = temp&0x7f;
}
}
IrData[i] = temp;
}
外層for循環(huán)4次,給IrData賦值镜雨。需要了解紅外傳感器原理嫂侍,書中寫著:
發(fā)射器按鍵按下后,將發(fā)射一組108ms的編碼脈沖荚坞。遙控編碼脈沖由前導(dǎo)碼(同步碼頭)挑宠,16位地址碼(8位地址碼,8位地址碼的反碼)颓影,16位操作碼(8位操作碼各淀,8位操作碼的反碼)組成。
也就是IrData數(shù)組中四個(gè)數(shù)據(jù)是诡挂,地址碼碎浇,地址碼反碼临谱,操作碼,操作碼反碼奴璃;而前導(dǎo)碼已經(jīng)前面識(shí)別過了悉默,使LowTimeHighTime為1。
內(nèi)層for循環(huán)8次溺健,
如果PN4==1高電平麦牺,那么temp = temp|0x80把第一位置1其他位不變
否則PN4==0低電平,那么temp = temp&0x7f把第一位置0其他為不變
通過這種按位與按位或的操作賦值給temp鞭缭,然后temp = temp>>1每次在開始temp右移一位剖膳,總共八次對(duì)temp八位賦值。
IrAddressData = IrData[0]+IrData[1];//address and anti-address
IrValueData = IrData[2]+IrData[3];//cao zuo ma
if((IrAddressData==0xff)&&(IrValueData==0xff))//if is signal ,do it
return 1;
else
return 0;
最后是對(duì)接收到數(shù)據(jù)的校驗(yàn)岭辣,IrData[0]+IrData[1]及 IrData[2]+IrData[3]相加吱晒,也就是對(duì)應(yīng)原碼反碼相加,結(jié)果應(yīng)該是0xff沦童,如果不是自然return 0報(bào)錯(cuò)仑濒。
IrOutput()解碼正確執(zhí)行相應(yīng)的操作
void IrOutput()
{
switch(IrData[2])
{
case 12 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x02);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x01);
GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_5 , 0x20);
SysCtlDelay(500*(50000000/3000));
GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_5 , 0x00);
break;
case 24 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x01);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x00);break;
case 94 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x03);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x00);break;
case 8 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x00);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x10);break;
case 28 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x02);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x10);break;
case 90 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x01);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x10);break;
case 66 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x03);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x10);break;
case 82 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x00);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x01);break;
case 74 : GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x02);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x01);break;
default: GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1|GPIO_PIN_0 , 0x03);
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0 , 0x11);
}
}
其中,代碼中注釋著:
//紅外解碼輸出偷遗,數(shù)字0-9對(duì)應(yīng)的關(guān)系如下墩瞳,地址碼為0x00
/*address 0x00
- 0->22
- 1->12
- 2->24
- 3->94
- 4->8
- 5->28
- 6->90
- 7->66
- 8->82
- 9->74
再結(jié)合單片機(jī)的調(diào)試結(jié)果,我反向推導(dǎo)出各個(gè)Pin控制的外設(shè)PN0(D2),PN1(D1),PF0(D4+LCD),PF4(D3)
舉個(gè)例子氏豌,case 12 對(duì)應(yīng)數(shù)字1喉酌,也就是遙控器按1,然后對(duì)應(yīng)操作
PN1=1泵喘,PN0=0泪电,PF4=0,PF0=1纪铺;即D1和D3燈會(huì)亮(是兩個(gè)綠燈相速,不是之前流水燈實(shí)驗(yàn)用到的LED)等等。case12下面另外是我自己加的代碼鲜锚,就是PM5=1一會(huì)突诬,讓蜂鳴器叫一聲。也就是case 后面的代碼可以自己設(shè)計(jì)芜繁,但是別忘了相應(yīng)的GPIO等初始化攒霹。