本帖最后由 zlkj 于 2016-11-22 19:02 编辑
敬请!把网友发表的“遥控器的红外解码C51程序”,给写出完整的遥控器程序,感谢!
以下程序具有短按、长按、连发功能。
/*********************************Copyright (c)*****************************
**
** 飞鹏电子工作室
** 嵌入式项目
** http://xpstudio2003.blog.163.com
**
**项目名称: xp51InfraredDecoder
**编译环境: KEIL 2
**--------------------------------------------------------------------------
**文 件 名: Decoder.C
**作 者: 曹香鹏
**创建日期: 2008年12月04日
**描 述: 代码参考网友冰棍的解码程序,在此致谢.
**功能说明: 可以返回 单按键长按键连发键, 不占用定时器,只用一个外部中断资源.
**--------------------------------------------------------------------------
**维护记录: 2009年1月27日,添加程序,NEC解码格式,
引导码+16位系统码+8位按键码+8位按键反码
引导码由9ms的低电平和4.5ms的高电平组成,
数据码为一段560us低电平,后引一段高电平,高电平长度为1680us时为1,560us时为0
如果按着键不放,则遥控器则发送一段重复码,
重复码由9ms的低电平,2.25ms的高电平,跟着是一个短脉冲 2009年1月27日20:00,解码成功,
关键问题:
100US的延时要精确,我是试出来的.通过测试前面的9ms引导低电平 2009年1月28日16:09,添加按键的分类
加入按下,长按,连发.
****************************************************************************/
#include "xp51HDF.H"
#include "Uart.h"
#include "Decoder.H"
BOOL IR_Flag=FALSE; //有键标志
INT8U IR_SysDat; //系统码
INT8U IR_KeyDat; //按键码
static INT8U IR_KeyTmp; //储存按键的原始值 //延时约100us
//晶振11.0592MHz
//一定要算准了,,呵呵,,
void Delay100us(void)
{
INT16U i="78";
while(--i);
}
void DropExInt0(void) interrupt 0
{
static INT8U IR_Repeat; //有重复键标志的次数
INT8U dataIR[4];
INT8U IR_Data;
INT8U width="0";
INT8U i="0" ;
IR_INT_CLOSE(); //禁止再次中断. //--------------------------------------------
//计算引导电平的宽度
//引导电平长9.45ms while(!IR_PIN)
{
Delay100us();
width ++;
} // SendComm(width);return;//test code
// 测试代码,返回值.一般返回为0X5A=90D为正确,再注释掉上面的程序行就可以了.
// // 8ms=80*100us 如果不到8ms视为干扰信号
if(width<80)
{
IR_INT_OPEN();
return ;
}
//--------------------------------------------
// 计算后续高电平宽度 width = 0;
while(IR_PIN)
{
Delay100us();
width ++;
}
//--------------------------------------------
//判断是否是重复信号2.5ms
//3ms=30*100us 如果不到3ms即视为2.5ms重复信号
if(width<30)
{
IR_Repeat ++; //接收到一次按键 //判断"连发"键
if(IR_Repeat > IR_REPEAT_LONG + IR_REPEAT_STEP)
{
IR_KeyDat = IR_KeyTmp | KEY_LIAN;
IR_Repeat -= IR_REPEAT_STEP;
IR_Flag = TRUE;
}
//判断"长按"键
else if(IR_Repeat == IR_REPEAT_LONG)
{
IR_KeyDat = IR_KeyTmp | KEY_LONG;
IR_Flag = TRUE;
} IR_INT_OPEN();
return;
}
IR_Repeat = 0 ; //--------------------------------------------
//4.5ms新键码引导电平
//4ms=40*100us 如果不到4ms视为错误信号,放弃接收
if(width<40)
{
IR_INT_OPEN();
return ;
}
//--------------------------------------------
//接收系统码和数据码,一共32位 //接收32位数据
while(i++<32)
{
//数据准备
width = 0;
IR_Data >>= 1; //等待低电平过去.
while(!IR_PIN); //数高电平长度: 1=1680us 0=560us
while(IR_PIN)
{
Delay100us();
width++;
}
if(width > 9)
{
IR_Data |= 0x80;
} //数据分类
if(i==8)
dataIR[0] = IR_Data ;
else if(i==16)
dataIR[1] = IR_Data ;
else if(i==24)
dataIR[2] = IR_Data ;
else if(i==32)
dataIR[3] = IR_Data ;
}
//--------------------------------------------
//纠错校验
if(dataIR[2] != ~dataIR[3])
{
IR_INT_OPEN();
return ;
}
//--------------------------------------------
//保存键值.
IR_SysDat = dataIR[1]; //保存遥控器类型
IR_KeyTmp = dataIR[2];
IR_KeyDat = KEY_DOWN | IR_KeyTmp; //保存键值及类型
IR_Flag = TRUE; //标记有键按下
IR_INT_OPEN(); }
|