不同型号的遥控器使用不同的红外协议,那怎么做一个万能遥控破解器来实现对所有遥控的破解呢,这里介绍一种简单粗暴的方法。
绝大多数遥控使用40KHZ左右的载波频率,所以我们使用一个简单的遥控接收器就好了,我们使用的是VS1838B这个型号,能接收40KHz左右的频率;
经过红外接收器,我们就收到了一连串的高低电平信号。
接下来我们就是用简单粗暴的方法来记录这个遥控信号,我们只需要记录每一个电平的位置和时间就好了,然后把这一帧所有的高低电平的位置和时间存储在外部存储器中,下次要发送同样的信号的时候,只需要读取这些信息,按原样发送出来就好了。
具体实现如下:
首先定义相关变量,注意我们将电平位置和长度信息写到一个结构体里面,value_msg里面一个位代表一个电平,其
#define SEND_RED 0 //默认的发送状态
#define READ_RED 1 //读取红外信号状态
#define READ_OK 2 // 读取成功,等待按键匹配状态
struct KEYMSG{
unsigned char key_value;//对应到矩阵键盘键值
unsigned int count_bit;//该红外信号高低电平总个数,一般是bit*2
unsigned char value_msg[40];//记录高低电平
unsigned char time[640];//记录每一个电平持续时间,每两个一组,分别存放TH0,TL0
};
volatile struct KEYMSG key_info;
data volatile unsigned char sys_status = SEND_RED;//系统当前状态
在外部中断收集这些信息,将信息存储在结构体里面
/*******************************************************************************
* 函 数 名 :Exit0Int
* 函数功能 :外部中断0 ISR
* 输 入 :无
* 输 出 :无
*******************************************************************************/
void Exit0Int() interrupt 0
{
EX0 = 0;
if(sys_status != READ_RED) return;
TH0 = 0;
TL0 = 0;
TR0 = 1;
while(1)
{
if(IRIN == 1)
{
while(IRIN)
{
if(TH0 > 200)//电平持续时间超出约20ms,即可返回
{
if(key_info.count_bit >= 16)
{
LED_ok = 0;
sys_status = READ_OK;
TR0 = 0;
return;
}
else
{
memset(&key_info.key_value , 0 , sizeof(struct KEYMSG));//清空buf
printf("key_info.count_bit < 16\r\n");
TR0 = 0;
EX0 = 1;
return;
}
}
}
}
else if(IRIN == 0)
{
while(!IRIN);
}
TR0 = 0;
key_info.time[key_info.count_bit*2] = TH0;
key_info.time[key_info.count_bit*2+1] = TL0;
TH0 = 0;
TL0 = 0;
TR0 = 1;//先开始下面的计数的同时执行下面的计算,将误差减到最小
key_info.value_msg[key_info.count_bit/8] = key_info.value_msg[key_info.count_bit/8] | ((unsigned char)(!IRIN) << (7-key_info.count_bit%8));
key_info.count_bit++;
if(key_info.count_bit > 320)
{
memset(&key_info.key_value , 0 , sizeof(struct KEYMSG));//清空buf
TR0 = 0;
printf("key_info.count_bit > 160\r\n");
EX0 = 1;
return;
}
}
// EX0 = 1;
}
写入红外信号帧到flash,注意写入的位置,不要和其他键值冲突了
/*******************************************************************************
* 函 数 名 :WriteKeyMsg
* 函数功能 :写入键值信息到外部存储器
* 输 入 :struct KEYMSG *key_msg 存放信息的结构体
* 输 出 :无
*******************************************************************************/
void WriteKeyMsg(struct KEYMSG *key_msg)
{
unsigned int index,length;
unsigned int start_add = (key_msg->key_value-1)*KEY_BLOCK;
unsigned char *ptemp = (unsigned char *)key_msg;
length = key_msg->count_bit*2 + 43;//减少写入时间
for(index = 0;index < length;index++)
{
X24c16WriteAdd(start_add+index,ptemp[index]);
Delayms(1);
}
}
最后要发送红外信号时,只要按下相应的键值,直接读取结构体信息就好了
/*******************************************************************************
* 函 数 名 :ReadKeyMsg
* 函数功能 :读取一个键值的信息,键值已经放到key_msg->key_value
* 输 入 :struct KEYMSG *key_msg 需要加载信息的结构体
* 输 出 :无
*******************************************************************************/
void ReadKeyMsg(struct KEYMSG *key_msg)
{
unsigned int index,length;
unsigned int start_add = (key_msg->key_value-1)*KEY_BLOCK;
unsigned char *ptemp = (unsigned char *)key_msg;
for(index = 0;index < 43;index++)
{
ptemp[index] = X24c16ReadAdd(start_add+index);
Delayms(1);
}
length = key_msg->count_bit*2;//减少读取时间
for(index = 43;index < length + 43;index++)
{
ptemp[index] = X24c16ReadAdd(start_add+index);
Delayms(1);
}
}
另外附上实际操作方法:
平台:航太电子HTM_52单片机开发板
由于存储红外信息需要较大的空间,原来的24C02改成了24C08,如果只是电视遥控,大家可以将程序改回为24C02存储
操作方法:
1、单击按键S16进入读模式,然后将被破解的遥控对着红外接收头按下按键,单片机自动记录红外信息并存储。
2、单击按键S1,将红外信息对应到按键S1上,完成信息存储和匹配
3、对着被控设备如电视单击S1,即可实现使用单片机来控制电视
如果存储芯片够大,也可以存储足够多的按键信息到单片机按键上,每个按键可以存储一个按键信息
该文章对应的工程请于这个链接下下载:基于HTM-52万能遥控破解源代码