51单片机学习笔记(清翔版)(23)——红外通讯

DS18B20课后题:

负数以补码形式存在的。

如果是负数,那么S全为1,前面那些不看,我们只看最后一个S,当它为1时,那么就是0x08,所以只要高8位大于等于0x08,就是负数。

51单片机学习笔记(清翔版)(23)——红外通讯_第1张图片

其中s=0x40这里

51单片机学习笔记(清翔版)(23)——红外通讯_第2张图片

上面打错了,如果不是负数,则s=0,则不显示负号,如果是负数,就执行else的语句。

51单片机学习笔记(清翔版)(23)——红外通讯_第3张图片

温度达不到零下怎么显示呢?模拟

51单片机学习笔记(清翔版)(23)——红外通讯_第4张图片51单片机学习笔记(清翔版)(23)——红外通讯_第5张图片

这里是错的,所以中文手册会出错,要参照英文手册。

错的是16进制,应该是FE6F


开始红外通讯

红外遥控广泛用于家庭中,体积小,抗干扰强,功能强,功耗低,成本低

开发板带有红外接收和红外发射功能

自学习型万能遥控器源代码,下载到开发板运行后,拿电视机遥控器对着开发板按下开关机键,开发板就能把开关机键代码解码,同时按下矩阵键盘某个按键,这个按键就有了电视机遥控器开关机键的功能,并且断电后学习到的数据不会丢失,因为程序把解码的程序储存到EEPROM中,只要是NEC协议的红外遥控器,开发板都可以解码,复制到开发板按键上。这就是万能遥控器。

51单片机学习笔记(清翔版)(23)——红外通讯_第6张图片

51单片机学习笔记(清翔版)(23)——红外通讯_第7张图片

51单片机学习笔记(清翔版)(23)——红外通讯_第8张图片

 红外发射电路用的红外发射二极管,发红外光,特殊颜色的普通光,可见光谱之下,即眼看不到它发光。

51单片机学习笔记(清翔版)(23)——红外通讯_第9张图片

解码芯片用单片机解码。应用电路就随机了,例如遥控器按下后,流水灯亮,流水灯就是应用电路。

上图右侧为一体化红外接收头。就是U6这个器件。

1脚将接收到的红外信号放大解调后输出,我们把数据送给了P32,便于我们编写程序解码。

可参考那个电路,也可参考芯片手册的电路:

51单片机学习笔记(清翔版)(23)——红外通讯_第10张图片

红外通讯没有射频模块做的好用,红外光会被东西挡到。

红外通讯流程:

红外发射装置:键盘编码调制,送给红外发射管,然后发射出去。例如我按下了CH-,右边是对应的键值码,即45,16进制,然后编码芯片就会对它进行编码、调制,然后送给发射管,在发射出去。

51单片机学习笔记(清翔版)(23)——红外通讯_第11张图片

红外接收装置:接收到信号后,放大、解调,然后输出给解码芯片解码。

我们输出给P32,由单片机解码。

51单片机学习笔记(清翔版)(23)——红外通讯_第12张图片

信号的调制和解调是红外通讯的基本原理。

将我们要发送的数据,也就是我们说的基带二进制信号,调制为38.41kHz的载波信号,然后发射出去。

红外接收设备接收到信号后要还原为我们发射的数据,也就是解调。目前大部分红外接收设备都是用的一体化红外接收头进行解调。

调制主要是像我们看的那个自学习型万能遥控器程序,编码和调制都需要通过单片机进行。

接下来看看编码和解码:

以我们目前这红外遥控系统为例,红外发射就不用考虑了,遥控器就是一个完整的红外发射器件,任意按下某个按键,遥控器就会把这按键的值进行编码调制发射。

接收端我们用了一体化接收头,接收到信号后,把这个信号放大解调,输出给单片机,我们写程序解码。要解码我们首先要知道是如何编码的,我们遥控器使用的NEC编码协议,要解码这个发出的数据,我们要先了解这个NEC协议。如果不知道遥控器(红外发射器件)是NEC协议的该怎么知道呢?我们可以用示波器或逻辑分析仪,把红外信号通过一体化接收头解调后的信号,把编码抓出来,之后分析是哪种协议。这是用逻辑分析仪分析的。

51单片机学习笔记(清翔版)(23)——红外通讯_第13张图片

之前说了调制是为了信号更好的传输,那么为什么要编码呢?如果不编码,会出现这种情况,抽屉里有空调和电视机,我用空调的遥控器按下开机键,想打开空调,结果都打开了,这就是为了区分不同机器类型,才将信号按照一定规律进行编码传输。现在不论是业余还是专业制作,都是用的编码芯片。不同的编码芯片编码协议不同。NEC是最广泛的。日本人定的。

空调遥控器的红外通讯,红外编码通常是用遥控器内单片机特定的编码,编码协议是自己定制的,不同厂家编码协议不一样。不过编码调制后基本都在38kHz频率上发射的。

所以我们也可以通过一体化接收头,把它解调出来,要想知道如何解码,就要用逻辑分析仪或示波器抓出来,分析编码规律。

NEC的编码完成后,所要发送的基带二进制编码通常有30多位。空调编码完后有100多位。

NEC

开始会有一段引导码,是有规定的,高电平9000微秒左右,低电平4500微秒。

只有两个8位的用户码。也是为了区分不同器件,例如两台电视机,不同品牌,都使用的NEC协议,为了不串用,厂家用户码做的就不一样。

在之后就是8位数据码和数据反码,数据码就是键值码,反码是为了校验前面8位是否正确的。

数据是一位一位发送的。

为了更形象化,我们把遥控器所发送的键值,通过开发板一体化接收头解调出来后,把基带二进制码通过示波器抓出来。开发板和逻辑分析仪接好。

51单片机学习笔记(清翔版)(23)——红外通讯_第14张图片

51单片机学习笔记(清翔版)(23)——红外通讯_第15张图片

发送和接收那端,起始码高电平在8~10ms就可以。

51单片机学习笔记(清翔版)(23)——红外通讯_第16张图片

所有的起始码,用户码,数据码和数据反码都能分析出来。

程序根据波形建立起一个思路,红外接收头的输出端,解调后输出给P32,有第二功能外部中断0,可以配置在跳边沿触发,来一个低电平触发一次,触发时我们就启动定时器,在它下次再次触发时,定时器在这期间走的数,我们取出来,就能知道脉冲有多宽。

51单片机学习笔记(清翔版)(23)——红外通讯_第17张图片

比如从这到这,看到有多长就能知道这是起始码。之后是判断0还是1,0约是1.125ms宽,1约是2.25ms宽。通过这种方法让单片机充当解码芯片,把红外遥控器键值解码出来。

这里起始码后只有32位数据,空调遥控器就长了,有100多位。

  

如果有告诉是某品牌的编码规律是怎么样的,还简单一点,否则只能一点一点分析找出规律。

解码后也可以用单片机把键值码学习下来,按照这个规律重新编码,编码完成后用定时器调制到38k这频率通过红外发射头发射,就可以遥控空调。


 编程,接收到红外信号后,把数据通过NEC协议规定解码,之后让串口以9600波特率发出,用计算机串口助手显示。

 写之前在梳理下思路:

51单片机学习笔记(清翔版)(23)——红外通讯_第18张图片

一体化红外接收头输出端接到了P32,第二功能是外部中断0,可以设置外部中断为跳边沿模式,来一个低电平触发一次,触发外部中断时让定时器开始计数,当下次再触发时,就可以读取计时器所计的数值,就可以计算出上一次脉宽的持续时间,根据时间确认是引导码(13.5ms左右)、数据0(1.125ms左右)或者数据1(2.25ms左右)。

为了更形象,我们通过逻辑分析仪先把红外数据的波形抓出来,通过波形一边写程序一边讲解。

51单片机学习笔记(清翔版)(23)——红外通讯_第19张图片

先是起始码,从1这里触发外部中断,开启定时器,2这里再次触发,就把定时器走的数读取出来,计算出持续时间,并且把定时器走数的值清0,再开始加,定时器一直不关,到下一次触发外部中断,再一次计算持续时间。

  1 #include 
  2 
  3 #define uchar unsigned char
  4 #define uint  unsigned int
  5 sbit P10=P1^0;
  6 uchar IRtime;    //储存检测红外高低电平持续时间
  7 uchar IRcord[4]; //储存解码后的4个字节数据
  8 uchar IRdata[33];//包含起始码在内的33位数据
  9 bit IRpro_ok;    //解码后4个字节数据接收完成标志位
 10 bit IRok;        //33位数据接收完成标志位
 11 
 12 void init()
 13 {
 14     TMOD|=0x02;//设置定时器0工作模式2,8位自动重装
 15     TL0=TH0=0;//初始化定时器0寄存器,定时器0溢出一次时间为256个机器周期
 16     EA=1;
 17     ET0=1;
 18     TR0=1;
 19     
 20     IT0=1;//设置外部中断0跳边沿触发方式
 21     EX0=1;
 22     
 23     TMOD|=0x20;//设置定时器1工作模式2,8位自动重装
 24     TL1=TH1=0xfd;//比特率9600
 25     SM1=1;SM0=0;//设置串口工作模式1,10位异步收发
 26     TR1=1;
 27 }
 28 
 29 //定时器中断,每中断一次需要256*1.085us=277.76us(256个机器周期,晶振频率位11.0592Mhz,机器周期=12*晶振周期)
 30 void time0() interrupt 1
 31 {
 32     IRtime++;//277.76us
 33 }
 34 
 35 //外部中断0存入33次脉宽
 36 void int0() interrupt 0
 37 {
 38     static uchar i;//静态变量用于存入33次数据计数
 39     static bit startflag;//开始储存脉宽标志位
 40     if(startflag)//标志被置1则开始存储33次脉冲宽度,一位一位存
 41     {
 42         if((IRtime<53)&&(IRtime>=32))i=0;//判断引导码,如果是引导码则从起始码开始存
 43         IRdata[i]=IRtime;//以T0溢出的次数来计算脉宽把这个时间存放在数组
 44         IRtime=0;//计数清零
 45         i++;//计数脉宽存入次数自加
 46         if(i==33)//i=33就表示已经存入了33次脉宽
 47         {
 48             IRok=1;//脉宽检查完成
 49             i=0;//把脉宽计数清零准备下次存入
 50         }
 51     }
 52     else
 53     {
 54         IRtime=0;//定时器0计数清零,因为初始化时就启动了,即使没有收到红外数据也再加
 55         startflag=1;//开始处理标志位置1
 56     }
 57 }
 58 
 59 //把提取的33次脉宽解码 NEC协议
 60 void IRcordpro()
 61 {
 62     uchar i;//计数处理4个字节
 63     uchar j;//用于处理1个字节的8位数据
 64     uchar k;//用于计数处理33次脉宽
 65     k=1;//从第一位脉宽开始处理,丢掉起始码
 66     for(i=0;i<4;i++)
 67     {
 68         for(j=0;j<8;j++)
 69         {
 70             if(IRdata[k]>5)    IRcord[i]|=0x80;//如果脉宽大于数据0标准的1125us那么就判断为数据1
 71             
 72             if(j<7)    IRcord[i]>>=1;//只能移动7次,防止最后一位移出
 73             k++;//处理下一次脉宽
 74         }
 75     }
 76     IRpro_ok=1;//解码完成
 77 }
 78 
 79 void main()
 80 {
 81     uchar i;//计数串口发送字节数
 82     init();
 83     while(1)
 84     {
 85         if(IRok)//判断33次脉宽是否提取完成
 86         {
 87             IRcordpro();//根据脉宽解码出4个字节数据
 88             IRok=0;//清零脉宽检查完成标志位等待下一次脉宽检查
 89             if(IRpro_ok)//判断是否解码完成
 90             {
 91                 if(IRcord[2]==0x45)P10=!P10;//若是CH-按键则亮第一个灯
 92                 for(i=0;i<4;i++)//串口发送4个字节数据
 93                 {
 94                     SBUF=IRcord[i];//发送数据
 95                     while(!TI);//等待发送完成标志
 96                     TI=0;//清零发送完成标志位
 97                 }
 98                 IRpro_ok=0;//清零解码完成标志位
 99             }
100         }
101     }
102     
103 }

 

转载于:https://www.cnblogs.com/Lieyuanbingshi/p/10834585.html

你可能感兴趣的:(51单片机学习笔记(清翔版)(23)——红外通讯)