红外遥控器的解码
实测距离10米时不会错误或需要重复按遥控器 (*^__^*) ……
接收头
(原文件名:接收头.jpg.jpg)
正确解码
(原文件名:20110103426.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码 接受数据正确时第二行显示OK 旁边的数字是连_发次数
错误解码
(原文件名:20110103427.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码 接受数据错误时第二行显示error 旁边的数字是连_发次数
51开发板配的万能遥控器
(原文件名:20110103428.jpg)
-----------------------------------------------------------------------
51单片机啊
SONY SIRC参考:
http://davidallmon.com/sirc/sirc.php
http://www.8051projects.net/out.php?link=http://sbprojects.com/knowledge/ir/sirc.htm
#include <reg51.h>
/******************************************************************/
/* 函 数 声 明 */
/******************************************************************/
void Timer0init(void); //定时器0初始化
void EX0init(void); //外部中断初始化
void Decode(void); //解码子程序
/******************************************************************/
/* 宏 定 义 区 */
/* 由于遥控器和程序存在一定误差,必须允许编码时长有一定的范围 */
/* 以下定义了时长和范围以及本机地址。用于调试 */
/******************************************************************/
#define Guide_timer 22 //引导码最短时长
#define IR_L_timer_min 10 //数据0 最短时长
#define IR_L_timer_max 14 //数据0 最长时长
#define IR_H_timer_min 16 //数据1 最短时长
#define IR_H_timer_max 20 //数据1 最长时长
#define TIMER0_COUNT 0x9c //定时器定时时间 100us
#define Timeout_cnt 240 //超时时长
/******************************************************************/
/* 变 量 保 存 区 */
/******************************************************************/
static unsigned char Timer0_cnt; //定时器计数值
static unsigned char Timer0_cnt_bk;
static bit timeout; //超时标志
static bit Guide; //引导码有效
static unsigned char IR_time[13]; //保存每两个下降沿之间的时间间隔
static unsigned int IR_12bit;
static unsigned char IR_Command; //7bit命令 保存一次解码后接受到的数据
static unsigned char IR_Address; //5bit地址 保存一次解码后接受到的数据
static unsigned char IR_Newkey;
/************ 编解码说明 ***************
引导码:2.4ms低电平+ 0.6ms高电平
数据0:0.6ms低电平+0.6ms高电平
数据1:1.2ms低电平+0.6ms高电平
*****************************************/
/******************************************************************/
/* 红 外 遥 控 解 码 */
/* CPU & XTAL :51 @ 12Mhz */
/* 支持的红外编码方案: Sony */
/* 编码格式:引导信号 + 7bit command + 5bit address */
/******************************************************************/
/******************************************************************/
/* 定时器0初始化 */
/* 定时值:100us */
/* 方式2 自动重载 */
/******************************************************************/
void Timer0init(void)//定时器0初始化
{
//定时值 100us
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; //清除引导标志
m=0; //复位数据位
}
else
{
if(Guide) //如果引导码有效
{
IR_time[m++]=Timer0_cnt_bk; //保存时间间隔
if(m==12) //接收够12bit数据后
{
m=0;
Guide=0; //清除引导标志
Decode(); //解码
};
};
if(Timer0_cnt_bk>Guide_timer) //如果时间间隔>引导码时长
{
Guide=1; //使能引导标志
m=0;
};
};
}
/******************************************************************/
/* 解码子程序 */
/******************************************************************/
void Decode(void)
{
unsigned char bitcounter,timecounter=0x00;
EX0 = 0; //外部中断无效
for(bitcounter=12; bitcounter>0; bitcounter--)
{
{
if((IR_time[timecounter]>IR_L_timer_min)&(IR_time[timecounter]<IR_L_timer_max))//数据"0" 0.6ms低电平+0.6ms高电平
{
IR_12bit>>=1;
IR_12bit&=0x7f;
}
else if((IR_time[timecounter]>IR_H_timer_min)&(IR_time[timecounter]<IR_H_timer_max)) //数据"1" 1.2ms低电平+0.6ms高电平
{
IR_12bit>>=1;
IR_12bit|=0x80;
}
timecounter++;
}
}
IR_12bit>>=4; //再右移4位 使command低位对齐
IR_Command=(char)IR_12bit&0x7f; //保留低7位
IR_12bit>>=7; //再右移7位 使address低位对齐
IR_Address=(char)IR_12bit&0x1f; //保留低5位
if(IR_Address==0x01) //地址码=1
{
IR_Newkey=1;
}
EX0 = 1; //重新开放外部中断
}
/******************************************************************/
/* 键 处 理 函 数 */
/* 正确接收数据并解码时被中断程序调用 */
/* 按键处理函数结束前外部中断不开放 */
/* 此处保存按键处理函数,键值在于结构体IR_data */
/******************************************************************/
void main()
{
Timer0init();//定时器0初始化
EX0init(); //外部中断初始化
while(1)
{
;
}
}
void Decode(void)
{
unsigned char bitcounter,timecounter=0x00;
EX0 = 0; //外部中断无效
for(bitcounter=12; bitcounter>0; bitcounter--)
{
{
if((IR_time[timecounter]>IR_L_timer_min)&(IR_time[timecounter]<IR_L_timer_max)) //数据"0" 0.6ms低电平+0.6ms高电平
{
IR_12bit>>=1;
IR_12bit&=0xf7ff; //16位int数的第12位置0
}
else if((IR_time[timecounter]>IR_H_timer_min)&(IR_time[timecounter]<IR_H_timer_max)) //数据"1" 1.2ms低电平+0.6ms高电平
{
IR_12bit>>=1;
IR_12bit|=0x800; //16位int数的第12位置1
}
timecounter++;
}
}
IR_Command=(char)IR_12bit&0x7f; //保留低7位
IR_12bit>>=7; //再右移7位 使address低位对齐
IR_Address=(char)IR_12bit&0x1f; //保留低5位
if(IR_Address==0x01) //地址码=1
{
IR_Newkey=1;
}
EX0 = 1; //重新开放外部中断
}
一周热门 更多>