需要7个简单元器件的红外接收器,只需拿起烙铁,不需硬件编程就可以制作完成,原理图如下:
由原理图我们可知,红外接收头把接收的红外信号转换为高低电平通过串口的DSR管脚传入到PC,PC软件通过对DSR高低电平信号的时间曲线进行分析,从而获得相对应的按键信息。
红外遥控器一般采用脉宽调制的串行码,经38kHz的载频把红外信号发射出去。其编码信息一般由三部分组成:引导码、地址码和数据码。一般信号长度大约100ms左右,持续按键则重复发送(中间会有10ms以上的间歇)。
红外遥控器的接收器是基于USB的,仅支持Vista以上版本,并且不支持个人开发,不过今天它终于发挥了它应有的作用。当然用电视或VCD遥控器也是可以的)
1、由于接收到的红外信号在微秒级别中变化,对系统实时性要求较高,所以具备垃圾回收功能,实时性没有保证的C#,似乎完不成这种信号的接收功能,所以我们选择的是VC,由它实现高优先级的线程去进行信号接收。
2、由于红外遥控信号是脉宽调制的串行码,所以我们需要采集信号的宽度,显然采用一般的时钟函数来获取时间间隔是不可行的,因为精度太低,所以我们需用采用多媒体时钟和高精度计时的API函数。
3、一般我们按键持续时间为几秒钟,并且由于按键发出前有一个10ms左右的引导信号,所以我们的程序很容易判断出信号起始点,这样我们一次仅需要接收一定量的原始数据就可以完成初步信号采集工作。
4、对于我们的红外接收程序来说并不需要实际解码出红外信号到底包含了那些具体的信息,只要其能够区分出红外遥控上的各个按键就行。
5、由于红接收器是通过串口RTS管脚供电,且通过DSR传递红外信号的,所以我们的程序即使不接收数据,也要打开串口,不过仅需要处理RTS和DSR管脚的信号即可。
DIY 简易红外遥控器
在网上发现个可以 DIY的东西,和大家分享一下,一起讨论,我编译的时候 P3_6、 P2_0
的管脚出错,我估计是原作者弄错了,大家一起学习一下,看看还能拓展一些新的功能。
本系统采用 89C2051 单片机为主控 CPU,在控制家电数量不多的情况下,完全可以适
用!具体控制电路如下:
SAA3010 电视遥控器的数据码值表如下:
*****************************************************
*[开关]55D2 [静音]55D3
*[1]55AB [2]55AC [3]55AD [4]55B2
*[5]55B3 [6]55B4 [7]55B5 [8]55CA
*[9]55CB [0]55AA [单/双]55CC [调谐]5554
*[节目+]56AA [节目-]56AB [微调+]56CD [微调-]56D2
*[音量+]552A [存储]56CB [召回]55D5
*[音量-]552B [爱好]55D4 [定时]56B4
*[对比+]5552 [色彩+]5532 [亮度+]5526 [录像]564A
*[对比-]5553 [色彩-]5533 [亮度-]55D2 [电视]5655
*****************************************************
为方便叙述,本电路只连接了 CPU的 P1_4 脚。但可以根据实际需求扩展,只需有足够
的 I/O 口!
C51 程序具体如下:
/*--------------------------------------------------------------------------------------
红外遥控开关控制器
(SAA3010T 电视遥控器)
只用八路或少于八路时,可以用 AT89C2051 代替 AT89C51。
一体化接收头输出端接 P3.2(Int0),P1 为控制输出端。
P3.6接 LED 到地,可以扩展到 32 路或更多!输出为高电平有效!
-----------------------------------------------------------------------------------------*/
#include
static unsigned char data IRCode[3],IRCON,IRCON2;
static unsigned char data DT;
void main(void)
{
unsigned int de;
TMOD = 0x01; //定时器0 方式 1
EA = 1; //允许 CPU中断
IT0 = 1; //INT0 下降沿有效
EX0 = 1; //开INT0 中断
do
{
for (de=0; de<8000; de++)
P3_6 = 1; //LED 点亮
for (de=0; de<8000; de++)
P3_6 = 0; //LED 熄灭
if (DT)
{
EX0=0; //关闭外中断
for (de=0; de<30000; de++) //按键值正确后会有一个延时,防止重复按键
P3_6 = 1;
for (de=0; de<30000; de++)
P3_6 = 0;
DT = 0;
}
EX0 = 1;
}while(1);
}
//定时器 0 中断处理
void timeint(void) interrupt 1 using 2
{
TH0=0xFC; //TH0=0XFC;TL0=0XE0
TL0=0xE0; //设定时值为 800us
if (IRCON<3)
{
if (IRCON2<8) //每中断一次读一次遥控接收头的状态,每二次为遥控编码中的一个
位
{
IRCON2++;
IRCode[IRCON]=IRCode[IRCON]<<1;//每读一次放入变量中的二进制的一个
位,每次左移一位
IRCode[IRCON]=IRCode[IRCON] | P3_2; //每八次填满一个字节,一个字节存放
遥控编码 4 个位
}
else
{
IRCON++; //填满一个字节,指向下一个变量
IRCON2=0; //计数清零
}
}
else
{
TR0 = 0; //关闭定时器
ET0 = 0; //定时器 0 中断关闭
if ((IRCode[1] != 0xFF) && (IRCode[2] != 0xFF))
{
if (IRCode[1] == 0x55)
{
switch (IRCode[2]) //可根据实际情况而定,其格式为 P1_X=~P1_X;DT=1;break;
{
case 0xD3: P1 = 0X00; DT = 1; break; //开启所有的继电器!
case 0xAB: P1_0 = ~P1_0; DT = 1; break;//1-8 键控制
case 0xAC: P1_1 = ~P1_1; DT = 1; break;
case 0xAD: P1_2 = ~P1_2; DT = 1; break;
case 0xB2: P1_3 = ~P1_3; DT = 1; break;
case 0xB3: P1_4 = ~P1_4; DT = 1; break;
case 0xB4: P1_5 = ~P1_5; DT = 1; break;
case 0xB5: P1_6 = ~P1_6; DT = 1; break;
case 0xCA: P2_0 = ~P2_0; DT = 1; break;
case 0xD2: P1 = 0xFF; DT = 1; break; //按电源键,关闭所有继电器
}//switch
} }
}
}
//INT0 中断
void INT0Fun(void) interrupt 0 using 2
{
EX0 = 0; //外部中断 0 关闭
ET0 = 1; //定时器0 中断打开
TH0=0xFC;
TL0=0xE0; //设定时值为 800us
for (IRCON=0; IRCON<3; IRCON++)
IRCode[IRCON] = 0;
IRCON = 0;
IRCON2 = 0; //计数清零
TR0 = 1;//开始计数
}
附:
在做本系统时,联想到家用的调速风扇,就可以用本系统实现!现分别用 CPU的 P1_0
和 P1_1 及 P1_2 脚引出 3 个继电器,硬件电路通上。分别控制风扇的高、中、低档。但是
C51 控制程序得稍微改动一下,若不改动的话,高、中或中、低档线圈同时通电,将导致风
扇电机的烧毁!!!
硬件电路图如下:
本电路同上述相比,加了个 7 段共阳数码管显示,显示风扇相应的档数,这里当按下遥
控器的 1、2、3 键,分别显示 1、2、3。按下遥控器 OFF 键不显示!
程序方面,只需改动程序中的 CASE 语句即可,遥控的 1、2、3 键分别控制高、中、
低档,改动后的程序如下:
case 0xAB:P3=0xfe;P1=0Xf9;DT = 1;break; //1 档并显示 1
case 0xAC:P3=0xfb;P1=0Xa4; DT = 1;break;//2 档并显示 2
case 0xAD:P3=0xef;P1=0Xb0;;DT = 1;break;//3 档并显示 3
case 0xD2: P3 = 0xFF;P1=0Xff;DT = 1; break; //停止不显示
具体实物图片如下:
最后提醒大家几点:请务必注意,在接通 220V之前,确保电机线圈不能同时通电!
还有一点,因为涉及了 220V的高压,所以一定要注意人身安全!!!