DS18B20课后题:
负数以补码形式存在的。
如果是负数,那么S全是1,前面那些不看,我们只看最后一个S,当它是1时,那就是0x所以只要高8位大于或等于0x08,是负数。
其中s=0x40这里
上面打错了,如果不是负数,s=0,则不显示负号,如果是负数,就执行else的语句。
如何显示温度低于零?
这是错误的,所以中文手册会出错,请参考英文手册。
错的是16进制,应该是FE6F
开始红外通信
红外遥控广泛应用于家庭,体积小,抗干扰强,功能强,功耗低,成本低
开发板具有红外接收和红外发射功能
自学习通用遥控源代码以来,下载到开发板运行后,将电视遥控器按下开关键,开发板可以解码开关键代码,同时按矩阵键盘按钮,该键具有电视遥控开关键功能,断电后学习数据不会丢失,因为解码程序存储到EEPROM中,只要是NEC红外遥控器协议,开发板都可以解码,复制到开发板按键上。这是万能遥控器。
红外发射电路中使用的红外发射二极管,红外光,特殊颜色的普通光,可见光谱下,即看不见。
用单片机解码解码芯片。应用电路是随机的,比如遥控器按下后,流水灯亮了,流水灯就是应用电路。
上图右侧为集成红外接收头。U6这个器件。
1脚放大解调后输出接收到的红外信号,我们给了数据P32.方便我们编写程序解码。
您可以参考芯片手册中的电路或电路:
红外通信不如射频模块,红外光会被东西挡住。
红外通信流程:
红外发射装置:键盘编码调制,送红外发射管,然后发射。例如,我按下了它CH-,右边是相应的键值码,即45、16进制,然后编码芯片会编码、调制,然后送到发射管发射。
红外接收装置:接收信号后,放大、解调,然后输出解码芯片解码。
我们输出给P单片机解码32。
调制和解调信号是红外通信的基本原理。
将基带二进制信号调制为38.41kHz然后发出载波信号。
收到信号后,红外接收设备应恢复为我们发送的数据,即解调。目前,大多数红外接收设备都使用综合红外接收头进行解调。
调制主要是我们看到的自学式通用遥控程序,编码和调制需要单片机进行。
接下来,我们来看看编码和解码:
以我们目前的红外遥控系统为例,不需要考虑红外发射。遥控器是一个完整的红外发射器件。如果您随意按下按钮,遥控器将编码和发射按钮的值。
我们在接收端使用集成接收头,接收到信号后,将信号放大解调,输出到单片机,写程序解码。要解码,我们首先需要知道如何编码,我们NEC编码协议,要解码发出的数据,首先要了解这一点NEC协议。如果不知道遥控器(红外发射器)NEC协议的该怎么知道呢?我们可以使用示波器或逻辑分析仪通过集成接收头解调红外信号,然后分析协议。这是用逻辑分析仪分析的。
之前说调制是为了更好的传输信号,那为什么要编码呢?如果不编码,就会发生这种情况。抽屉里有空调和电视机。我用空调遥控器按下启动按钮,想打开空调,但都打开了。这是为了区分不同的机器类型,并按照一定的规则传输信号。现在不论是业余还是专业制作,都是用的编码芯片。不同的编码芯片编码协议不同。NEC是最广泛的。日本人定的。
对于空调遥控器的红外通信,红外编码通常使用遥控器中单片机的特定编码。编码协议自行定制,不同厂家的编码协议不同。但编码调制后基本为38kHz频率发射。
因此,我们也可以通过集成接收头来解调它。如果我们想知道如何解码,我们需要使用逻辑分析仪或示波器来分析编码规则。
NEC编码完成后,通常有30多个基带二进制编码要发送。空调编码后有100多个。
NEC
开始会有一段引导码,是有规定的,高电平9000微秒左右,低电平4500微秒。
只有两个8位的用户代码。它还用于区分不同的设备,如两台电视机和不同的品牌NEC协议,为了不串用,厂家的用户码就不一样了。
之后是8位数据码和数据反码,数据码是键值码,反码是验证前8位是否正确。
数据是一个一个发送的。
为了更加生动,我们通过开发板集成接收头解调遥控器发送的键值,并通过示波器捕获基带二进制码。开发板与逻辑分析仪连接。
发送和接收端的高电平至少为8~10ms就可以。
所有起码、用户码、数据码和数据反码都可以分析。
程序根据波形建立了红外接收头的输出端,解调后输出P32.有第二个功能外部中断0,可以配置在跳边缘触发,低电平触发一次。触发时,我们启动定时器。当它下次再次触发时,我们可以知道脉冲有多宽。
例如,从这个到这个,你可以知道这是多长时间的开始。然后判断0还是1,0是1.125ms宽,1约是2.25ms宽度。这样,单片机就可以充当解码芯片,解码红外遥控器的键值。
这里至少只有32位数据,空调遥控器长,100多位。
如果你告诉某个品牌的编码规则是什么,那就简单一点,不然只能一点一点分析找出规则。
解码后,您以用单片机学习键值码,按照这个规律重新编码。编码完成后,用定时器调制到38k空调可以通过红外发射头发射来遥控。
编程,接收红外信号后,通过数据NEC协议规定解码,然后让串口以9600波特率发出,用电脑串口助手显示。
写作前梳理思路:
一体化红外接收头输出端接收P32.第二个功能是外部中断0。外部中断可部中断设置为跳边模式电平触发一次。触发外部中断时,定时器开始计数。下次触发时,可以读取计时器计算的值,计算上次脉宽的持续时间。引导码按时间确认(13).5ms数据0(1)左右.125ms或者数据1(2).25ms左右)。
为了更形象,我们通过逻辑分析仪先把红外数据的波形抓出来,通过波形一边写程序一边讲解。
首先,至少从1开始触发外部中断,打开定时器,2再次触发,读取定时器的数量,计算持续时间,计算定时器的值,然后开始添加,定时器不关闭,直到下次触发外部中断,再次计算持续时间。
1 #include <reg52.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 sbit P10=P1^0; 6 uchar IRtime; ///存储检测红外高低电平的持续时间 7 uchar IRcord[4]; ///存储解码后的四个字节数据 8 uchar IRdata[33];///包括起码在内的33位数据 9 bit IRpro_ok; /// 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 ///定时器中断,每次中断需要2566次*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;//以T计算脉宽,将此时存储在数组中的脉宽 44 IRtime=0;//计数清零 45 i ;///计数脉宽存入次数自加 46 if(i==33)//i=333说已经存储了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 }