紅外接收頭的型號有很多 HS0038 VS838等 功能大致相同 只是引腳封裝不同
HS0038 封裝: VS838封裝:
紅外接收有幾種統(tǒng)一的編碼方式,采用哪種編碼方式取決于遙控器使用的芯片,接收頭接收到的都是一樣的。
電視遙控器使用的是專用集成發(fā)射芯片來實現(xiàn)遙控碼的發(fā)射,如東芝TC9012,飛利浦AA3010T 等,通常彩電遙控信號的發(fā)射,就是將某個按鍵所對應(yīng)的控制指令和系統(tǒng)碼(由0 和1 組成的序列),調(diào)制在38KHz 的載波上,然后經(jīng)放大、驅(qū)動紅外發(fā)射管將信號發(fā)射出去。不同公司的遙控芯片,采用的遙控碼格式也不一樣。較普遍的有兩種,一種是NEC 標(biāo)準(zhǔn),一種是PHILIPS 標(biāo)準(zhǔn)。
NEC 標(biāo)準(zhǔn):
遙控載波的頻率為38KHz(占空比為1:3);當(dāng)某個按鍵按下時,系統(tǒng)首先發(fā)射一個完整的全碼,如果鍵按下超過108ms 仍未松開,接下來發(fā)射的代碼(連發(fā)代碼)將僅由起始碼(9ms)和結(jié)束碼(2.5ms)組成。
一個完整的全碼=引導(dǎo)碼+用戶碼+用戶碼+數(shù)據(jù)碼+數(shù)據(jù)反碼。
其中,引導(dǎo)碼高電平9ms,低電平4.5ms;系統(tǒng)碼8 位,數(shù)據(jù)碼8 位,共32 位;其中前 16 位為用戶識別碼,能區(qū)別不同的紅外遙控設(shè)備,防止不同機種遙控碼互相干擾。后 16 位為 8 位的操作碼和 8 位的操作反碼,用于核對數(shù)據(jù)是否接收準(zhǔn)確。收端根據(jù)數(shù)據(jù)碼做出應(yīng)該執(zhí)行什么動作的判斷。連發(fā)代碼是在持續(xù)按鍵時發(fā)送的碼。它告知接收端,某鍵是在被連續(xù)地按著。
NEC 標(biāo)準(zhǔn)下的發(fā)射碼表示
發(fā)射數(shù)據(jù)時0 用“0.56ms 高電平+0.565ms 低電平=1.125ms”表示;
數(shù)據(jù)1 用“高電平0.56ms+低電平1.69ms=2.25ms”表示。
遙控器發(fā)射的信號:
一體化接收頭接收到的信號:
需要注意的是:當(dāng)一體化接收頭收到38kHz 紅外信號時,輸出端輸出低電平,否則為高電平。所以一體化接收頭輸了的波形是與發(fā)射波形是反向的
PHILIPS 標(biāo)準(zhǔn):
載波頻率為38KHz;沒有簡碼,點按鍵時,控制碼在1 和0 之間切換,若持續(xù)按鍵,則控制碼不變。
一個全碼=起始碼‘11’+控制碼+用戶碼+用戶碼
數(shù)據(jù)0 用“低電平1.778ms+高電平1.778ms”表示;
數(shù)據(jù)1用“高電平1.778ms+低電平1.778ms”表示。
連續(xù)碼重復(fù)延時114ms。(未驗證)
所謂的解碼就是一個區(qū)分脈沖寬度的過程。紅外信號的0和1 是通過脈沖持續(xù)時間的長短來區(qū)分的。
我的遙控器使用的是NEC標(biāo)準(zhǔn)的WD6122芯片,遙控器編碼如下:
這里的用戶碼 是指接收到的用戶碼 即 第八位 為 00 高八位 為 FF
程序采用了狀態(tài)機的思路,分為檢測引導(dǎo)碼,32位數(shù)據(jù)接收,連發(fā)碼處理 三個狀態(tài)。
還對用戶碼進行了校驗,限定處理唯一用戶碼的遙控器的數(shù)據(jù)。對于反碼也加入了驗證。
檢測程序如下:(程序使用11.0592Mhz晶振 不能使用12Mhz)
#include#include"lcd1602.h"#defineucharunsignedchar//宏定義uchar為無符號字符#defineuintunsignedint#defineIR_UserCode0xFF00//紅外遙控器用戶碼ucharIR_Code[32]={0};ucharIR_User[16]={0};//用戶碼ucharIR_Data[8]={0};//數(shù)據(jù)碼ucharIR_CData[8]={0};//數(shù)據(jù)反碼ucharkey='0',value=0;//keyLCD顯示值;value接收頭接收到值(16進制)typedefenum{State_0=0x00,State_1=0x01,State_2=0x02}ScanState_Typedef;ScanState_TypedefScanState;voidIR_Check(void);voidIR_CodeHandle(void);voidIR_Decode(void);voiddelay(uintn);voidmain(){LCD_Init();LCD_WriteString("TheKeyIs:",1);while(1){IR_Check();}}voidIR_Check(void){uchari=0,n=0;switch(ScanState){caseState_0://檢測引導(dǎo)碼{while(IR_DQ==1);delay(500);if(IR_DQ==0){while(IR_DQ==0);delay(300);if(IR_DQ==1){ScanState=State_1;while(IR_DQ==1);}else{ScanState=State_2;//為連發(fā)碼}}else{ScanState=State_0;}break;}caseState_1://32位數(shù)據(jù)接收{(diào)while(i<32){while(IR_DQ==0);delay(60);//延時0.48msif(IR_DQ==1)IR_Code[i]=0;delay(28);//延時0.22ms,總延時0.70msif(IR_DQ==1){IR_Code[i]=1;while(IR_DQ==1);}else{IR_Code[i]=0;}i++;}IR_CodeHandle();ScanState=State_0;break;}caseState_2://連發(fā)碼處理{while(IR_DQ==0);ScanState=State_0;break;}}}voidIR_CodeHandle(void){ucharn=0,check=0;uintuser=0;for(n=0;n<8;n++){IR_User[n]=IR_Code[n];//低位用戶碼IR_User[8+n]=IR_Code[8+n];//高位用戶碼IR_Data[n]=IR_Code[16+n];IR_CData[n]=IR_Code[24+n];if(IR_Data[n]+IR_CData[n]==0x01){check++;}//反碼檢測,正數(shù)的原碼和補碼各位相加后為0x01}for(n=0;n<16;n++)//處理用戶碼{if(n==0){user=IR_User[0];}else{user+=IR_User[n]*(2<<(n-1));}}if((user==IR_UserCode)&&(check==8))//用戶碼校驗反碼校驗{for(n=0;n<8;n++)//處理數(shù)據(jù)碼,二進制轉(zhuǎn)換為16進制{if(n==0){value=IR_Data[0];}else{value+=IR_Data[n]*(2<<(n-1));}}IR_Decode();LCD_WriteByte(0xC7,0);//更新接收值LCD_WriteByte(key,1);}}voidIR_Decode(void){//P3=value;switch(value){case0x0D:key='0';break;case0x0C:key='1';break;case0x18:key='2';break;case0x5E:key='3';break;case0x08:key='4';break;case0x1C:key='5';break;case0x5A:key='6';break;case0x42:key='7';break;case0x52:key='8';break;case0x4A:key='9';break;default:key='?';}}voiddelay(uintn){while(--n);//8us一次}
lcd1602.h 的程序見: LCD顯示漢字一文
效果圖: