下面的程序是我把買的板子里面帶的稍微修改了一下,把之前的delay函數延時改成了定時器0方式二工作。單發的時候沒問題,連發的時候會變成FFH。
使用的收發協議就是那個NEC協議,9ms低+4.5ms高引導碼那個。紅外接收器輸出腳連的是外部中斷0,P3^2引腳..........
單片機源程序如下:
- #include<reg52.h>
- typedef unsigned int u16;
- typedef unsigned char u8;
- //#define u16 unsigned int
- //#define u8 unsigned char
- sbit LSA=P2^2;//數碼管位選
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit IRIN=P3^2;//外部中斷入口
- sbit LED1=P2^0;
- sbit LED2=P2^1;
- sbit LED3=P2^5;
- u8 irvalue[6];
- u8 count;
- u8 displaydata[8];
- u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};//0~f+h 顯示碼
- void digdisplay()
- {
- u8 i,j;
- for(i=0;i<3;i++)
- {
- switch(i)
- {
- case(0):LSA=1;LSB=1;LSC=1;break;
- case(1):LSA=0;LSB=1;LSC=1;break;
- case(2):LSA=1;LSB=0;LSC=1;break;
- }
- P0=displaydata[i];//發數據,displaydata是定義好要存數據的數組
- j=100;
- while(j--);
- P0=0x00;//消隱
- }
- }
- void judge()
- {
- if(irvalue[2]==69)
- LED1=~LED1;
- else if(irvalue[2]==94)
- LED2=~LED2;
- }
- void irinit()
- {
- IT0=1;//下降沿觸發
- EX0=1;//打開中斷0允許
- EA=1;//開總中斷
- IRIN=1;//初始化端口
- TMOD=0x02;//定時器0工作方式2
- TH0=0x06; //設置初值計時0.25ms
- TL0=0x06;
- ET0=1; //開定時器0中斷
- TR0=1; //啟動定時器0
- PT0=1; //定時器0
- }
- void main()
- {
- irinit();
- while(1)
- {
- displaydata[0]=smgduan[irvalue[2]/16];
- displaydata[1]=smgduan[irvalue[2]%16];
- displaydata[2]=smgduan[16];
- digdisplay();
- }
- }
- /*NEC碼位定義:一個脈沖560微秒連續載波,一個邏輯1傳輸需要560微秒脈沖+1680微秒低電平
- 一個邏輯0傳輸需要560微秒脈沖+560微秒低電平
- 在接收端對應的是 邏輯1:560微秒低電平+1680微秒高電平
- 邏輯0:560微秒低電平+560微秒高電平
- 通過時間判斷0或1
- NEC數據格式:9ms+4.5ms的引導碼
- 8位地址碼+8位地址反碼
- 8位控制碼+8位控制反碼*/
- void T0_TIMER() interrupt 1
- {
- count++;
- }
- void readir() interrupt 0
- {
- u8 j,k,l;
- count=0;
- //TR0=1;
- while(count<30);
- //TR0=0;
- if(IRIN==0)
- {
- count=0;
- while((IRIN==0)&&(count<40));//等9ms?
- if(IRIN==1)
- {
- count=0;
- while((IRIN==1)&&(count<20));
- //4.5ms? 引導碼
- for(l=0;l<4;l++)
- irvalue[l]=0;
- for(k=0;k<4;k++)//4組數據
- {
- for(j=0;j<8;j++)//接收一組數據
- {
- count=0;
- while((IRIN==0)&&(count<4));//等待信號前的560微秒
- LED3=0;
- count=0;
- while((IRIN==1)&&(count<8));//計算高電平
- irvalue[k]>>=1;//k表示第幾組數據,右移一位
- if(count>4) //高電平大于565微秒? 800微秒
- {
- irvalue[k]|=0x80;
- }
- count=0;
- }
- }
- }
- if(irvalue[2]!=~irvalue[3])
- return;
- judge();
- }
- }
復制代碼
|