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