虽然流过电容MC2的电流IC有69.08mA,但在电容器上几乎不产生功耗,这是因为对于一个理想电容,流过电容的电流为虚部电流,它所作的功为无功功率。
可见,电容降压式电源的效率也很高。
经过实验测试,该电源电路通电后输出4.88V的直流电压,交流电压分量小于3mV,输出电流在50mA时,电压不低于4.7V,可以满足解码电路的电源需求。
2.2解码电路设计
智能红外遥控开关的硬件核心部分是微控制器和红外接收部分,其原理图如图3所示。
红外解码电路中的微控制器选用ATmega8L的AVR单片机。
它的工作电压为2.7~5.5V,4MHz(3V,25℃)时功耗,工作模式为3.6mA,空闲模式为1.0mA,掉电模式仅为0.5μA,采用先进的RISC结构,除了拥有8KB的系统内可编程FLASH存储器,还有512B的E2PROM,可用于记忆各类遥控器发射出的各种红外编码信号。
红外接收电路使用集成红外接收器成品,同时实现红外接收、放大、整形的功能,一般不需要任何外接元件就能完成从红外接收到输出TTL电平兼容信号的所有工作。
接收器对外只有3个引脚:
电源Vcc,公共地GND和1个脉冲信号输出OUT。
由图3可以看出,其与单片机接口非常方便。
当按下“记忆”按键S1时,红外接收头SPH开始记录遥控器发出的信号,同时将接收到的信号保存在单片机ATmega8L的E2PROM中。
以后当遥控器发出同样的红外脉冲信号时,通过红外接收头接收并与E2PROM中的数据进行对比,如果一致,就发出控制信号控制开关的通断。
3程序设计
红外遥控接收头解调出的编码是串行二进制码,包含着遥控器按键信息。
但它还不便于CPU读取识别,因此需要先对这些串行二进制码进行解码。
本设计采用的是软件解码方式对接收到的红外信号进行解码。
3.1红外遥控器发射编码简介
目前应用中的各种红外遥控系统的原理都大同小异,区别只是在于各系统的信号编码格式不同。
遥控器所产生的脉冲编码的格式一般为:
其中,引导脉冲为宽度是10ms左右的一个高脉冲和一个低脉冲的组合,用来标识指令码的开始。
识别码、键码、键码的反码均为数据编码脉冲,用二进制数表示。
“O”和“1”均由毫秒量级的高低脉冲的组合代表识别码(即用户码)是对每个遥控系统的标识。
当指令键按下时,指令信号产生电路便产生脉冲编码。
键码后面一般还要有键码的校验码,用来检验键码接收的正确性,防止误动作,增强系统的可靠性。
3.2存储编码程序设计
当按下“记忆”按键S1时,单片机进入存储记忆红外遥控编码的状态。
ATmega8L单片机首先关闭中断,等待遥控器发出的红外遥控编码输入。
当红外遥控编码输入后,单片机将其保存至E2PROM中。
这样,即使断电之后,单片机存储在E2PROM中的信息也不会丢失,可以保证断电后的正常使用。
存储红外信号的编码程序流程图如图4所示。
3.3软件解码程序设计
软件解码则由ATmega8L单片机的外部中断、定时器以及软件构成一个红外遥控接收系统。
定时器用于延时测量两个脉冲串之间的间隔。
外部中断用于当接收到红外脉冲信号时触发定时器进行数据接收。
当红外接收管接收到红外脉冲时,程序首先出发外部中断,由外部中断启动定时器,每个一段时间间隔就采样一次,并将采样到的红外脉冲编码保存到RAM变量中,然后与存储编码程序中所保存的编码进行比较,当
两者相同时则认为是按下了开关按键,进行相应的开关操作,否则程序不执行开关操作。
软件解码程序的流程图如图5所示。
4结语
目前的家用电器,如电视机、VCD、DVD和功放机等一般都配备了遥控器及智能化控制技术,给人们的使用带来了极大的方便。
随之而来的小家电如电灯的控制也在向自动化、智能化操作方面发展,这样才能满足人们的生活需求。
智能红外遥控开关充分利用了现在家用电器繁多的遥控器,实现了遥控器的功能复用,而且在软件解码红外遥控系统中,解码的核心是CPU,电路极为简单无须外围器件,体积小,抗干扰能力强。
经过实验多次测试,该开关可以替换原墙壁开关,不用再增加连线,为安装和使用提供了方便。
把原机械式墙壁换成该遥控开关不仅实用,也很安全经济。
例子一:
本实验采用延迟函数的方法来解码,采用定时器方法一样,本程序对红外遥控解码后通过液晶1602显示出来!
笔者没有写注释的习惯,所以注释较少,望读者见谅,不懂得地方可以给我留言,我们再研究探讨!
//当接收一个字节的最后一个位时,若此位位“1”,则IR的高电平时间会延长
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitRS=P3^3;
sbitRW=P3^4;
sbitE=P3^5;
sbitIR=P3^2;
ucharcodezifu[]="0123456789ABCDEF";
ucharcodemaker[]="10-07-08Jingang";
uchargao,di,addr,datas,addrf,datasf,N;
uinti,j,flag,a;
ucharIRR[4];
ucharnum[8];
voidIR_delay(ucharx) //x*0.14MS
{
for(x=0;x<0x37;x++);
}
voiddelay(uintz)//延迟z*1ms
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_comm(ucharcom)
{
RS=0;
RW=0;
E=0;
P0=com;
delay
(1);
E=1;
delay
(1);
E=0;
}
voidwrite_data(uchardatas)
{
RS=1;
RW=0;
E=0;
P0=datas;
delay
(1);
E=1;
delay
(1);
E=0;
}
voidlcdinit()
{
delay(15);//掉电15ms
write_comm(0x38);
delay(5);
write_comm(0x38);
delay(5);
write_comm(0x38);
write_comm(0x01);//清屏显示
write_comm(0x0c);
write_comm(0x04);
write_comm(0x01);
write_comm(0x80+0x00);//确定写数据的初始地址
for(i=0;i<16;i++)
{
write_data(maker[i]);
}
}
voiddisplay(uchargao,uchardi)
{
write_data(gao);
write_data(di);
write_data(0x20);
}
voidinit_interrupt()
{
EA=1;//开总中断
EX0=1;//开外部中断0
}
voidscontr()
{
while(IR==0);//索引码到来
while(IR==1);//索引码高电平
for(i=0;i<4;i++)//准备接收四个字节
{
for(j=0;j<8;j++)//接收第一个字节
{
while(IR==0);//第一个数据低电平到来到结束
while(IR==1)
{
IR_delay
(1);//延迟约0.14ms
N++;
if(N>20)//为什么若去掉这两句就只能接收一次数据
break;
}
IRR[i]=IRR[i]>>1;
if(N>=8)
{
IRR[i]=IRR[i]|0x80;
}
N=0;
}
}
EX0=1;
}
voidtestdata()
{
if(IRR[1]==0xbf)
if(IRR[2]=~IRR[3])
{
//取遥控发送的地址和键值
num[0]=IRR[0]/16;
num[1]=IRR[0]%16;
num[2]=IRR[1]/16;
num[3]=IRR[1]%16;
//以上为遥控发送的地址
num[4]=IRR[2]/16;
num[5]=IRR[2]%16;
//以上为接收到的遥控键值
num[6]=IRR[3]/16;
num[7]=IRR[3]%16;
//以上为接收到的遥控键值取反值
write_comm(0x80+0x40);
display(zifu[num[0]],zifu[num[1]]);
display(zifu[num[2]],zifu[num[3]]);
display(zifu[num[4]],zifu[num[5]]);
display(zifu[num[6]],zifu[num[7]]);
a=IRR[2];
switch(a)//分别赋予各个遥控按键的功能“点亮相应的数码管”
{
case0x00:
P2=0xfe;
break;
case0x01:
P2=0xfd;
break;
case0x02:
P2=0xfb;
break;
case0x04:
P2=0xf7;
break;
case0x05:
P2=0xef;
break;
case0x06:
P2=0xdf;
break;
default:
P2=0x00;
break;
}
}
}
voidmain()
{
N=0;
lcdinit();
init_interrupt();
while
(1)
{
if(flag==1)
{
EX0=0;
flag=0;
scontr();
while(IR==0);
testdata();
}
//EX0=1;
}
}
voidinter0()interrupt0
{
EX0=0;
flag=1;
}
例子二:
红外线遥控器软件解码原理和程序(C)
收录时间:
2010-06-1615:
08:
33 来源:
作者:
【大中小】点击:
155
红外线一开始发送一段13.5ms的引导码,引导码由9ms的高电平和4.5ms的低电平组成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放,则遥控器则发送一段重复码,重复码由9ms的高电平,2.25ms的低电平,跟着是一个短脉冲,本程序来自网络,版权归源作者所有,仅做学习交流之用!
不得用于商业目的,本程序经过试用,能解大部分遥控器的编码!
#include "at89x52.h"
#define NULL 0x00//数据无效
#define RESET 0X01//程序复位
#define REQUEST 0X02//请求信号
#define ACK 0x03//应答信号,在接收数据后发送ACK信号表示数据接收正确,
也位请求信号的应答信号
#define NACK 0x04//应答信号,表示接收数据错误
#define BUSY 0x05//忙信号,表示正在忙
#define FREE 0x06//空闲信号,表示处于空闲状态
#define READ_IR 0x0b//读取红外
#define STORE_IR 0x0c//保存数据
#define READ_KEY 0x0d//读取键值
#define RECEIVE 0Xf400//接收缓冲开始地址
#define SEND 0xfa00//发送缓冲开始地址
#define IR 0x50//红外接收缓冲开始地址
#define HEAD 0xaa//数据帧头
#define TAIL 0x55//数据帧尾
#define SDA P1_7
#define SCL P1_6
unsignedcharxdata*buf1; //接受数据缓冲
unsignedint buf1_length; //接收到的数据实际长度
unsignedcharxdata*buf2; //发送数据缓冲
unsignedint buf2_length; //要发送的数据实际长度
bitbuf1_flag; //接收标志,1表示接受到一个数据帧,0表示没有接受到数据帧或数据
帧为空
bitbuf2_flag; //发送标志,1表示需要发送或没发送完毕,0表示没有要发送的数据或
发送完毕
unsignedcharstate1,state2; //用来标志接收字符的状态,state1用来表示接
收状态,state2用来表示发送状态
unsignedchardata*ir;
union{
unsignedchara[2];
unsignedintb;
unsignedchardata*p1[2];
unsignedintdata*p2[2];
unsignedcharxdata*p3; //红外缓冲的指针
unsignedintxdata*p4;
}p;
//union{ //
// unsignedchara[2]; //
// unsignedintb;
// unsignedchardata*p1[2];
// unsignedintdata*p2[2];
// unsignedcharxdata*p3;
// unsignedintxdata*p4; //地址指针
例子五:
遥控器程序
2008年01月11日23:
23本站原创作者:
本站用户评论(0)
关键字:
遥控解码的原理:
我们知道遥控是采用38KHZ的脉冲通过红外发光二极管调制发送出去的。
我们的主
目的是怎样将从空气中传送来的遥控信息,进行解码。
对于遥控里面的最底层原理,我就不多介绍啦,网
友可以参考相关书籍。
在这里简单的说一下遥控解码的注意事项:
引导码的时间为:
13.5ms,高电平时间为9ms,低电平时间为4.5ms。
低电平时间周期为:
用L表示低L=1.125ms
高电平时间周期为:
用H表示高H=2.25ms
发送一串数据大约58.5---76.5ms
遥控码是由:
引导码、用户码、用户反码、键盘码、键盘反码几部分组成。
相关源程序:
(C语言版本)
unsignedcharth1_val=0,th1_old=0;
unsignedcharc_last=0;
unsignedcharc_bits=8;
unsignedcharc_index=0;
unsignedcharc_code,c_last1,c_last2,c_last3=0;
bitc_error=0;
#defineT_100US(F_OSC/12/10000)
#defineT_ZERO_MIN(T_100US*10)
#defineT_ZERO_MAX(T_100US*18)
#defineT_ONE_MIN(T_100US*20)
#defineT_ONE_MAX(T_100US*28)
#defineT_REP_MIN(T_100US*110)
#defineT_REP_MAX(T_100US*120)
#defineT_START_MIN(T_100US*130)
#defineT_START_MAX(T_100US*150)
#defineTH_ZERO_MIN(T_ZERO_MIN>>8)
#defineTH_ZERO_MAX(T_ZERO_MAX>>8)
#defineTH_ONE_MIN(T_ONE_MIN>>8)
#defineTH_ONE_MAX(T_ONE_MAX>>8)
#defineTH_REP_MIN(T_REP_MIN>>8)
#defineTH_REP_MAX(T_REP_MAX>>8)
#defineTH_START_MIN(T_START_MIN>>8)
#defineTH_START_MAX(T_START_MAX>>8)
#defineCODE10x0a
#defineCODE20xf5
#defineINIT_T0(65536L-(F_OSC/12)/HZ)
#defineINIT_TH0(INIT_T0>>8)
unsignedintremocnt=0;
externbitmenu1flag;
voidint0_bh(void)