红外遥控器的解码
实测距离10米时不会错误或需要重复按遥控器 (*^__^*) ……
接收头
(原文件名:接收头.jpg.jpg)
正确解码
(原文件名:20110103426.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码 接受数据正确时第二行显示OK 旁边的数字是连_发次数
错误解码
(原文件名:20110103427.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码 接受数据错误时第二行显示error 旁边的数字是连_发次数
51开发板配的万能遥控器
(原文件名:20110103428.jpg)
#ifndef DECODE_H_
#define DECODE_H_
/******************************************************************/
/* 函 数 声 明 */
/******************************************************************/
void Timer0init(void);//定时器0初始化
void EX0init(void); //外部中断初始化
void Decode(void); //解码子程序
void get_IRkey(void); //键处理
/******************************************************************/
/* 宏 定 义 区 */
/* 由于遥控器和程序存在一定误差,必须允许编码时长有一定的范围 */
/* 以下定义了时长和范围以及本机地址。用于调试 */
/******************************************************************/
#define IR_addr1 0x0a //本机地址1
#define IR_addr2 0x0a //本机地址2
#define Guide_timer 39 //引导码最短时长
#define Continuous_timer 39 //连_发码最短时长
#define IR_L_timer_min 3 //数据0 最短时长
#define IR_L_timer_max 7 //数据0 最长时长
#define IR_H_timer_min 8 //数据1 最短时长
#define IR_H_timer_max 12 //数据1 最长时长
#define TIMER0_COUNT 0x1f //定时器定时时间
#define Timeout_cnt 250 //超时时长
/******************************************************************/
/* 变 量 保 存 区 */
/******************************************************************/
static unsigned char Timer0_cnt; //定时器计数值
static unsigned char Timer0_cnt_bk;
static bit timeout; //超时标志
static bit Guide; //引导码有效
static bit Continuous; //连_发码
static unsigned char IR_time[33]; //保存每两个下降沿之间的时间间隔
/******************************************************************/
/* 结 构 体 区 */
/* 保存一次解码后接受到的四字节数据 */
/******************************************************************/
static struct IR_data //红外接收数据寄存
{
unsigned char addr1; //地址1(客户码1)
unsigned char addr2; //地址2(客户码2)
unsigned char data1; //数据1(数据码)
unsigned char data2; //数据2(数据码反码)
}IR_data;
#endif
/************ 编解码说明 ***************
引导码+地址吗+地址码+数据码+数据码反码+连_发码+...
引导码:9ms低电平+4.5ms 高电平
连_发码:9ms低电平+2.25ms高电平
数据0:0.56ms低电平+0.56ms高电平
数据1:0.56ms低电平+1.69ms高电平
*****************************************/
=====================================C文件========================================================
/******************************************************************/
/* 红 外 遥 控 解 码 */
/* CPU & XTAL :89c52 @ 12Mhz */
/* 支持的红外编码方案: NEC6121 */
/* 编码格式:引导信号(或连_发信号)+地址码+地址码+控制码+控制码反码 */
/******************************************************************/
#include "decode.h"
#include "display.c"
/******************************************************************/
/* 定时器0初始化 */
/* 定时值:225us */
/* 方式2 自动重载 */
/******************************************************************/
void Timer0init(void)//定时器0初始化
{
//定时值 225us
TMOD=0x02;//定时器0工作方式2 自动重载
TH0=TIMER0_COUNT; //重载值
TL0=TIMER0_COUNT; //初始化值
ET0=1; //定时器0中断有效
TR0=1; //定时开始
}
/******************************************************************/
/* 外部中断初始化 */
/* 中断端口:外部中断0 P3.2 */
/* 触发方式:下降沿 */
/******************************************************************/
void EX0init(void)
{
EA = 1; //总中断开
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //外部中断有效
}
/******************************************************************/
/* Timer0中断子程序 */
/******************************************************************/
void Timer0(void) interrupt 1 using 1
{
Timer0_cnt++;
if(Timer0_cnt>Timeout_cnt)
timeout=1; //超时标志
}
/******************************************************************/
/* 外部中断0函数 */
/* 下降沿触发 */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0
{
static unsigned char m=0;
Timer0_cnt_bk=Timer0_cnt; //备份时间计数值,即前一个下降沿到本下降沿的时间间隔
Timer0_cnt=0x00; //清空时间计数值
if(timeout) //如果超时
{
TL0=TIMER0_COUNT; //初始化定时器0
Timer0_cnt=0x00; //清空时间计数值
timeout=0; //清除超时标志
Guide=0; //清除引导标志
Continuous=0; //清除连_发标志
m=0; //复位数据位
}
else
{
if(Guide|Continuous) //如果引导码有效
{
IR_time[m++]=Timer0_cnt_bk; //保存时间间隔
if(m==32) //接收够32数据后
{
m=0;
Guide=0; //清除引导标志
Decode(); //解码
};
};
if(Timer0_cnt_bk>Guide_timer) //如果时间间隔>引导码时长
{
Guide=1; //使能引导标志
m=0;
};
if(Timer0_cnt_bk>Continuous_timer) //如果时间间隔>引导码时长
{
Continuous=1; //使能引导标志
EX0=0;
/**此处加入连_发操作代码**/
display_Continuous();
EX0=1;
m=0;
};
};//end of 超时
}
/******************************************************************/
/* 解码子程序 */
/******************************************************************/
void Decode(void)
{
unsigned char m,n,s=0x00;
static unsigned char *p; //指向结构体IR_data.XX的指针
EX0 = 0; //外部中断无效
p=&IR_data.addr1;
for(n=0;n<4;n++)
{
for(m=8;m>0;m--)
{
if((IR_time
>IR_L_timer_min)&(IR_time<IR_L_timer_max))//数据“0” 0.56ms低电平+0.56ms高电平{
*p>>=1;
*p&=0x7f;
}
else if((IR_time
>IR_H_timer_min)&(IR_time<IR_H_timer_max)) //数据“1” 0.56ms低电平+1.69ms高电平
{
*p>>=1;
*p|=0x80;
};
s++;
};
p++;
};
if(IR_data.data2==~IR_data.data1) //数据2=数据1反码
{
if((IR_data.addr1==IR_addr1)&(IR_data.addr2==IR_addr2))
get_IRkey();
}
else
{
/**非本机遥控器或数据错误**/
display_error();
};
EX0 = 1; //重新开放外部中断
}
/******************************************************************/
/* 键 处 理 函 数 */
/* 正确接收数据并解码时被中断程序调用 */
/* 按键处理函数结束前外部中断不开放 */
/* 此处保存按键处理函数,键值在于结构体IR_data */
/******************************************************************/
void get_IRkey()
{
display_keyValue(); //显示从遥控收到的数据
}
============================================资料==============================================================
源程序ourdev_608886TMXLKE.rar(文件大小:41K) (原文件名:遥控解码 测试.rar)
网上找的教程 作者所有ourdev_608887HO95UR.pdf(文件大小:317K) (原文件名:手把手教你红外解码.pdf)
网上找的教程 作者所有ourdev_608888K13FOP.doc(文件大小:164K) (原文件名:红外解码.doc)
/************ 位变量定义 *********/
sbit RS=P1^3;
sbit RW=P1^1;
sbit E=P1^0;
sbit BF=P3^3;
-----------------------------------------------------------------------
红外接收头接单片机外部中断0,INT0 (P3.2)
1602数据口接P0 (需要上拉电阻)
晶振用12 MHz
一周热门 更多>