最近发现一个比较浪费电的现象,很多家庭在看完电视后就直接按遥控器上的按钮关闭电视机(其实这样也是费电的,有的牌子的电视机在待机情况下的功耗可达20W,甚至更多),加上现在都是数字电视,有的人家是基本上不关机顶盒的,浪费电的情况很是严重。我自己家里看电视不太多,睡觉前也总是将电视机和机顶盒的电源关闭,电脑也总是在关机后按下总电源,不过最近连了局域网,经常是ADSL和路由器开一个晚上,夏天的话或许半夜起来关掉,但现在天越来越冷,不太高兴晚上起来关了,要想个办法才行了。
其实要想在不用的情况下完全不费电,那就只有自己起来关电源了。不过我想只要降低功耗了,那东西就值得用。
现在很多电器都是用红外遥控的,有专门的编码和解码,市场上也有卖一些万能的遥控器,可见其编码和解码有一定规则。
为了使我们在关闭电脑的电源而不影响电视机、DVD等电器的使用,就必须考虑我们的编码不能和电视机遥控器的编码有冲突。也就是说我们要自己定义编码规则。这样一来,解码也就自己要做了。单片机就成了我们最好的选择了。
现在单片机有很多种可共我们选择,51系列对初学者来说应该是比较好的选择之一,资料很多,烧写器也比较便宜。我们就用20 PIN的AT89C2051,它有15个I/O口,够了吧。现在无线发射也是比较流行的,毕竟红外是会因为遮挡而无法正常接收的,就用一个口用来无线发射,反正口多嘛,另外需要8个按键外加一个LED用来指示,这样还是有口剩余哦。
经过整理,发射的原理图如下:
TL0038是集红外线信号接收放大为一体的接收器。其中心接收频率为38KZH,输出为TTL电平,平时输出高电平,当收到码信号后,输出低电平。用来做为我们接收头正好,另外用4个口控制4个继电器,4个口控制4个LED对应指示,另再留一个无线接收的。。哈,AT98C2051的I/O口还是蛮多的。
下面是整理后的原理图:
花了点时间LAY好了板。。
发射的PCB:
接收的PCB:
这几天把板子做好了,下来逐个上传!
这次用感光板做的,线条效果比较好,下面是显影后的发射PCB这之前的工作没有拍下.可惜了)
显影后的接收PCB
再来两张腐蚀后的PCB
先说下发射的PCB,设计的时候在上面还有无线的发射线路,现在只调试红外发射部分.在调试的过程中发现,用单片机产生38KHz的频率并没有想象中那么顺利,笔者用C编译的,结果为了这个38KHz的频率也费了不少劲,后来在用示波器测了之后才调到了下图所示的频率:
如果用汇编的话可能就会剩力一些了.
再上张工作中的发射PCB
接收PCB焊好后的效果,没有焊继电器
工作时的发射和接收波形比较:
最后来张合影:
下面是发射的源程序,供大家参考..其实还有很多需要改的地方,现在发射的时间比较长,而且只是简单的发射一遍数据,没有判断是否正确的步骤,
// www.555diy.com //
// 名称:2051红外发射 //
// 版本:2051 TX 001-A //
// 日期:2008.07.06. //
// 作者;ksysl //
// 修改记录: //
// //
// I/O口功能说明
// P32 红外DATA 低电平数据发射
// P33 红外38K载波
// P37 LED指示 高电平LED亮
// P10 ~ P17 按键
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit h38k = P3^3; // 38k频率位
sbit h_data = P3^2; // 发射红外数据位
sbit led = P3^7; // LED指示位
bit key = 0 ; // 按键标志位
uchar sed_data ; // 发送的数据
uchar key_data ; // 按键判断用
void delay_ms(uchar time); // 延时
void key_scan(void); // 按键扫描
void h_data_send(void); // 红外数据发送
//*****************************************************************//
// 延时 开始
void delay_ms(uchar time)
{
uchar i,j;
for(i=0;i<20;i++)
for(j=0;j<248;j++)
for(;time>0;time--);
}
// 延时 结束
//*****************************************************************//
//*****************************************************************//
// 按键扫描开始
void key_scan(void)
{
key_data=P1&0xff;
if(key_data!=0xff)
{
delay_ms(5);
if(key_data!=0xff)
{
switch(key_data)
{
case 0xfe: key="1"; //S8
sed_data=0xfe;
break;
case 0xfd: key="1"; //S7
sed_data=0xfd;
break;
case 0xfb: key="1"; //S6
sed_data=0xfb;
break;
case 0xf7: key="1"; //S5
sed_data=0xf7;
break;
case 0xef: key="1"; //S4
sed_data=0xef;
break;
case 0xdf: key="1"; //S3
sed_data=0xdf;
break;
case 0xbf: key="1"; //S2
sed_data=0xbf;
break;
case 0x7f: key="1"; //S1
sed_data=0x7f;
break;
default : break;
}
}
}
}
// 按键扫描结束
//********************************************************************//
//********************************************************************//
// 红外数据发送开始
void h_data_send(void)
{
if(key==1) // 按键标志位
{
uchar p;
led =1; // 亮LED
h_data=0; // =0,三极管导通,让单片机开始接收数据
delay_ms(5); // 延时
for(p=0;p<8;p++) // 发送8为数据
{
h_data=(bit)(sed_data&0x80);
delay_ms(4);
sed_data<<=1;
}
}
h_data=1; // 停止发射
key=0; // 关按键标志位
led=0; // 灭LED
}
// 红外数据发送结束
//*********************************************************************//
//*********************************************************************//
// 主程序 开始
main()
{
TMOD=0x01; // 定时器0 工作方式1
TR0=1; // 开定时器中断
ET0=1;
EA=1; // 开总中断
//I/O口初始化
h38k=0; // 38K 频率
h_data=1; // 红外数据
key=0;
P1=0xff;
led=0;
while(1)
{
key_scan();
h_data_send();
}
}
// 主程序 结束
//**********************************************************************//
//**********************************************************************//
// 定时器0 产生38K频率 开始
void t0(void) interrupt 1
{
TH0=0xff; //
TL0=0xfc;
h38k=~h38k; // 38k 频率产生
}
// 定时器0 产生38K频率 结束
//**********************************************************************//
接收源程序..共大家参考..
// www.555diy.com //
// 名称:2051红外接收 //
// 版本:2051 RX 001-A //
// 日期:2008.07.06. //
// 作者;ksysl //
//修改记录: //
// //
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit int0 = P3^2; // 红外数据接收口
sbit rx = P3^7; // LED
sbit int1 = P3^3; //
sbit k1 = P1^7; // 继电器1
sbit k2 = P1^5; // 继电器2
sbit k3 = P1^3; // 继电器3
sbit k4 = P1^1; // 继电器4
sbit led1 = P1^6; // 继电器1对应LED
sbit led2 = P1^4; // 继电器2对应LED
sbit led3 = P1^2; // 继电器3对应LED
sbit led4 = P1^0; // 继电器4对应LED
uchar key; // 数据处理标志位
uchar res_data; // 接收到的红外数据
//***************************************************************//
// 延时 开始
void delay_ms(uchar time)
{
uchar i,j;
for(i=0;i<20;i++)
for(j=0;j<248;j++)
for(;time>0;time--);
}
// 延时 结束
//***************************************************************//
//***************************************************************//
// 红外数据处理 开始
void data_scan(void)
{
if(key==1)
{
switch(res_data)
{
case 0xfe: //S8
led1=1;
k1=1;
break;
case 0xfd: //S7
led1=0;
k1=0;
break;
case 0xfb: //S6
led2=1;
k2=1;
break;
case 0xf7: //S5
led2=0;
k2=0;
break;
case 0xef: //S4
led3=1;
k3=1;
break;
case 0xdf: //S3
led3=0;
k3=0;
break;
case 0xbf: //S2
led4=1;
k4=1;
break;
case 0x7f: //S1
led4=0;
k4=0;
break;
default :
break;
}
res_data=0; //清红外数据
}
delay_ms(10); //延时
rx="0"; //灭LED
key="0";
}
// 红外数据处理 结束
//********************************************************************//
//********************************************************************//
// 红外数据接收 开始
void rx_data(void)
{
uchar p="0";
res_data=0;
for(p=0;p<8;p++)
{
res_data<<=1; // 接收到的数据左移一位
if(int0==1)
{
res_data++;
}
delay_ms(4);
}
rx=0;
key=1;
}
// 红外数据接收 结束
//********************************************************************//
//********************************************************************//
// 主程序 开始
main()
{
TMOD=0x01; // 定时器0 工作方式1
TR0=1; // 开定时器中断
ET0=1;
EA=1; // 开总中断
key=0;
res_data=0;
P1=0x00; //
rx=0;
while(1)
{
data_scan();
if(int0==0)
{
rx="1";
delay_ms(5);
rx_data();
}
}
}
// 主程序 结束
//**********************************************************************//
//**********************************************************************//
// 定时器0 开始
void t0(void) interrupt 1
{
TH0=0xff; //
TL0=0xfc;
int1=~int1; //
}
// 定时器0 结束
//**********************************************************************//
如有疑问可点击http://bbs.555diy.com/dispbbs.asp?boardID=13&ID=402&page=1参与讨论.
文章评论(0条评论)
登录后参与讨论