温控就三步,第一步测温,第二步控制加热装置的开关,第三步根据PID算法从测量来的温度控制加热装置的开关,控制调节方式采用按键的方式或者蓝牙的方式,显示采用0.96寸IIC的OLED。
第一步:18b20采集温度
一.DS18B20温度传感器
1.引脚图
2.DS18B20内部结构图
主要由2部分组成:64位ROM、9字节暂存器,如图所示。
(1) 64 位ROM。它的内容是64 位序列号,它可以被看作是该DS18B20 的地址序列码,其作用是使每个DS18B20 都各不相同,这样就可以实现一根总线上挂接多个DS18B20 的目的。
(2) 9字节暂存器包含:温度传感器、上限触发TH高温报警器、下限触发TL低温报警器、高速暂存器、8位CRC产生器。
3.64位ROM结构图
8位CRC:是单总线系列器件的编码,DS18B20定义为28H。
48位序列号:是一个唯一的序列号。
8位系列码:由CRC产生器生产,作为ROM中的前56位编码的校验码。
4.9字节暂存器结构图
以上是内部9 个字节的暂存单元(包括EEPROM)。
字节0~1 是温度存储器,用来存储转换好的温度。
字节2~3 是用户用来设置最高报警和最低报警值。这个可以用软件来实现。
字节4 是配置寄存器,用来配置转换精度,让它工作在9~12 位。
字节5~7 保留位。
字节8 CRC校验位。是64位ROM中的前56位编码的校验码。由CRC发生器产生。
5.温度寄存器结构图
温度寄存器由两个字节组成,分为低8位和高8位。一共16位。
其中,第0位到第3位,存储的是温度值的小数部分。
第4位到第10位存储的是温度值的整数部分。
第11位到第15位为符号位。全0表示是正温度,全1表示是负温度。
表格中的数值,如果相应的位为1,表示存在。如果相应的位为0,表示不存在。
6.配置寄存器
精度值:
9-bit 0.5℃
10-bit 0.25℃
11-bit 0.125℃
12-bit 0.0625℃
7.温度/数据关系
注意:如果温度是一个负温度,要将读到的数据减一再取反
二.单总线协议
1.单总线通信初始化
初始化时序包括:主机发出的复位脉冲和从机发出的应答脉冲。主机通过拉低单总线480-960μs产生复位脉冲;然后由主机释放总线,并进入接收模式。主机释放总线时,会产生一由低电平跳变为高电平的上升沿,单总线器件检测到该上升沿后,延时15~60μs,接着单总线器件通过拉低总线60~240μsμ来产生应答脉冲。主机接收到从机的以应答脉冲后,说明有单总线器件在线,到此初始化完成。然后主机就可以开始对从机进行ROM命令和功能命令操作。
2.位写入时序
写时隙:当主机把数据线从逻辑高电平拉到逻辑低电平的时候,写时间隙开始。有两种写时间隙:写1的时间隙和写0时间隙。所有写时间隙必须最少持续60us,包括两个写周期间至少1us的恢复时间。DQ引脚上的电平变低后,DS18B20在一个15us到60us的时间窗口内对DQ引脚采样。如果DQ引脚是高电平,就是写1,如果DQ引脚是低电平,就是写0。主机要生成一个写1时间隙,必须把数据线拉到低电平然后释放,在写时间隙开始后的15us内允许数据线拉到高电平。主机要生成一个写0时间隙,必须把数据线拉到低电平并保持60us。
3.位读取时序
当主机把总线从高电平拉低,并保持至少1us后释放总线;并在15us内读取从DS18B20输出的数据。
4.DS18B20的ROM操作命令
用途:主要是用于选定在单总线上的DS18B20,分为5个命令
(1).读出ROM,代码为33H,用于读出DS18B20的序列号,即64位激光ROM代码。
(2).匹配ROM,代码为55H,用于识别(或选中)某一特定的DS18B20进行操作。
(3).搜索ROM,代码为F0H,用于确定总线上的节点数以及所有节点的序列号。
(4).跳过ROM,代码为CCH,当总线仅有一个DS18B20时,不需要匹配 。
(5).报警搜索,代码为ECH,主要用于鉴别和定位系统中超出程序设定的报警温度界限的节点。
三.驱动程序
1.初始化
void DS18B20_init() { DQ=1; delay_us(1); //稍作延时 DQ=0; delay_us(80); //延时480到960us DQ=1; i = 0; while(DQ) //等待DS18B20拉低总线 { delay_us(100); i++; if(i>5)//约等待>5MS { return 0;//初始化失败 } } }
2.写字节
void write_byte(uchar dat) //写一个字节 { uchar i; for(i=0;i<8;i++) { DQ=0; //每写入一位数据之前先把总线拉低1us _nop_(); DQ=dat&0x01; //取最低位写入 delay_us(10); //延时68us,持续时间最少60us DQ=1; //然后释放总线 dat=dat>>1; //从低位开始写 } delay_us(10); }
3.读字节
uchar read_byte() //读一个字节 { uchar i,dat=0; for(i=0;i<8;i++) { DQ=0; //先将总线拉低1us _nop_(); DQ=1; //然后释放总线 _nop_();_nop_(); _nop_();_nop_(); if(DQ) dat=dat|0x80; //每次读一位 dat=dat>>1; //从最低位开始读 delay_us(10); //读取完之后等待48us再接着读取下一个数 } return dat; }
4.读温度
uint read_temper () { uchar a,b; uint t=0; DS18B20_init(); delay_us(15); write_byte(0xcc); //跳过ROM操作命令 write_byte(0x44); //发送启动温度转换命令 DS18B20_init(); delay_us(15); write_byte(0xcc); //跳过ROM操作命令 write_byte(0xbe); //发送读温度寄存器命令 a=read_byte(); //先读低八位 b=read_byte(); //再读高八位 t=b; t<<=8; //左移八位 t=t|a; //t为16位的数,使高八位为b的值,低八位为a的值 return t; //返回温度值 }
5.温度转换
uint temper_change() { uint temper; float tp; temper=read_temper(); if(temper<0) //考虑负温度的情况 { temper=temper-1; temper=~temper; tp=temper*0.0625; //16位温度转换成10进制的温度 temper=tp*100+0.5; //留两个小数点,并四舍五入 } else { tp=temper*0.0625; //16位温度转换成10进制的温度 temper=tp*100+0.5; //留两个小数点,并四舍五入 } return temper; }
第二步:OLED显示
1. I2C总线是PHLIPS公司推出的一种串行总线,I2C总线只有两根双向信号线。其中一根是数据线SDA,另一根是时钟线SCL。
2. 每个接到I2C总线上的器件都有唯一的地址。发送数据到总线上的称为发送器,从总线上接收数据的器件称为接收器。
每个I2C总线上的器件的地址唯一,主机就是通过寻找唯一的地址来进行数据传输。
当主机为发送器的时候,器件接收数据,当主机为接收器的时候,器件发送数据。
然后具体发送的数据根据OLEDIIC通信手册写驱动就好了,不过网上都有现成的,没有不要根据手册重复造轮子,知道IIC通信原理就行了,在这里给大家讲一下移植的步骤:
新建.c和.h文件添加拓展路径到工程中。
这里有一个add include 点击添加.h文件的路径就好了,oled的驱动一般有三个文件oled.h配置汇总文件,oled.c配置文件,oledfont.h字库文件。网上都有示例会调用的好了,网上教程很多