返回主页 单片机教程XL2000开发板 单片机学习 自制编程器 单片机资料 软件下载 电子技术产品介绍如何购买 进入论坛

<>
如果您在使用中有任何问题请你访问51单片机学习网论坛,和更多的朋友一起讨论
yaokong.asm 遥控器测试程序按任意键试验版数码管指示灯闪烁。任意遥控器均可!
n6221.asm 为配套的红外线遥控(P3.7)显示数码管1234567890的程序 
n6221b.asm 遥控器控制显示0123456789abcdef数据保持
n6221c.asm 遥控器控制30个io的led点亮,可由此控制继电器实现家电的遥控
8路红外遥控开关控制器(可扩展为32路)
作 者:明浩 出 处:磁动力工作室

在此给出的只是一个DEMO,主要着重于单片机的应用上,安全方面请大家自行考虑增加。


论坛上有一些希望能DIY多路的红外遥控开关,我在此做了一个DOME版的,同样用我熟悉的SAA3010T的解码程序(省下了不少时间),程

序可以直接用于AT89C51或AT89C2051或相容的芯片,用2051时,P1.0,P1.1要用10K电阻上拉。使用一体化接收头时电源方面一定要做好滤波

,如用大的滤波电容使直流更加的稳定,用104(0.1uF)的小电容去掉高频等等,只有这样才能在一定程序上提高抗干扰性。在程序方面,

我这里做的很简单,用了遥控器的1-8号键做1-8的继电器控制,按一下为继电器通,再按一下为继,二次按键的间隔时间大约在1秒钟,这

样就可以避免按一次键会使继电器返复通断(按一次键的时间不定发送键值的次数也不定)。还用了遥控的电源按键,按下时所有断电器关

闭。这个电路如果使用AT89C51的话可以找到32路或更多的控制。有网友说要做兼容多遥控学习型的,我想也是可行的,那会用到IC2器件,

存储收到的数据做为学习,接收时再对比对,但是如果你的数据较多的话会造成速度慢等问题。我个人认为还是用专一的遥控器好点,比如

说你用电视遥控去遥控电视和红外开关,当你要开电视或许同时会触发到红外开关。

明浩 2004.03.28


实验的实物图
点击放大
原理图-1 点击放大(图上31脚(EA/VPP)应接+5V)
点击放大
原理图-2 点击放大


键值编码

单片机HEX文件下载:04032801_1_8COM.rar

C51源码:

/*----------------------------------------

8路红外遥控开关控制器
(SAA3010T电视遥控器)

Copyright 2004/3/27
http://www.cdle.net
http://bbs.cdle.net

All rights reserved.

明浩 E-mail: pnzwzw@163.com
pnzwzw@cdle.net

只用八路时可以用AT89C2051代替AT89C51
一体化接收头输出端拉P3.2(int0),P1为控制输出端。
可以扩展到32路或更多
输出为低电平有效
----------------------------------------*/

#include <AT89x51.h>

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<10000; de++)
P3_6 =1;
for (de=0; de<10000; de++)
P3_6 =0;
if (DT)
{
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=0xFD;
TL0=0x1E; //设定时值为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])
{
case 0xAB: //1-8键控制
P1_0 =~P1_0;
DT =1;
break;
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:
P1_7 =~P1_7;
DT =1;
break;
case 0xD2: //按关闭电源键,关闭所有继电器
P1 =0xFF;
DT =1;
break;
}
}
}
}
}

//INT0中断
void INT0Fun(void) interrupt 0 using 2
{
EX0 =0; //外部中断0关闭
ET0 =1; //定时器0中断打开
TH0=0xFD;
TL0=0x1E; //设定时值为800us

for (IRCON=0; IRCON<3; IRCON++)
IRCode[IRCON] =0;
IRCON =0;
IRCON2 =0; //计数清零

TR0 =1;//开始计数