2022.9
网上根本找不到资料,没人免费发布,有发布也是要钱的。哎。自己研究吧。
刚买的奥克斯清芯净空调,遥控器型号YKR-T/101,这样子的,手感不错:
用USB示波器抓了波形看了一下,和标准的电视遥控红外格式是一样的,就是最普通的那种格式。
然后,发送一次是13个字节。
注意,红外信号每字节是最低位在先,LSb!
以前有STC51单片机编了一个程序抓红外,这次改进了一下,结果入了几个坑。
抓的红外信号,分析了一下13字节的含义。
倒数第二字节是表示哪个按键,但其实没什么用,主要是看前面11个字节的代码,除了屏显键是这个字节有用。
最后事个字节校验就是直接前面12字节加起来。
但最后我也是直接用固定值,即抓的13字节是什么就直接用这13字节,没有去自己生成13字节。
分析如下:[]之中的表示bit数
字节(红外信号是低比特在先) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 固定代码 | 温度减8[5]-上下吹风[3] | 左右摆风 | 未知 | 风速[3]-小时[5] | 静音[1]-强力[1]-[1]-半小时[5] | 模式[4]-[1]-睡眠[1]-[1]-光感[1] | 轻风 | 未知 | 定时开[1]-定时关[1]-开关[1]-辅热[1]-ECO[1]-清洁[1]-健康[1]-[1] | 未知 | 按键 | 校验(前面12字节直接加起来) |
风速一档,制冷,下吹风 |
|
|
|
|
|
|
|
|
|
|
|
|
|
32开 | C3 | C5 | E0 | 0 | 60 | 0 | 20表示制冷 | 0 | 0 | 20 | 0 | 45表示开关键 | 4D |
31开 | C3 | BD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 45 | 45 |
30开 | C3 | B5 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 45 | 3D |
30关 | C3 | B5 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 45 | 1D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29开 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 45 | 35 |
29关 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 45 | 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28开 | C3 | A5 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 45 | 2D |
16开 | C3 | 45 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 45 | CD |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30切到31 | C3 | BD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 40表示温度调高键 | 40 |
29切到30 | C3 | B5 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 40 | 38 |
28切到29 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 40 | 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31切到30 | C3 | B5 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 41表示温度调低键 | 39 |
30切到29 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 41 | 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29已开,风速1,下吹: |
|
|
|
|
|
|
|
|
|
|
|
|
|
开静音 | C3 | AD | E0 | 0 | 60 | 80 | 20 | 0 | 0 | 20 | 0 | 48表示静音键 | B8 |
关静音 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 48 | 38 |
开静音后,再开ECO | C3 | AD | E0 | 0 | 60 | 80 | 20 | 0 | 0 | 28 | 0 | 53表示ECO键 | CB |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
重新再来: |
|
|
|
|
|
|
|
|
|
|
|
|
|
29已开,风速1,下吹: |
|
|
|
|
|
|
|
|
|
|
|
|
|
风速切2 | C3 | AD | E0 | 0 | 40 | 0 | 20 | 0 | 0 | 20 | 0 | 44表示风速键 | 14 |
风速切3 | C3 | AD | E0 | 0 | 20 | 0 | 20 | 0 | 0 | 20 | 0 | 44 | F4 |
风速切强力 | C3 | AD | E0 | 0 | 20 | 40 | 20 | 0 | 0 | 20 | 0 | 44 | 34 |
风速切自动 | C3 | AD | E0 | 0 | A0 | 0 | 20 | 0 | 0 | 20 | 0 | 44 | 74 |
风速切1 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 44 | 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29已开,风速1,下吹: |
|
|
|
|
|
|
|
|
|
|
|
|
|
开ECO | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 53表示ECO键 | 4B |
切30度 | C3 | B5 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 40 | 40 |
切29度 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 41 | 39 |
ECO开屏显(遥控器不显示屏显) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 55 | 4D |
ECO关屏显 | 相同 |
|
|
|
|
|
|
|
|
|
|
|
|
开健康(有显示健康) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 2A | 0 | 47表示健康键 | 41 |
关健康 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 47 | 3F |
开睡眠(有显示睡眠) | C3 | AD | E0 | 0 | 60 | 0 | 24 | 0 | 0 | 28 | 0 | 4B表示睡眠键 | 47 |
关睡眠 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 4B | 43 |
开静音(有显示静音) | C3 | AD | E0 | 0 | 60 | 80 | 20 | 0 | 0 | 28 | 0 | 48表示静音键 | C0 |
关静音 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 48 | 40 |
开光感(有显示光感) | C3 | AD | E0 | 0 | 60 | 0 | 21 | 0 | 0 | 28 | 0 | 49表示光感键 | 42 |
关光感 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 49 | 41 |
开加湿(没显示加湿) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 4A表示加湿键 | 42 |
再按一次加湿 | 相同 |
|
|
|
|
|
|
|
|
|
|
|
|
消ECO | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 53 | 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29已开,风速1,下吹: |
|
|
|
|
|
|
|
|
|
|
|
|
|
开屏显(不显示屏显) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 55表示屏显键 | 45 |
消屏显 | 相同 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
下吹切全吹 | C3 | AE | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 42表示上下风键 | 33 |
全吹切上吹 | C3 | A9 | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 42 | 2E |
切上吹2 | C3 | AA | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 42 | 2F |
切上吹3 | C3 | AB | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 42 | 30 |
切上吹4 | C3 | AC | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 42 | 31 |
切下吹 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 42 | 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开左右摆 | C3 | AD | 0表示摆风 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 43表示摆风键 | 53 |
关左右摆 | C3 | AD | E0表示不摆风 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 43 | 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开轻风(轻风+风自动) | C3 | AF | E0 | 0 | A0 | 0 | 20 | 40表示轻风 | 0 | 20 | 0 | 52表示轻风键 | C4 |
关轻风(变成风自动) | C3 | AD | E0 | 0 | A0 | 0 | 20 | 0 | 0 | 20 | 0 | 52 | 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0.5小时后关 | C3 | AD | E0 | 0 | 60 | 1E | 20 | 0 | 0 | 60 | 0 | 4D表示定时键 | 9B |
取消 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 4D | 3D |
1小时后关 | C3 | AD | E0 | 0 | 61 | 0 | 20 | 0 | 0 | 60 | 0 | 4D | 7E |
取消 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 4D | 3D |
1.5小时后关 | C3 | AD | E0 | 0 | 61 | 1E | 20 | 0 | 0 | 60 | 0 | 4D | 9C |
取消 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 4D | 3D |
24小时后关 | C3 | AD | E0 | 0 | 78 | 0 | 20 | 0 | 0 | 60 | 0 | 4D | 95 |
取消 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 4D | 3D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
重新开始,关机状态 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
关机后按屏显(遥控器上没显示屏显) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 55 | 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
关机后按清洁(遥控器上有显示清洁) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 4 | 0 | 59表示清洁键 | 2D |
取消清洁 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 59 | 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
关机后按加湿(遥控器上没显示加湿) | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 4A表示加湿键 | 1A |
再按一次加湿 | 相同 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0.5小时后开 | C3 | AD | E0 | 0 | 60 | 1E | 20 | 0 | 0 | 80 | 0 | 4D | BB |
取消 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 4D | 1D |
24小时后开 | C3 | AD | E0 | 0 | 78 | 0 | 20 | 0 | 0 | 80 | 0 | 4D | B5 |
取消 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 4D | 1D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
重新开始,关机状态 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开制热29,风1,下吹,会自动开辅热 | C3 | AD | E0 | 0 | 60 | 0 | 80表示制热 | 0 | 0 | 30 | 0 | 45 | A5 |
关 | C3 | AD | E0 | 0 | 60 | 0 | 80 | 0 | 0 | 0 | 0 | 45 | 75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开制热29,风1,下吹,会自动开辅热 |
|
|
|
|
|
|
|
|
|
|
|
|
|
关辅热 | C3 | AD | E0 | 0 | 60 | 0 | 80 | 0 | 0 | 20 | 0 | 56 | A6 |
关 | C3 | AD | E0 | 0 | 60 | 0 | 80 | 0 | 0 | 0 | 0 | 45 | 75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开除湿29,风1,下吹 | C3 | AD | E0 | 0 | 60 | 0 | 40表示除湿 | 0 | 0 | 20 | 0 | 45 | 55 |
关 | C3 | AD | E0 | 0 | 60 | 0 | 40 | 0 | 0 | 0 | 0 | 45 | 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开自动,下吹,风会自动 | C3 | 5 | E0 | 0 | A0 | 0 | 0表示自动 | 0 | 0 | 20 | 0 | 45 | AD |
关 | C3 | 5 | E0 | 0 | A0 | 0 | 0 | 0 | 0 | 0 | 0 | 45 | 8D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开通风,风1,下吹 | C3 | 5 | E0 | 0 | 60 | 0 | C0表示通风 | 0 | 0 | 20 | 0 | 45 | 2D |
关 | C3 | 5 | E0 | 0 | 60 | 0 | C0 | 0 | 0 | 0 | 0 | 45 | 0D |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
关机下+按屏显键 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 0 | 0 | 55 | 25 |
开机后+按屏显 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 20 | 0 | 55 | 45 |
ECO+按屏显 | C3 | AD | E0 | 0 | 60 | 0 | 20 | 0 | 0 | 28 | 0 | 55 | 4D |
ECO+静音+按屏显 | C3 | AD | E0 | 0 | 60 | 80 | 20 | 0 | 0 | 28 | 0 | 55 | CD |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32ECO+静音 | C3 | C5 | E0 | 0 | 60 | 80 | 20 | 0 | 0 | 28 | 0 | 40 | D0 |
32ECO+静音+屏屏 | C3 | C5 | E0 | 0 | 60 | 80 | 20 | 0 | 0 | 28 | 0 | 55 | E5 |
单片机最终程序如下:
#include <STC\STC12C5A60S2.H>
#include <INTRINS.h>
//采用1T周期的STC12C5A60S2单片机,11.0592MHZ
//WXL:一体化接收头默认是输出高电平,有信号时输出低电平; 接P3.2脚 INT0中断
//WXL:这里按“低位在先”,先接收低bit,LSb!
/******************************************************************/
/* 本程序的蓝本从网上搜集,经修改并注释,万能遥控器解码成功 */
/* 晶振:11.0592MHz */
/* 整理与测试:单片机教程网 胡琴 2012.5.15 */
/************************* 说 明 *********************************/
/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */
/* 以脉宽为低电平0.565ms、间隔高电平0.56ms、周期为1.125ms的组合表示"0"; */ //即发射是高电平0.565、低电平0.56
/* 以脉宽为低电平0.565ms、间隔高电平1.685ms、周期为2.25ms的组合表示"1"。 */ //即发射是高电平0.565、低电平1.685
/* 注意:接收码的脉宽与间隔是对发射码取反的,即间隔是0.565ms */ //因为接收头是收到载波时输出低电平0!!
/* 解码后共有四个十六进制码,本程序取第三个作为识别码 */
/*******************************************************************/
#define uchar unsigned char
#define DATA_QUANTITY 13 //WXL: 定义红外要接收的字节数(根据不同遥控器来定)
uchar data IRcode[DATA_QUANTITY]; //定义一个数组用来存储代码
sbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)
//sbit P0_0=P0^0; //P0连接到 LED 上
//sbit P0_1=P0^1;
//sbit P0_2=P0^2;
void Delay700us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 8;
j = 131;
do
{
while (--j);
} while (--i);
}
void Delay500us() //@11.0592MHz
{
unsigned char i, j;
i = 6;
j = 93;
do
{
while (--j);
} while (--i);
}
void Delay50us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 135;
while (--i);
}
void Delay3500us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 38;
j = 163;
do
{
while (--j);
} while (--i);
}
/**************************延时0.6ms子程序**********************/
void Delay0_6ms(void) //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 7;
j = 112;
do
{
while (--j);
} while (--i);
}
/**************************延时0.9ms子程序**********************/
void Delay0_9ms(void) //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 10;
j = 170;
do
{
while (--j);
} while (--i);
}
/***************************延时1ms子程序**********************/
void Delay1ms(void)
{
unsigned char i, j;
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
/***************************延时4ms子程序**********************/
void Delay4ms(void)
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 44;
j = 3;
do
{
while (--j);
} while (--i);
}
/**************************** 延时子程序 ************************/
void Delay(void)
{
uchar i,j,k;
for(i=200;i>0;i--)
for(j=200;j>0;j--)
for(k=3;k>0;k--) ;
}
/******************** 中断0解码服务子程序 ********************/
void int0(void) interrupt 0 //-----红外接收头待机默认输出高电平。中断用于接到负边沿后,开始进行红外读码
{
uchar CodeTemp;
uchar i,j,k;
uchar tt,t2;
CodeTemp=0;
EA = 0;
for(k=0; k<17; k++) //注意:循环体也需要执行时间,所以增加了delay时间,造成时间不准,不能精确定位时间点! 所以不可以delay短、次数多! 要delay长,次数短!
{
Delay500us(); //WXL:500us*17=8.5ms
if (IRsignal==1) {tt=1; t2=k; goto MYOUT; } //如果中间有一次变高电平,则说明不是引导码,退出中断
}
//如果持续了8.5ms低电平,说明是引导码。 WXL:引导码是 9ms低+4.5ms高=13.5ms。 但发射器有误差,不可能正好9ms,会提前和推后,所以按共8.5ms
Delay1ms();
if (IRsignal==0) {tt=2; t2=0; goto MYOUT; } //WXL: 9.5ms时,一定是在前导码的高电平了,如果不是,则退出
for(k=0; k<7; k++)
{
Delay500us(); //WXL:500us*7=3.5ms 9.5~13ms一定是前导码的高电平
if (IRsignal==0) {tt=3; t2=k; goto MYOUT; } //如果中间有一次变低电平,则说明不是引导码,退出中断
}
Delay700us();
if (IRsignal==1) {tt=4;t2=0; goto MYOUT; } //WXL: 13.7ms时,一定是在数据的低电平的中间,如果不是,则退出
//WXL: 下面开始接收数据
for(i=0; i<DATA_QUANTITY; i++) //分别读取n个字节
{
for(j=0; j<8; j++) //每个字节8个bit的判断
{
while(IRsignal==0); //等待上升沿,此处用得很好:因为0.56ms的低电平(接收时)是代码0与1的相同部分 // WXL:因为红外头默认输出是高电平,故用while(IRsignal==0)很安全,而用while(IRsignal==1)则可能会进入死循环
Delay0_9ms(); //上升沿后0.9ms (因为0.9介于0.56与1.125之间)
if(IRsignal==1) // WXL:长高电平是1
{
Delay1ms(); //WXL:延时1ms正好落在下次的低电平中间。 上升沿后0.9ms+1ms=1.9ms
CodeTemp=CodeTemp>>1;
CodeTemp=CodeTemp | 0x80;
}
else // WXL:短高电平是0
CodeTemp=CodeTemp>>1; //右移一位,自动补"0"
}
IRcode[i]=CodeTemp;
CodeTemp=0;
}
for(i=0; i<DATA_QUANTITY; i++) //通过串口将代码发出
{
SBUF=IRcode[i];
while(!TI); //等待一个字节发送完毕
TI=0;
}
tt=0;
t2=0;
MYOUT:
Delay();
EA = 1;
SBUF=0x55;
while(!TI); //等待一个字节发送完毕
TI=0;
SBUF=0xAA;
while(!TI); //等待一个字节发送完毕
TI=0;
SBUF=tt;
while(!TI); //等待一个字节发送完毕
TI=0;
SBUF=t2;
while(!TI); //等待一个字节发送完毕
TI=0;
}
/***********************串口初始化程序*********************/
void initUart(void)
{
TMOD |= 0x20; //
SCON = 0x50; //
PCON |= 0x80; //
TH1 = 250; // 9600 bps @ 11.0592MHz
TL1 = 250;
TR1 = 1;
}
/**************************主程序*************************/
void main()
{
//P0=0XFF;
initUart();
IT0 = 1; //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)
EX0 = 1; //外部中断INT0开, (1:开, 0:关 )
EA = 1; //开所有中断 -----红外接收头待机默认输出高电平。中断用于接到负边沿后,开始进行红外读码
IRsignal=1;
Delay();
while(1)
{
}
}