打印
[牛人杂谈]

新唐Cortex—M0学习红外发射

[复制链接]
831|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

我用的是HS0038B这个接收端,而"38"代表要载波成38KHZ的意思,电路图如下:



我原来以为只要往P3.6端口写1,那红外就会发出1,太天真了,红外发射一定要载波,调制,这样抗干扰的能力才强!


沙发
玛尼玛尼哄|  楼主 | 2016-8-23 14:39 | 只看该作者
但是我当时有个问题,为什么我的接收端用成品红外发射它就是高电平和低电平,老师给我的回答:因为HS0038B里面有解调电路,你看到的信号是已经是解调好的!就因为这个原因不明白,我整整忙活了五天,等到出来的那一刹那,整个人都非常高兴,正好是周末,可以好好休息了。

使用特权

评论回复
板凳
huangcunxiake| | 2016-8-24 00:13 | 只看该作者
对的,出来的频率是解调好的,所以不需要再解码

使用特权

评论回复
地板
wahahaheihei| | 2016-8-24 00:27 | 只看该作者
这个一般可以搜索网上的使用方法,比如原理图,代码,参考参考就明白了

使用特权

评论回复
5
zhuomuniao110| | 2016-8-26 23:21 | 只看该作者
这些作为传输用的红外二极管输出的光波本来就是带频率的

使用特权

评论回复
6
yiyigirl2014| | 2016-8-26 23:24 | 只看该作者
一般用三极管驱动,以前用过

使用特权

评论回复
7
huangcunxiake| | 2016-8-27 11:41 | 只看该作者
编码过程:
(1) 二进制信号的调制
二进制信号的调制由单片机来完成,它把编码后的二进制信号调制成频率为38kHz的间断脉冲串(用定时器来完成),相当于用二进制信号的编码乘以频率为38kHz的脉冲信号得到的间断脉冲串,即是调制后用于红外发射二极管发送的信号。
(2)PPM编码
这种遥控编码具有以下特征:
1遥控编码脉冲由前导码、16 位地址码(8位地址码、8 位地址码的反码)和 16 位操作码(8 位操作码、8 位操作码的反码)组成。前导码:是一个遥控码的起始部分,由一个9ms的高电平 ( 起始码 ) 和一个4. 5ms的低电平 ( 结果码 )组成,作为接受数据的准备脉冲。
16位地址码:能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。
16 位操作码:用来执行不同的操作。
2采用脉宽调制的串行码,以脉宽为0.56ms、间隔0.56ms、周期为1.12ms的组合表示二进制的“0”;以脉宽为1.68ms、间隔0.56ms、周期为2.24ms的组合表示二进制的“1”。

使用特权

评论回复
8
huangcunxiake| | 2016-8-27 11:42 | 只看该作者
发送程序
#include <AT89X51.h>
static bit OP;        //红外发射管的亮灭控制位
static unsigned int count;       //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag;      //红外发送标志
sbit  P3_4=P3^4;
char iraddr1;  //十六位地址的第一个字节
char iraddr2;  //十六位地址的第二个字节
void SendIRdata(char p_irdata);//发送子函数
void delay();
void main(void)
{
  count = 0;
  flag = 0;       //无载波
  OP = 0;         //不亮
  P3_4 = 0;       //在后面会发现用OP赋值的
  EA = 1; //允许CPU中断
  TMOD = 0x11; //设定时器0和1为16位模式1
  ET0 = 1; //定时器0中断允许
  TH0 = 0xFF;
  TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次
  TR0 = 1;//开始计数
  iraddr1=3;//自定义的一个地址
  iraddr2=252;//地址反码
  do{
      delay();
      SendIRdata(12);
  }while(1);
}
//定时器0中断处理
void timeint(void) interrupt 1
{
  TH0=0xFF;
  TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  count++;
  if (flag==1)
  {OP=~OP; }//如果是待发送的有效数据flag=1,就在此产生载波(亮灭交变)
  else
  {OP = 0; }
  P3_4 = OP;
}
void SendIRdata(char p_irdata)     //发送数据子函数
{
  int i;
  char irdata=p_irdata;
  //发送9ms的起始码,并是载波模式有效
  endcount=223;
  flag=1;
  count=0;
  while(count<endcount);//等待中断,控制亮灭交变的总时间为9ms
  //发送4.5ms的结果码,并是载波模式无效
  endcount=117
  flag=0;
  count=0;
  do{}while(count<endcount);

  //发送十六位地址的前八位
  irdata=iraddr1;
  for(i=0;i<8;i++)
  {//一个周期里规定先以高电平开始,在以低电平结束。先发送0.56ms的38KHZ“1”的红外波(即编码中0.56ms的高电平)
     endcount=10;
     flag=1;
     count=0;
     do{}while(count<endcount);
//停止发送红外信号(即编码中的低电平)
   if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
     {endcount=41; }  //1为宽的高电平1.68ms
   else
  {endcount=15; }  //0为窄的高电平0.56ms
    flag=0;
    count=0;
    while(count<endcount);
    irdata=irdata>>1;//依次取位
  }
  //发送十六位地址的后八位
  irdata=iraddr2;    //此处已经是地址的反码
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     while(count<endcount);
     if(irdata-(irdata/2)*2)
     {endcount=41;}
     else
     {endcount=15;}
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //发送八位数据
  irdata=p_irdata;
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     while(count<endcount);
     if(irdata-(irdata/2)*2)
     { endcount=41; }
     else
     {endcount=15; }
     flag=0;
     count=0;
     do{}while(count<endcount);
     irdata=irdata>>1;
  }
  //发送八位数据的反码
  irdata=~p_irdata;      //要将数据位取反
  for(i=0;i<8;i++)
  {
     endcount=10;
     flag=1;
     count=0;
     while(count<endcount);
     if(irdata-(irdata/2)*2)
     {endcount=41; }
     else
     {endcount=15; }
     flag=0;
     count=0;
     while(count<endcount);
     irdata=irdata>>1;
  }
  endcount=10;
  flag=1;
  count=0;
  do{}while(count<endcount);
  flag=0;
}
void delay()
{
  int i,j;
  for(i=0;i<400;i++)
  {
    for(j=0;j<100;j++)
    {
    }
  }
}

使用特权

评论回复
9
huangcunxiake| | 2016-8-27 11:43 | 只看该作者
红外接收部分:
红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。为了减少干扰,采用的是价格便宜性能可靠的一体化红外接收头(HS0038,它接收红外信号频率为38kHz,周期约26us)  接收红外信号,它同时对信号进行放大、检波、整形得到 TTL电平的编码信号,再送给单片机,经单片机解码并执行去控制相关对象。
#include"reg52.h"            
#define uchar unsigned char   
#define uint  unsigned int
#include"reg52.h"            
#define uchar unsigned char   
#define uint  unsigned int
uchar ram[4]={0,0,0,0};//存放接受到的4个数据  地址码16位+按键码8位+按键码取反的8位
void delaytime(uint time) //延迟90uS
{  uchar a,b;
   for(a=time;a>0;a--)
   { for(b=40;b>0;b--); }
}
void rem()interrupt 0   //中断函数
{
  uchar ramc=0;      //定义接收了4个字节的变量
  uchar count=0;      //定义现在接收第几位变量
  uint  i=0;        //此处变量用来在下面配合连续监测9MS 内是否有高电平
  prem=1;
  for(i=0;i<1100;i++)  //以下FOR语句执行时间为8MS左右
   {
     if(prem)   //进入遥控接收程序首先进入引导码的前半部判断,即:是否有9MS左右的低电平
   return;       //引导码错误则退出 ,注意与break语句的区别
   }
  while(prem!=1);   //等待引导码的后半部 4.5 MS 高电平开始的到来。
  delaytime(50);  //延时大于4.5MS时间,跨过引导码的后半部分,来到真正遥控数据32位中
//第一位数据的0.56MS开始脉冲
for(ramc=0;ramc<4;ramc++)//循环4次接收4个字节
  {    for(count=0;count<8;count++)  //循环8次接收8位(一个字节)
   {
while(prem!=1);   //开始判断现在接收到的数据是0或者1 ,首先在这行本句话时,
//保已经进入数据的0.56MS 低电平阶段
             //等待本次接受数据的高电平的到来。
        delaytime(9);//高电平到来后,数据0 高电平最多延续0.56MS,而数据1,高电平可延续1.66MS大于0.8MS 后我们可以再判断遥控接收脚的电平。
      if(prem)     //如果这时高电平仍然在继续那么接收到的数据是1的编码
      {ram[ramc]=(ram[ramc]<<1)+1;//将目前接收到的数据位1放到对应的字节中
delaytime(11); //如果本次接受到的数据是1,那么要继续延迟1MS,这样才能跨
//下个位编码的低电平中(即是开始的0.56MS中)
      }
      else             //否则目前接收到的是数据0的编码
        ram[ramc]=ram[ramc]<<1;   //将目前接收到的数据位0放到对应的字节中     
   } //本次接收结束,进行下次位接收,此接收动作进行32次,正好完成4个字节的接收
  }
if(ram[2]!=(~(ram[3]&0x7f)))    //本次接收码的判断
  { for(i=0;i<4;i++)   //没有此对应关系则表明接收失败,清除接受到的数据
ram=0;
returned;}
main()
{
   IT0=1;              //设定INT0为边沿触发
   EX0=1;      //打开外部中断0
   EA=1;              //全局中断开关打开
   while(1)
   {
   switch(dis_num)
    {
      case  0x81: num=0; break;
    case  0xcf: num=1; break;
    case  0x92: num=2; break;
    case  0x86: num=3; break;
    case  0xcc: num=4; break;
    case  0xa4: num=5; break;
    case  0xa0: num=6; break;
    case  0x8f: num=7; break;
      case  0x80: num=8; break;
      case  0x84: num=9; break;
    case  0x88: num=10;break;
    case  0xe0: num=11;break;
    case  0xb1: num=12;break;
      case  0xc2: num=13;break;
      case  0xb0: num=14;break;
case  0xb8: num=15;break;
    }
       P2=table[num];
   P1=0x01;
   delaytime(5);
   }
}

使用特权

评论回复
10
gejigeji521| | 2016-8-27 12:41 | 只看该作者
二进制信号的调制由单片机来完成,它把编码后的二进制信号调制成频率为38kHz的间断脉冲串(用定时器来完成)

使用特权

评论回复
11
dongnanxibei| | 2016-8-27 15:07 | 只看该作者
遥控编码脉冲由前导码、16 位地址码(8位地址码、8 位地址码的反码)和 16 位操作码(8 位操作码、8 位操作码的反码)组成。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

170

主题

3053

帖子

2

粉丝