这个小程序 已经很久的 事了, 2012年就做的, 天气热了 这个遥控还是管用.,,
使用coolEdit对遥控进行编码分析并使用STC51单片机进行编码发射
cooledit是一个 音频分析软件, 但通过遥控接收头 连接到音频线上 插到电脑的音频输入口, 即可观察到 接收到的红外波形, 通过对波形的分析,即可编写 和 遥控发射信号一样的 波形,再 通过红外led灯 即可代替 遥控器 遥控 空调 或者 其它电器, 写得不完善 以后有待完善.
用P1.3 按键 控制空调关闭
P1.5 按键 控制空调打开
红外发送引脚是P1.2
单片机用11.0592M
波形采用低电平发送38k载波,然后高电平不发送载波,本程序里面不发送是红外灯一直亮,但不影响对空调的控制。
而真正的空调遥控只是按键才发亮的,不按键时红外灯是不亮的。
关:地址码:10110010 01001101
其余两个码:01111011 10000100
11100000 00011111
编码按照先接收到的是低位,后接收到的是高位
所以程序发送的码字是:
关:地址码:77 178
其余两个码:222 33
7 248
开:地址码:10110010 01001101
其余两个码:00011111 11100000
01001000 10110111
开:地址码:77 178
其余两个码:248 7
18 237
以44100hz采样,使用 cooledit pro 音频软件采样得到的采样间隔(正确)
引导1:194
引导2: 196
prefix:23
one :72
zero :25
end : 233 过渡码,美的空调需要连续发两次,两次之间有大约5ms的过渡段,不发送38k载波
波形:
/* 51单片机红外遥控发码 OK */
/* */
/* */
/* TAM HANG LAUNG 2012.1.21 */
//外部中断1 2 p3.3 INT1 接红外接收器
//红外发送接口p1.2 单片机使用11.0592M晶振
#include <reg52.h>
#define uint unsigned int
static bit OP; //红外发射管的亮灭
static unsigned int count; //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag; //红外发送标志
static unsigned int begin1; //终止延时计数
static unsigned int begin2; //终止延时计数
static unsigned int prefix; //
static unsigned int one; //
static unsigned int zero; //
static unsigned int end; //
char iraddr1; //十六位地址的第一个字节
char iraddr2; //十六位地址的第二个字节 其实是iraddr1的反码
void SendIRdata(char p_irdata,char b_irdata);
void delay();
char KeyScan();
void mdelay(uint delay);
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit P1_4=P1^4;
sbit P1_5=P1^5;
void main(void)
{
count = 0;
flag = 0;
OP = 0;
P1_2 = 0;
P1_4=0;
begin1=115;
begin2=115;
prefix=12;
one=35;
zero=12;
end=118;
EA = 1; //允许CPU中断
TMOD = 0x11; //设定时器0和1为16位模式1
ET0 = 1; //定时器0中断允许
TH0 = 0xFF;
TL0 = 0xE8; //设定时值0为38K 也就是每隔26us中断一次 12M晶振用E6 11.0592M晶振时候用E8
TR0 = 1;//开始计数
iraddr1=77;
iraddr2=178;
do{
if(KeyScan()==1) //关闭空调 美的空调需要连续发送两次相同代码,
{
SendIRdata(222,7);
SendIRdata(222,7);
}
if(KeyScan()==2) //打开空调 美的空调需要连续发送两次相同代码,
{
SendIRdata(248,18);
SendIRdata(248,18);
}
// delay();
}while(1);
}
//定时器0中断处理
void timeint(void) interrupt 1
{
TH0=0xFF;
TL0=0xE8; //设定时值为38K 也就是每隔26us中断一次 12M晶振用TL0=E6 11.0592M晶振时候用TL0=E8
count++;
if (flag==1)
{
OP=~OP;
}
else
{
OP = 0;
}
P1_2 = OP;
}
void SendIRdata(char p_irdata,char b_irdata)
{
int i;
char irdata=p_irdata;
//发送4.5ms的起始码
endcount=begin1;
flag=1;
count=0;
do{}while(count<endcount);
//发送4.5ms的结果码
endcount=begin2;
flag=0;
count=0;
do{}while(count<endcount);
//发送十六位地址的前八位
irdata=iraddr1;
for(i=0;i<8;i++)
{
//先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
//停止发送红外信号(即编码中的高电平)
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=one; //1为宽的高电平
}
else
{
endcount=zero; //0为窄的高电平
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送十六位地址的后八位
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=one;
}
else
{
endcount=zero;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送前八位数据
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=one;
}
else
{
endcount=zero;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送前八位数据的反码
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=one;
}
else
{
endcount=zero;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送后八位数据
irdata=b_irdata;
for(i=0;i<8;i++)
{
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=one;
}
else
{
endcount=zero;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//发送后八位数据的反码
irdata=~b_irdata;
for(i=0;i<8;i++)
{
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{
endcount=one;
}
else
{
endcount=zero;
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
endcount=prefix;
flag=1;
count=0;
do{}while(count<endcount);
endcount=end;
flag=0;
count=0;
do{}while(count<endcount);
flag=0;
}
char KeyScan()
{
if(P1_3==0)
{
mdelay(20);
if(P1_3==0) //关闭空调
{
return 1;
}
}
if(P1_5==0) //开空调
{
mdelay(20);
if(P1_5==0)
{
return 2;
}
}
return 0;
}
/*延时子程序*/
void mdelay(uint delay)
{ uint i;
for(;delay>0;delay--)
{for(i=0;i<62;i++) //1ms延时.
{;}
}
}
void delay()
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}