轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_6b86b0f20101iq0q.html
上述“0”、“1”組成的32位二進制碼經(jīng)過38KHz的載波進行二次調(diào)制以提高發(fā)射效率、降低電源功耗。
32位二進制碼組中,前16位為用戶識別碼,能區(qū)別不同電氣設(shè)備防止不同機種遙控碼相互干擾。后16位為8位操作碼極其反碼。遙控器在按下后周期性的發(fā)出一種32位二進制碼,周期108ms。這108ms由一個起始碼(9ms),一個結(jié)果碼(4.5ms),低8位地址碼、高8位地址碼、8位數(shù)據(jù)碼極其8位數(shù)據(jù)反碼組成。
接受時使用1838通用紅外接頭
上述是我自己整理的資料。后經(jīng)示波器驗證大致是這樣的,便開始編寫程序。
紅外解碼的關(guān)鍵就是識別“0”和“1”。以下是具體代碼,通過51單片機接受紅外信號,解碼后將8位操作碼通過串口以十六進制發(fā)送給電腦(比較粗糙,還沒來得及完善,僅供參考)
#include//單片機型號STC89C52
#define uchar unsigned char
#define uint unsigned int
sbit IR=P3^2;//位定義,使用P3^2口外部中斷0
uint lowtime,hightime;
uchar a[4],m,flag;
bit decode();//解碼程序
void sci();//串口初始化
void main()
{
// delay_ms(100);
TR0=0;
TH0=0;
TL0=0;
sci();
EA=1;
IT0=1;//設(shè)置外部中斷0為下降沿觸發(fā)方式
EX0=1;//開外部中斷0
while(1)
{
if(flag==1) //驗證前導(dǎo)碼正確后才開始解碼并向串口發(fā)送數(shù)據(jù)
{
decode();
for(m=0;m<1;m++)//向串口發(fā)射a[2],及8位操作碼
{
SBUF=a[2];
while(!TI);
TI=0;
}
while(1);
}
}
}
void ext0() interrupt 0
{
EX0=0;//進外部中斷0后立即關(guān)閉中斷0,防止二次中斷
TR0=1;//開定時器0
while(IR==0);//一直計數(shù),直到IR由0跳變到1
TR0=0;//關(guān)閉定時器0
lowtime=256*TH0+TL0;//lowtime儲存引導(dǎo)碼低電平持續(xù)時間
TH0=0;
TL0=0;//清空定時器0寄存器值,以備下一次計數(shù)
TR0=1;
while(IR==1);//等待IR由1跳表到0
TR0=0;//關(guān)閉定時器0
hightime=256*TH0+TL0;//hightime存儲結(jié)果碼高電平持續(xù)時間
if((lowtime>7800)&&(lowtime<8800)&&(hightime>3600)&&(hightime<4700))
//9000us/1.085=8294,判斷區(qū)間8800-7800
//4500us/1.085=4100,判斷區(qū)間3600-4700
//此值為11.0592MHz晶振時的值。
flag=1;//符合判斷條件則將flag標志置1,否則認為是干擾信號不予解碼
}
bit decode()
{
uchar temp;
uchar i,j;
for(i=0;i<4;i++)
{
for(j=0;j<7;j++)
{
temp>>=1;
TH0=0;
TL0=0;
TR0=1;
while(IR==0);
TR0=0;
lowtime=256*TH0+TL0;
TH0=0;
TL0=0;
TR0=1;
while(IR==1);
TR0=0;
hightime=256*TH0+TL0;
if((lowtime<370)||(lowtime>640))//低電平時間長度不合理
return 0;
if((hightime>420)&&(hightime<620))//高電平持續(xù)時間560us左右即位“0”
temp&=0x7f;
if((hightime>1300)&&(hightime<1800))//高電平持續(xù)時間1680us左右即位“1”
temp|=0x80;
}
a[i]=temp;
}
}
void sci()
{
SM0=0;
SM1=1;
REN=1;
TMOD=0x21;//此處注意設(shè)置定時器0的方式為工作方式1
TH1=0xfd;
TL1=0xfd;
TR1=1;
ES=1;
}
這只是初步的程序,調(diào)試過程中狀況百出。顯示串口顯示問題,SBUFS是8位寄存器,只能存儲8位二進制數(shù)據(jù),故32位二進制需要發(fā)送四次,每次到串口為1位十六進制數(shù)據(jù)。還有定時器0的模式,之前一直沒有設(shè)置,結(jié)果郁悶了一晚上。
另外,關(guān)于紅外的用途的話,有人說這東西接受距離不遠,也就幾米(有資料說在輸出段并上1uf電容可將接收距離增加至十多米,待驗證),最致命的是它是紅外線,必須要將發(fā)射端對準接收端才能接收到信號,這就是它比不上藍牙、NRF24L01等無線通信最主要的原因。不過,NRF24L01之麻煩,以我的智商估計沒有半個月是做不出來的。