通過中斷方式接收紅外線,并譯出對應編碼。
單片機源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- sbit hwx=P3^3; //定義紅外接收腳,
- code unsigned char d[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- //P0段選,共陽數碼管 0-9 a-f - 表
- unsigned char code w[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
- //P1位選,直接使用P1的8個端口進行8位選擇
- unsigned char l_tmpdate[4]={0,0,0,0};//顯示管數據
- unsigned char l_lhj[66]; //定義66位數組變量來存儲接收的時間參數
- void delay(); //延時子函數
- void display(unsigned char *lp);//數字的顯示函數;lp為指向數組的地址
- void main(void) //入口函數
- {
- EA=1; //首先開啟總中斷
- EX1=1; //開啟外部中斷 1
- IT1=1; // 設置成 下降沿觸發方式
- while(1){ //循環顯示,接收都由中斷處理
- display(l_tmpdate);
- }
- }
- void display(unsigned char *lp)//顯示
- {
- P2=w[5];
- P0=~d[lp[0]]; //查表法得到要顯示數字的數碼段
- delay();
- //P0=0; //清除顯示,為下一位顯示準備
- P2=w[4];
- P0=~d[lp[1]];
- delay();
- // P0=0;
- P2=w[2];
- P0=~d[lp[2]];
- delay();
- // P0=0;
- P2=w[1];
- P0=~d[lp[3]];
- delay();
- //P0=0;
- }
- void delay(void) //空5個指令
- {
- unsigned char i=13;
- while(i)
- i--;
- }
- void hongwai(void) interrupt 2 //外部中斷 1 ,INT1(P3^3)連接紅外線接收IC數據腳
- {
- unsigned char i,j,tmp;
- EX1=0; //暫是關閉處斷中斷1,才能正常接收數據
- j=33; //傳送一組數包括引導碼1位,地址碼8位加反碼8位,指令碼8位加反碼8位,總共33位
- i=0; //從第一維數組開始
- tmp=100; //加八延時,按鍵消抖
- while(tmp){
- tmp--;
- }
- if(hwx){ //然后再檢測紅線接收腳是有數據接收,有繼續,沒有則退出
- EX1=1;
- return;
- }
- while(j){ //循環接收33位數據,為何我們用到66位數組,我們可以不接收高電平時間常數,只接低電平常數就
- //可以判斷1或0了,在這里我們都接收,為串口調試軟件接收計算波形
- //還有一點要知道,接收波形是反向,在沒有接收時端口為高電平
- tmp=0;
- l_lhj[i]=1; //時間量從1開始
- while(!hwx){ //檢測高低電平的變化,累計低電平的持續時間
- l_lhj[i]++; //沒變繼續加1
- delay(); //加入延時,是因為我們采用8位二進來存儲,如果不加延時,時間量將計滿
- tmp++; //此變量為防止干擾帶來的死循環,也就是低電平持續時間最長不超過250個延時
- if(tmp==250)
- break;
- }
- i++;
- tmp=0;
- l_lhj[i]=1; //時間量從1開始
- while(hwx){ //檢測高低電平的變化,累計高電平的持續時間
- l_lhj[i]++; //沒變繼續加1
- delay(); //同上
- tmp++;
- if(tmp==250)
- break;
- }
- i++;
- j--;
- }
- i=255; //加入循環延時,抗干擾
- while(i){
- tmp=255;
- while(tmp){
- P0=0XF0;
- tmp--;
- }
- i--;
- }
- tmp=0;
- for(i=3;i<19;i++,i++){ //處理地址位,對低電平時間數據的數理,這里我們只處理地址碼和指令碼,引導碼和反碼我們就忽略
- tmp>>=1; //右移一位,接收低電平在前
- if(l_lhj[i]>30) //檢測低電平時間超過30就確認為1
- tmp+=0x80; //0x80=10000000
- }
- l_tmpdate[0]=tmp/16; //分開2位以16進制顯示
- l_tmpdate[1]=tmp%16;
-
- tmp=0;
- for(i=35;i<51;i++,i++){ //同上,這里處理指令位
- tmp>>=1;
- if(l_lhj[i]>30)
- tmp+=0x80;
- }
- l_tmpdate[2]=tmp/16;
- l_tmpdate[3]=tmp%16;
- EX1=1;
- //再次啟用外部中斷1,為下一次接收做準備
- }
復制代碼
所有資料51hei提供下載:
ir.rar
(18.28 KB, 下載次數: 12)
2018-5-22 15:22 上傳
點擊文件名下載附件
|