钻石会员
主题
帖子
积分14173
阅读权限50
注册时间2009-11-17
最后登录1970-1-1
在线时间 小时
|
用以前做的类似的改了一下,仅供参考。
//红外解码的参数是按照11.0592M来的,用其他的需修改。
#include<reg52.h>
#include "intrins.h"
sbit out_1=P1^0;
sbit out_2=P1^1;
sbit out_3=P1^2;
sbit out_4=P1^3;
sbit out_5=P1^4;
sbit out_6=P1^5;
sbit out_7=P1^6;
sbit out_8=P1^7;
sbit beep=P3^7;
sbit IR=P3^2; //将IR位定义为P3.2引脚
unsigned char a[4]; //储存用户码、用户反码与键数据码、键数据反码
unsigned int LowTime,HighTime; //储存高、低电平的宽度
unsigned char hwcode;
void delay_ms(int ms)
{
unsigned char y ;
while(ms--)
{
for(y = 0 ; y<250 ; y++)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
}
}
/************************************************************
函数功能:对4个字节的用户码和键数据码进行解码
说明:解码正确,返回1,否则返回0
出口参数:dat
*************************************************************/
bit DeCode(void)
{
unsigned char i,j;
unsigned char temp; //储存解码出的数据
for(i=0;i<4;i++) //连续读取4个用户码和键数据码
{
for(j=0;j<8;j++) //每个码有8位数字
{
temp=temp>>1; //temp中的各数据位右移一位,因为先读出的是高位数据
TH0=0; //定时器清0
TL0=0; //定时器清0
TR0=1; //开启定时器T0
while(IR==0); //如果是低电平就等待
//低电平计时
TR0=0; //关闭定时器T0
LowTime=TH0*256+TL0; //保存低电平宽度
TH0=0; //定时器清0
TL0=0; //定时器清0
TR0=1; //开启定时器T0
while(IR==1) //如果是高电平就等待
;
TR0=0; //关闭定时器T0
HighTime=TH0*256+TL0; //保存高电平宽度
if((LowTime<370)||(LowTime>640))
return 0; //如果低电平长度不在合理范围,则认为出错,停止解码
if((HighTime>420)&&(HighTime<620)) //如果高电平时间在560微秒左右,即计数560/1.085=516次
temp=temp&0x7f; //(520-100=420, 520+100=620),则该位是0
if((HighTime>1300)&&(HighTime<1800)) //如果高电平时间在1680微秒左右,即计数1680/1.085=1548次
temp=temp|0x80; //(1550-250=1300,1550+250=1800),则该位是1
}
a[i]=temp; //将解码出的字节值储存在a[i]
}
if(a[2]=~a[3]) //验证键数据码和其反码是否相等,一般情况下不必验证用户码
return 1; //解码正确,返回1
return 0;
}
/************************************************************
函数功能:红外线触发的外中断处理函数
*************************************************************/
void Int0(void) interrupt 0
{
EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
TH0=0; //定时器清0
TL0=0; //定时器清0
TR0=1; //开启定时器T0
while(!IR){
LowTime=TH0*256+TL0;
if(LowTime>10000){TR0=0;EX0=1;return;}
} //如果是低电平就等待 低电平计时
TR0=0; //关闭定时器T0
LowTime=TH0*256+TL0; //保存低电平宽度
TH0=0; //定时器清0
TL0=0; //定时器清0
TR0=1; //开启定时器T0
while(IR){HighTime=TH0*256+TL0;
if(HighTime>5000){TR0=0;EX0=1;return;}
} //如果是高电平就等待
TR0=0; //关闭定时器T0
HighTime=TH0*256+TL0; //保存高电平宽度
if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))
{
//如果是引导码,就开始解码,否则放弃,引导码的低电平计时
//次数=9000us/1.085=8294, 判断区间:8300-500=7800,8300+500=8800.
if(DeCode()==1) // 执行遥控解码功能
{
hwcode=a[2];
}
}
IR=1;
EX0=1; //开启外中断EX0
}
//主程序
void main()
{
EA=1; //开启总中断
EX0=1; //开外中断0
ET0=1; //定时器T0中断允许
IT0=1; //外中断的下降沿触发
ET1=1;
TMOD=0x11; //使用定时器T0的模式1
TR0=0;
while(1)
{
//自锁模式
switch(hwcode)
{case 0x1F:out_1=!out_1;break;
case 0x02:out_2=!out_2;break;
case 0x03:out_3=!out_3;break;
case 0x04:out_4=!out_4;break;
case 0x05:out_5=!out_5;break;
case 0x06:out_6=!out_6;break;
case 0x07:out_7=!out_7;break;
case 0x08:out_8=!out_8;break;
}
//点动模式,按一下保持100MS
/*switch(hwcode)
{case 0x1F:out_1=1;delay_ms(100);out_1=0;break;
case 0x02:out_2=1;delay_ms(100);out_2=0;break;
case 0x03:out_3=1;delay_ms(100);out_3=0;break;
case 0x04:out_4=1;delay_ms(100);out_4=0;break;
case 0x05:out_5=1;delay_ms(100);out_5=0;break;
case 0x06:out_6=1;delay_ms(100);out_6=0;break;
case 0x07:out_7=1;delay_ms(100);out_7=0;break;
case 0x08:out_8=1;delay_ms(100);out_8=0;break;
}
*/
hwcode=0;
}
} |
|