下面的程序是我把买的板子里面带的稍微修改了一下,把之前的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();
- }
- }
复制代码
|