紅外線一開(kāi)始發(fā)送一段13.5ms的引導(dǎo)碼,引導(dǎo)碼由9ms的高電平和4.5ms的低電平組成,跟著引導(dǎo)碼是系統(tǒng)碼,系統(tǒng)反碼,按鍵碼,按鍵反碼,如果按著鍵不放,則遙控器則發(fā)送一段重復(fù)碼,重復(fù)碼由9ms的高電平,2.25ms的低電平,跟著是一個(gè)短脈沖,本程序是免費(fèi)給大家,版權(quán)所有,不得用于商業(yè)目的,如需用到本程序到商業(yè)上請(qǐng)與本人聯(lián)系經(jīng)本人同意后方可用于商業(yè)目的,本程序經(jīng)過(guò)試用,能解大部分遙控器的編碼!
#include "at89x52.h" #define NULL 0x00//數(shù)據(jù)無(wú)效 #define RESET 0X01//程序復(fù)位 #define REQUEST 0X02//請(qǐng)求信號(hào) #define ACK 0x03//應(yīng)答信號(hào),在接收數(shù)據(jù)后發(fā)送ACK信號(hào)表示數(shù)據(jù)接收正確, 也位請(qǐng)求信號(hào)的應(yīng)答信號(hào) #define NACK 0x04//應(yīng)答信號(hào),表示接收數(shù)據(jù)錯(cuò)誤 #define BUSY 0x05//忙信號(hào),表示正在忙 #define FREE 0x06//空閑信號(hào),表示處于空閑狀態(tài) #define READ_IR 0x0b//讀取紅外 #define STORE_IR 0x0c//保存數(shù)據(jù) #define READ_KEY 0x0d//讀取鍵值 #define RECEIVE 0Xf400//接收緩沖開(kāi)始地址 #define SEND 0xfa00//發(fā)送緩沖開(kāi)始地址 #define IR 0x50//紅外接收緩沖開(kāi)始地址 #define HEAD 0xaa//數(shù)據(jù)幀頭 #define TAIL 0x55//數(shù)據(jù)幀尾 #define SDA P1_7 #define SCL P1_6
unsigned char xdata *buf1; //接受數(shù)據(jù)緩沖 unsigned int buf1_length; //接收到的數(shù)據(jù)實(shí)際長(zhǎng)度 unsigned char xdata *buf2; //發(fā)送數(shù)據(jù)緩沖 unsigned int buf2_length; //要發(fā)送的數(shù)據(jù)實(shí)際長(zhǎng)度 bit buf1_flag; //接收標(biāo)志,1表示接受到一個(gè)數(shù)據(jù)幀,0表示沒(méi)有接受到數(shù)據(jù)幀或數(shù)據(jù) 幀為空 bit buf2_flag; //發(fā)送標(biāo)志,1表示需要發(fā)送或沒(méi)發(fā)送完畢,0表示沒(méi)有要發(fā)送的數(shù)據(jù)或 發(fā)送完畢 unsigned char state1,state2; //用來(lái)標(biāo)志接收字符的狀態(tài),state1用來(lái)表示接 收狀態(tài),state2用來(lái)表示發(fā)送狀態(tài) unsigned char data *ir; union{ unsigned char a[2]; unsigned int b; unsigned char data *p1[2]; unsigned int data *p2[2]; unsigned char xdata *p3; //紅外緩沖的指針 unsigned int xdata *p4; }p; //union{ // // unsigned char a[2]; // // unsigned int b; // unsigned char data *p1[2]; // unsigned int data *p2[2]; // unsigned char xdata *p3; // unsigned int xdata *p4; //地址指針 //}q; //
union{ unsigned char a[2]; unsigned int b; }count; union{ unsigned char a[2]; unsigned int b; }temp; union{ unsigned char a[4]; unsigned int b[2]; unsigned long c; }ir_code;
union{ unsigned char a[4]; unsigned int b[2]; unsigned long c; unsigned char data *p1[4]; unsigned int data *p2[4]; unsigned char xdata *p3[2]; unsigned int xdata *p4[2]; }I; unsigned char ir_key; bit ir_flag; //紅外接收標(biāo)志,0為緩沖區(qū)空,1為接收成功,2為緩沖溢出 void sub(void); void delay(void); void ie_0(void); void tf_0(void); void ie_1(void); void tf_1(void); void tf_2(void); void read_ir(void); void ir_jiema(void); void ir_init(void); void ir_exit(void); void store_ir(void); void read_key(void); void reset_iic(void); unsigned char read_byte_ack_iic(void); unsigned char read_byte_nack_iic(void); bit write_byte_iic(unsigned char a); void send_ack_iic(void); void send_nack_iic(void); bit receive_ack_iic(void); void start_iic(void); void stop_iic(void); void write_key_data(unsigned char a); unsigned int read_key_data(unsigned char a); void ie0(void) interrupt 0{ie_0();} void tf0(void) interrupt 1{tf_0();} void ie1(void) interrupt 2{ie_1();} void tf1(void) interrupt 3{tf_1();tf_2();} void tf2(void) interrupt 5{ //采用中斷方式跟查詢方式相結(jié)合的辦法解碼 EA=0; //禁止中斷 if(TF2){ //判斷是否是溢出還是電平變化產(chǎn)生的中斷 TF2=0; //如果是溢出產(chǎn)生的中斷則清除溢出位,重新開(kāi)放中斷退出 EA=1; goto end; } EXF2=0; //清除電平變化產(chǎn)生的中斷位 *ir=RCAP2H; //把捕捉的數(shù)保存起來(lái) ir++; *ir=RCAP2L; *ir++; F0=1; TR0=1; //開(kāi)啟計(jì)數(shù)器0 loop: TL0=0; //將計(jì)數(shù)器0重新置為零 TH0=0; while(!EXF2){ //查詢等待EXF2變?yōu)? if(TF0)goto exit; //檢查有沒(méi)超時(shí),如果超時(shí)則退出 }; EXF2=0; //將EXF2清零 if(!TH0) //判斷是否是長(zhǎng)低電平脈沖過(guò)來(lái)了 { //不是長(zhǎng)低電平脈沖而是短低電平 if(F0)count.b++; //短脈沖數(shù)加一 temp.a[0]=RCAP2H; //將捕捉數(shù)臨時(shí)存放起來(lái) temp.a[1]=RCAP2L; goto loop; //返回繼續(xù)查詢 } else{ //是低電平脈沖,則進(jìn)行處理
F0=0; *ir=temp.a[0]; //把連續(xù)的短脈沖總時(shí)間記錄下來(lái) ir++; *ir=temp.a[1]; ir++; *ir=RCAP2H; //把長(zhǎng)電平脈沖時(shí)間記錄下來(lái) ir++; *ir=RCAP2L; ir++; if(ir>=0xda) { goto exit; //判斷是否溢出緩沖,如果溢出則失敗退出 } goto loop; //返回繼續(xù)查詢 } exit: ir_flag=1; //置ir_flag為1表示接收成功 end: ; }
void rs232(void) interrupt 4{ static unsigned char sbuf1,sbuf2,rsbuf1,rsbuf2; //sbuf1,sbuf2用來(lái)接收 發(fā)送臨時(shí)用,rsbuf1,rsbuf2用來(lái)分別用來(lái)存放接收發(fā)送的半字節(jié) EA=0; //禁止中斷 if(RI){ RI=0; //清除接收中斷標(biāo)志位 sbuf1=SBUF; //將接收緩沖的字符復(fù)制到sbuf1 if(sbuf1==HEAD){ //判斷是否幀開(kāi)頭 state1=10; //是則把state賦值為10 buf1=RECEIVE; //初始化接收地址 } else{ switch(state1){ case 10:sbuf2=sbuf1>>4; //把高半字節(jié)右移到的半字節(jié) sbuf2=~sbuf2; //把低半字節(jié)取反 if((sbuf2&0x0f)!=(sbuf1&0x0f)) //判斷接收是否正確 { //接收錯(cuò)誤,有可能接收的是數(shù)據(jù)幀尾,也有可能是接收錯(cuò)誤 if(sbuf1==TAIL) //判斷是否接收到數(shù)據(jù)幀尾 { //是接收到數(shù)據(jù)幀尾 buf1=RECEIVE; //初始化接收的地址 if(*buf1==RESET) //判斷是否為復(fù)位命令 { ES=0; sbuf2=SP+1; for(p.p1[0]=SP-0x10;p.p1[0]<=sbuf2;p.p1 [0]++)*p.p1[0]=0; } state1=0; //將接收狀態(tài)標(biāo)志置為零,接收下一個(gè)數(shù)據(jù)幀 buf1_flag=1; //置接收標(biāo)志為1,表示已經(jīng)接收到一個(gè)數(shù)據(jù)幀 REN=0; //禁止接收 } else { //不是接受到數(shù)據(jù)幀尾,表明接收錯(cuò)誤 state1=0; // 將接收狀態(tài)標(biāo)志置為零,重新接收 buf1=RECEIVE; //初始化發(fā)送的地址 *buf1=NACK; //把NACK信號(hào)存入接收緩沖里 buf1_flag=1; //置標(biāo)志位為1,使主程序能對(duì)接收錯(cuò)誤進(jìn)行處理 REN=0; //禁止接收 }
} else { //接收正確 rsbuf1=~sbuf1; //按位取反,使高半字節(jié)變?cè)a rsbuf1&=0xf0; //僅保留高半字節(jié),低半字節(jié)去掉 state1=20; //將狀態(tài)標(biāo)志置為20,準(zhǔn)備接收低半字節(jié) } break; case 20:sbuf2=sbuf1>>4; //把高半字節(jié)右移到的半字節(jié) sbuf2=~sbuf2; //將低半字節(jié)取反 if((sbuf2&0x0f)!=(sbuf1&0x0f)) //判斷接收是否正確 { //接受錯(cuò)誤 state1=0; // 將接收狀態(tài)標(biāo)志置為零,重新接收 buf1=RECEIVE; //初始化接收的地址 *buf1=NACK; //把NACK信號(hào)存入發(fā)送緩沖里 buf1_flag=1; //置標(biāo)志位為1,使主程序能對(duì)接收錯(cuò)誤進(jìn)行處理 REN=0; //禁止接收 } else { sbuf1&=0x0f; //僅保留低半字節(jié),去掉高半字節(jié) rsbuf1|=sbuf1; //高低半字節(jié)合并 *buf1++=rsbuf1; //將接收的數(shù)據(jù)保存至接收緩沖里,并且數(shù)據(jù)指針加一 buf1_length++; //接收數(shù)據(jù)長(zhǎng)度加一 state1=10; //將state1置為10,準(zhǔn)備接收下個(gè)字節(jié)的高半字節(jié) } break;
} }
} else{
TI=0; //清除發(fā)送中斷標(biāo)志 if(buf2_length) //判斷發(fā)送長(zhǎng)度是否為零 { //發(fā)送長(zhǎng)度不為零 if(state2==0) //判斷是否發(fā)送高半字節(jié) { //發(fā)送高半字節(jié) sbuf2=*buf2; //將要發(fā)送的字節(jié)送到sbuf2 rsbuf2=~sbuf2; //取反,使高半字節(jié)變?yōu)榉创a sbuf2>>=4; //將高半字節(jié)右移到低半字節(jié) rsbuf2&=0xf0; //保留高半字節(jié),去掉低半字節(jié) sbuf2&=0x0f; //保留低半字節(jié),去掉高半字節(jié) rsbuf2|=sbuf2; //合并高低半字節(jié) SBUF=rsbuf2; //發(fā)送出去 state2=10; //將state2置為10準(zhǔn)備發(fā)送下半字節(jié) } else { //發(fā)送低半字節(jié) sbuf2=*buf2; //將要發(fā)送的字節(jié)送到sbuf2 buf2++; //指針加一 buf2_length--; //發(fā)送數(shù)據(jù)長(zhǎng)度減一 rsbuf2=~sbuf2; //取反,使低半字節(jié)變?yōu)榉创a rsbuf2<<=4; //將低半字節(jié)反碼左移到高半字節(jié) rsbuf2&=0xf0; //保留高半字節(jié),去掉低半字節(jié) sbuf2&=0x0f; //保留低半字節(jié),去掉高半字節(jié) rsbuf2|=sbuf2; //合并高低半字節(jié) SBUF=rsbuf2; //發(fā)送出 state2=0; } } else { //如果發(fā)送數(shù)據(jù)長(zhǎng)度為零則發(fā)送數(shù)據(jù)幀尾 if(buf2_flag){ //判斷是否發(fā)過(guò)數(shù)據(jù)幀尾 SBUF=TAIL; //將數(shù)據(jù)幀尾發(fā)送出去 while(TI==0); TI=0; buf2_flag=0; //置發(fā)送標(biāo)志為零,表示發(fā)送完畢 } } } EA=1; //開(kāi)放中斷 }
|