原创 自制红外

2009-2-19 21:30 2521 12 12 分类: MCU/ 嵌入式
用AT89S52自制电视红外遥控器
红外遥控器发送数据时,是将二进制数据调制成一系列的脉冲信号红外发射管发射出去,红外载波为频率38KHz
的方波,红外接收端在收到38KHz的载波信号时,会输出低电平,否则输出高电平,从而可以将“时断时续”的红外光信号解调成一定周期的连续方波信号,再
经过1838一体化红外接收头解调便可以恢复出原数据信号。如图1所示

5_3_6700c73a3236197.gif
                          图1

红外接收头解调过程如图2所示

点击看大图
                                                      图2


解调后的“0”和“1”波形及单片机编码图3图4所示

5_3_91aa8590c609f82.gif
                                                        图3

5_3_7266dcc0eeabdb5.gif
                                                        图4


点击看大图


了解了红外接收头解调及遥控编码下面就可以对照图5编写编码程序了,图5是遥控按键1的一段实际编码
由9ms低电平4.5ms高电平的启始码,26位系统码,及8位数据码、8位数据反码、23ms高电平及结束码组成

电路图

点击看大图


实物图

5_3_4f9275fd94af667.gif



*****************************************以下是遥控完整程序***********************************************

/*********************************************
**项目: 自制红外电视遥控器(EE01学习板演示程序)

**作者:一线工人

**网站:电子工程师之家 www.eehome.cn

**转贴请保持代码的完整性
*********************************************/


#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
bit irout;//红外管状态
sbit ir=P1^7;//红外发射管控制脚
uint count, set_count;//中断计数,设定中断次数
bit flag,keyflag;//红外发送标志,按键标志位
uchar irsys[4]={0x1a,0xa1,0xdc,0x03};//26位系统码,最后一个字节只用2位
uchar ircode,irdata;
/**********************************************
  延时1ms
***********************************************/

void delay(uint z)//延时1ms,晶振22.1184M
  {
    uint x,y;
    for(x=z;x>0;x--)
        for(y=225;y>0;y--);
}

/**********************************************
  按键扫描
**********************************************/
 
void keyscan(void)

  uchar keytemp;
  P3=0xff;
  keytemp=P3&0x0f;
  if(keytemp!=0x0f)
    {
    delay(20);
    keytemp=P3&0x0f;
    if(keytemp!=0x0f)
    keyflag=1;//有按键标志
    switch(keytemp)
        {
        case 0x0e:irdata=27;break;//按键1对应该遥控器P+的键值
        case 0x0d:irdata=26;break;//按键2对应该遥控器P-的键值
        case 0x0b:irdata=31;break;//按键3对应该遥控器VOL+的键值
        case 0x07:irdata=30;break;//按键4对应该遥控器VOL-的键值
        }

   
    }
   
}
/*******************************************
  发送8位红外数据
*******************************************/
void sendcode_8(void)
{

  uchar i;
  for(i=0;i<8;i++)
  {
 
  set_count=28;//发送0.56ms  38k红外波(编码中的0.56ms低电平)
  flag=1;
  count=0;
  TR0=1;
  while(count<set_count);
  TR0=0;
  if(ircode&0x01)//判断红外编码最低位,1宽的高电平,0窄的高电平
  {
    set_count=120;
    }
  else
    {
      set_count=38;
    }
  flag=0;
  count=0;
  TR0=1;
  while(count<set_count);
  TR0=0;
  ircode=ircode>>1;
  }
}


/*******************************************
  发送2位红外数据
*******************************************/
void sendcode_2(void)//前26位系统码最后两位
{

  uchar i;
  for(i=0;i<2;i++)
  {
 
  set_count=28;
  flag=1;
  count=0;
  TR0=1;
  while(count<set_count);
  TR0=0;
  if(ircode&0x01)
  {
    set_count=120;
    }
  else
    {
      set_count=38;
    }
  flag=0;
  count=0;
  TR0=1;
  while(count<set_count);
  TR0=0;
  ircode=ircode>>1;
  }
}

/*******************************************
  发送红外数据
*******************************************/
void sendcode(void)
{
set_count=575;//发送9ms 38K红外光
flag=1;
count=0;
TR0=1;
while(count<set_count);
TR0=0;
set_count=320;//间隔4.5ms
flag=0;
count=0;
TR0=1;
while(count<set_count);
TR0=0;
ircode=irsys[0];//发送26位系统码的前1-8位
sendcode_8(); 
ircode=irsys[1];//发送26位系统码的前9-16位
sendcode_8();
ircode=irsys[2];//发送26位系统码的前17-24位
sendcode_8();
ircode=irsys[3];//发送26位系统码的前24-26位
sendcode_2();
ircode=irdata;//发送8位数据码
sendcode_8();
ircode=~irdata; //发送8位数据反码
sendcode_8();
set_count=28;//发送0.56ms  38k红外波(编码中的0.56ms低电平)
  flag=1;
  count=0;
  TR0=1;
  while(count<set_count);
  TR0=0;
ir=1;
delay(23);//延时23ms(编码中的23ms高电平)
set_count=575;//发送9ms  38k红外波
flag=1;
count=0;
TR0=1;
while(count<set_count);
TR0=0;
set_count=330;//间隔4.5ms
flag=0;
count=0;
TR0=1;
while(count<set_count);
TR0=0;
set_count=30;//发送0.56ms  38k红外波(编码中的0.56ms低电平)
flag=1;
count=0;
TR0=1;
while(count<set_count);
TR0=0;
ir=1;

}


/*******************************************
  定时器初始化
*******************************************/
void init_timer()
{
  EA=1;
  TMOD=0X02;//8位自动重载模式
  ET0=1;
  TH0=0XE8;//定时13us,38K红外波,晶振22.1184
  TL0=0XE8;
}

/*******************************************
  主函数
*******************************************/
void main(void)
{
  init_timer();
  count=0;
  flag=0;
  irout=1;
  while(1)
  {
    keyscan();
    if(keyflag)//若有新按键
    {
    delay(10);
    sendcode();//发送红外编码
    delay(500);
    keyflag=0;//按键标志清零
    }
 
}
}
 

/*******************************************
  定时器中断
*******************************************/

void timer0(void) interrupt 1
{
count++;
if(flag==1)
{
  irout=~irout;
}
else
  {
    irout=1;
  }
ir=irout;
}

***************************************************************************************************

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /2 下一条