参考文献
DS18B20的原理及实例代码(51单片机、STM32单片机)-CSDN博客
【STM32F103ZET6开发板】第3-4讲:DS18B20温度传感器
https://zhuanlan.zhihu.com/p/648424172
手把手从0到1教你做STM32+FreeRTOS智能家居--第7篇之DS18B20温度传感器
https://zhuanlan.zhihu.com/p/699162760
《STM32MP1 M4裸机HAL库开发指南》第三十二章 DS18B20数字温度传感器实验
https://blog.51cto.com/u_15046463/5889109
STM32F407开发板DS18B20应用案例
STM32F407开发板DS18B20应用案例-电子发烧友网
https://www.eeworld.com.cn/mcu/eic667937.html
DS18B20温度传感器实验
实验目的
- 了解DS18B20温度传感器的基本原理及CRC8校验。
- 掌握STM32与DS18B20单总线通信的程序设计。
实验内容
- 编写程序检测DS18B20温度值通过串口1在串口调试助手上显示。
- 编写程序检测DS18B20温度值通过RS485接口在串口调试助手上显示。
硬件设计
温度传感器
温度传感器(temperature transducer)是利用物质各种物理性质随温度变化的规律把温度转换为电量的传感器。温度传感器是温度测量仪表的核心部分,品种繁多。按测量方式可分为接触式和非接触式两大类,按照传感器材料及电子元件特性分为热电阻和热电偶两类。
测试中最常用的温度传感器有:热电偶传感器、热敏电阻传感器、铂电阻传感器(RTD)、集成(IC)温度传感器。
图1:常见温度传感器类型示例
热电偶测温的基本原理是两种不同成份的材质导体组成闭合回路,当两端存在温度梯度时,回路中就会有电流通过,此时两端之间就存在电动势——热电动势,由该原理可知热电偶的一个优势是其无需外部供电。另外,热电偶还有测温范围宽、价格便宜、适应各种大气环境等优点,但其缺点是测量精度不高,故在高精度的测量和应用中不宜使用热电偶。热电偶两种不同成份的材料连接是标准的,根据采用材料不同可分为K型热电偶、S型热电偶、E型热电偶、N型热电偶、J型热电偶等等。
热敏电阻是敏感元件的一类,热敏电阻的电阻值会随着温度的变化而改变。按照温度系数不同分为正温度系数热敏电阻(PTC)和负温度系数热敏电阻(NTC)。正温度系数热敏电阻(PTC)在温度越高时电阻值越大,负温度系数热敏电阻(NTC)在温度越高时电阻值越低,它们同属于半导体器件,被广泛应用于各种电子元器件中。热敏电阻通常在有限的温度范围内可实现较高的精度,通常是-90℃〜130℃。
铂电阻,又称为铂热电阻,它的阻值会随着温度的变化而改变。并且铂电阻阻值会随着温度的升高匀速有规律的变大。铂电阻可分为PT100和 PT1000等系列产品,PT100即表示它在0℃时阻值为100欧姆,PT1000即表示它在0℃时阻值为1000欧姆。铂电阻具有抗振动、稳定性好、准确度高、耐高压等优点,被广泛应用于医疗、电机、工业、温度计算、卫星、气象、阻值计算等高精温度设备中。
集成(IC)温度传感器是将温度传感器集成在一个芯片上、可完成温度测量及信号输出功能的专用IC。集成(IC)温度传感器的主要特点是功能单一(仅测量温度)、测温误差小、价格低、响应速度快、传输距离远、体积小、微功耗等,适合远距离测温、控测,不需要进行非线性校准,外围电路简单。集成(IC)温度传感器按输出信号类型可分为模拟集成温度传感器和数字集成温度传感器两种。
- 注:电子元器件通常都有一定的温度系数,其输出信号会随温度变化而漂移,称为“温漂”,为了减小温漂,采用一些补偿措施在一定程度上抵消或减小其输出的温漂,这就是温度补偿。
DS18B20数字温湿度传感器
DS18B20是Dallas 半导体公司推出的新一代单总线数字温湿度传感器,DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。正是这个地址序列码使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
图2:DS18B20光刻ROM的64位序列号
DS18B20主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。下面给出DS18B20传感器芯片和已封装DS18B20传感器于金属壳内的实物图。
图3:DS18B20传感器芯片和带外壳线子的DS18B20传感器实物图
- 注:艾克姆科技IK-ZET6开发板有DS18B20传感器专用接口J17,用户不需要购买带线子的DS18B20产品。
DS18B20数字温度传感器的规格参数
下面介绍下DS18B20数字温度传感器芯片的规格参数,DS18B20数字温度传感器芯片还有贴片封装的,在此不做介绍。
表1:DS18B20数字温度传感器规格参数
参数 | 规格 |
---|---|
工作电压 | 3V〜5.5V |
封装 | TO-92-3 |
测量范围 | 温度:-55〜+125℃ |
精度 | -10〜+85℃:±0.5℃ -55〜+125℃:±2℃ |
转换时间 | 9位:93.75ms 10位:187.5ms 11位:375ms 12位:750ms |
衰 减 值 | 无衰减,无需校准。 |
输出信号 | 单总线数字信号 |
引脚数 | 3个 |
- 注: DS18B20传感器转换精度可通过配置寄存器实现,默认转换精度是12位,对应转换时间是750ms。
DS18B20数字温度传感器的管脚定义
下面介绍DS18B20数字温度传感器的管脚定义,首先将DS18B20数字温度传感器的引脚号标注下。
图4:DS18B20数字温度传感器管脚号
表2:DS18B20数字温度传感器管脚定义
DS18B20管脚号 | 管脚名 | 功能描述 |
---|---|---|
1 | GND | 供电地 |
2 | DATA | 串行数据引脚 |
3 | VCC | 供电正 |
- 注:MCU的GPIO口可以和DS18B20的串行数据引脚DATA连接,但需要该引脚上接有上拉电阻方可有效采集传感器信息。
DS18B20数字温度传感器与开发板连接
IK-ZET6开发板上设计了1个DS18B20/DHT11传感器接口,该接口串行数据引脚DATA连接到STM32F103ZET6的PB1引脚上。通过单总线通信协议读取DS18B20数字温度传感器采集的数据。
图5:IK-ZET6开发板DS18B20/DHT11接口
1、工作在寄生电源下的典型接法
2、 外部供电下的典型接法
- 1个DS18B20/DHT11接口占用的单片机的引脚如下表:
表3:DS18B20/DHT11接口引脚分配
DHT11 | 引脚 | 说明 |
---|---|---|
DATA | PB1 | 独立GPIO |
- 注:独立GPIO表示开发板没有其他的电路使用这个GPIO,非独立GPIO说明开发板有其他电路用到了该GPIO。
-
软件设计
-
DS18B20数字温度传感器通信
-
和DHT11数字温湿度传感器一样,DS18B20数字温度传感器采用的也是单总线通信。单总线在前面已经有过详细讲解在此不再赘述。但不同于DHT11的校验方式,DS18B20采用的是CRC8校验方式。 -
CRC校验介绍 -
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
下面介绍下CRC校验的几个基本概念:
1、帧检验序列FCS(Frame Check Sequence):为了进行差错检验而添加的冗余码。
2、多项式模2运行:实际上是按位异或(Exclusive OR)运算,即相同为0,相异为1,也就是不考虑进位、借位的二进制加减运算。
如:10011011 + 11001010 = 01010001。
3、生成多项式(generator polynomial):当进行CRC检验时,发送方与接收方需要事先约定一个除数,即生成多项式,一般记作G(x)。生成多项式的最高位与最低位必须是1。常用的CRC码的生成多项式有:
CRC8=X^8+X^5+X^4+1
CRC-CCITT=X^16+X^12+X^5+1
CRC16=X^16+X^15+X^5+1
CRC12=X^12+X^11+X^3+X^2+1
CRC32=X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 - 注:每一个生成多项式都可以与一个代码相对应,如CRC8对应代码:100110001。
CRC8校验介绍
CRC8校验有常规编码算法和逆序CRC信息单元编码算法两种,下面将分别进行算法介绍,仅供大家参考。
- 常规编码算法
下面介绍对单个字节的CRC8常规编码算法介绍。
- #define POLYNOMIAL 0x131 //G(x) = x^8 + x^5 + x^4 + 1 = 100110001
- /*************************************************************************
- * 函 数 名: calcrc_1byte
- * 功能说明: 单字节CRC校验
- * 形 参: unsigned char abyte:待校验单字节数据
- * 返 回 值: 经CRC校验值
- *************************************************************************/
- unsigned char calcrc_1byte(unsigned char abyte)
- {
- unsigned char bit,crc_1byte;
- crc_1byte=abyte;
- for (bit = 8; bit > 0; --bit)
- {
- if (crc_1byte & 0x80) //判断最高位是否为1
- {
- crc_1byte = (crc_1byte << 1) ^ POLYNOMIAL; //最高位为1,左移一位与多项式异或
- }
- else
- {
- crc_1byte = (crc_1byte << 1); //最高位为0,直接左移一位
- }
- }
- return crc_1byte;
- }
下面介绍对多字节的CRC8常规编码算法介绍。
- #define POLYNOMIAL 0x131 //G(x) = x^8 + x^5 + x^4 + 1 = 100110001
- /***************************************************************************
- * 函 数 名: calcrc_nbyte
- * 功能说明: 多字节CRC校验
- * 形 参: unsigned char *buf:待校验数组指针 unsigned char len:校验数
- * 返 回 值: 经CRC校验值
- ***************************************************************************/
- unsigned char calcrc_nbyte(unsigned char *buf,unsigned char len)
- {
- unsigned char bit,crc_nbyte;
- crc_nbyte=0xFF;
- while(len--)
- {
- crc_nbyte ^= *buf++; //先与需要计算的数异或,再指向下一个数
- for (bit = 8; bit > 0; --bit)
- {
- if (crc_nbyte & 0x80) //判断最高位是否为1
- {
- crc_nbyte = (crc_nbyte << 1) ^ POLYNOMIAL; //最高位为1,左移一位与多项式异或
- }
- else
- {
- crc_nbyte = (crc_nbyte << 1); //最高位为0,直接左移一位
- }
- }
- }
- return crc_nbyte;
- }
- 逆序CRC信息单元编码算法
下面介绍对单个字节的逆序CRC信息单元编码算法介绍。
- #define POLYNOMIAL 0x8C //00110001反序为10001100
- /***************************************************************************
- * 函 数 名: calcrc_1byte
- * 功能说明: 单字节CRC校验
- * 形 参: unsigned char abyte:待校验单字节数据
- * 返 回 值: 经CRC校验值
- ****************************************************************************/
- unsigned char calcrc_1byte(unsigned char abyte)
- {
- unsigned char bit,crc_1byte;
- crc_1byte=abyte;
- for (bit = 8; bit > 0; --bit)
- {
- if (crc_1byte & 0x01) //判断最低位是否为1
- {
- crc_1byte = (crc_1byte >> 1) ^ POLYNOMIAL; //最低位为1,右移一位与多项式异或
- }
- else
- {
- crc_1byte = (crc_1byte >> 1); //最低位为0,直接右移一位
- }
- }
- return crc_1byte;
- }
下面介绍对多字节的逆序CRC信息单元编码算法介绍。
- #define POLYNOMIAL 0x8C //00110001反序为10001100
- /**************************************************************************
- * 函 数 名: calcrc_nbyte
- * 功能说明: 多字节CRC校验
- * 形 参: unsigned char *buf:待校验数组指针 unsigned char len:校验数
- * 返 回 值: 经CRC校验值
- **************************************************************************/
- unsigned char calcrc_nbyte(unsigned char *buf,unsigned char len)
- {
- unsigned char bit,crc_nbyte;
- crc_nbyte=0;
- while(len--)
- {
- crc_nbyte ^= *buf++; //先与需要计算的数异或,再指向下一个数
- for (bit = 8; bit > 0; --bit)
- {
- if (crc_nbyte & 0x01) //判断最低位是否为1
- {
- crc_nbyte = (crc_nbyte >> 1) ^ POLYNOMIAL; //最低位为1,右移一位与多项式异或
- }
- else
- {
- crc_nbyte = (crc_nbyte >> 1); //最低位为0,直接右移一位
- }
- }
- }
- return crc_nbyte;
- }
- 注:DS18B20生成CRC码使用的就是逆序CRC信息单元编码算法。
DS18B20数字温度传感器与MCU通信
DS18B20数字温度传感器DATA引脚用于与微处理器MCU进行单总线通信,下图给出MCU作为单总线通信的主机与DS18B20从机之间进行通信的步骤。
图6:MCU与DS18B20单总线通信步骤示意
- 注:可以将上图中的第1步到第4步理解为一个工作周期,通常大部分操作执行一个工作周期即可。而如果是读取当前温度,则需要执行两个工作周期。
- 下面给出MCU向DS18B20发送的ROM指令和RAM指令
表4:ROM指令表
序号 | 指令 | 代码 | 功能描述 |
---|---|---|---|
1 | 读ROM | 33H | 读DS18B20温度传感器ROM中的编码。 |
2 | 匹配ROM | 55H | 发出此命令后,接着发出64位ROM编码,访问单总线上与该编码相对应的DS18B20使之做出响应,为下一步读写DS18B20做准备。 |
3 | 跳过ROM | CCH | 忽略64位ROM地址,直接向DS18B20发温度变换命令。 |
4 | 搜索ROM | F0H | 用于确定挂接在同一总线上DS18B20的个数和识别64位ROM地址。为操作各器件做好准备。 |
5 | 报警芯片搜索 | ECH | 执行后,只有温度超过设定值上限或下限的片子才做出响应。 |
- 注:此处跳过ROM指令并非不发送ROM指令,这是一条特殊的指令。
表5:RAM指令表
序号 | 指令 | 代码 | 功能描述 |
---|---|---|---|
1 | 写暂存器 | 4EH | 发出向内部RAM的3、4字节写上、下限温度数据命令,紧跟该命令后是传送2字节的数据。 |
2 | 读暂存器 | BEH | 读内部RAM中9字节的内容。 |
3 | 复制暂存器 | 48H | 将RAM中第3、4字节的内容复制到EEPROM中。 |
4 | 温度变换 | 44H | 启动DS18B20进行温度变换,结果存入内部9字节RAM中。 |
5 | 重调EEPROM | B8H | 将EEPROM中内容恢复到RAM中的第3、4字节。 |
6 | 读供电方式 | B4H | 读DS18B20供电模式。寄生供电时DS18B20发送0,外接电源供电时DS18B20发送1。 |
DS18B20数字温湿度传感器接收数据计算示例
- 正温时,DS18B20温度转换计算公式如下:
图7:DS18B20正温计算公式
- 负温时,DS18B20温度转换计算公式如下:
图8:DS18B20负温计算公式
- DS18B20温度变换后暂存器中的9字节数据:
图9:DS18B20温度变换后暂存器中的9字节数据
DS18B20温度串口调试助手显示实验(串口1)
- 注:本节的实验源码是在“实验3-3-1:DHT11温湿度传感器 - 串口调试助手显示(串口1)”的基础上修改。本节对应的实验源码是:“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”。
工程需要用到的库文件
本例需要用到的c文件如下表所示,工程需要添加下表中的c文件。
表6:实验需要用到的C文件
序号 | 文件名 | 后缀 | 功能描述 |
---|---|---|---|
1 | stm32f10x_rcc | .c | 复位与时钟控制器。 |
2 | stm32f10x_gpio | .c | 通用输入输出。 |
3 | stm32f10x_usart | .c | 通用同步/异步收发器。 |
4 | misc | .c | 中断向量控制器。 |
按下图所示将需要的c文件添加到工程。
图10:在新建工程中添加所需库函数c文件
头文件引用和路径设置
- 需要引用的头文件
因为在“main.c”文件中使用了标准库和我们自己建的软件延时函数,所以需要引用下面的头文件。
- #include "stm32f10x.h"
- //delay这里报错的原因是:delay函数用汇编实现的,导致了MDK误报。
- #include "delay.h"
- 需要包含的头文件路径
本例需要包含的头文件路径如下表:
表7:头文件包含路径
序号 | 路径 | 描述 |
---|---|---|
1 | ..\Lib\F10x_FWLIB\inc | 标准库头文件路径。 |
2 | ..\User | stm32f10x_conf.h头文件在该路径,所以要包含。 |
3 | ..\User\bsp | 自建的板卡相关的驱动文件路径。 |
MDK中点击魔术棒,打开工程配置窗口,按照下图所示添加头文件包含路径。
图11:添加头文件包含路径
MCU与DS18B20传感器通信所需函数汇集
在“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”工程中有ds18b20.c文件,该文件包括了MCU单总线与DS18B20通信所用到的函数。这些函数仅是艾克姆科技根据DS18B20手册设计的函数,仅供用户参考。下表列举了这些函数。
表8:MCU与DS18B20单总线通信相关函数汇集
序号 | 函数名 | 功能描述 |
---|---|---|
1 | DS18B20_Rst | MCU发复位脉冲给DS18B20。 |
2 | DS18B20_Presence | MCU检测DS18B20返回的存在脉冲。 |
3 | DS18B20_Read_Bit | 从DS18B20读取一个位。 |
4 | DS18B20_Read_Byte | 从DS18B20读取一个字节。 |
5 | DS18B20_Write_Byte | 写一个字节到DS18B20。 |
6 | DS18B20_Init | 初始化DS18B20。 |
7 | DS18B20_Get_Temp | 从DS18B20读取温度值。 |
编写代码
首先介绍下DS18B20_Rst 函数和DS18B20_Presence 函数,因为是单总线通信,需要根据手册上对时序的要求来合理设定延时及判断脉冲长度。
代码清单:MCU发复位脉冲给DS18B20
- /*****************************************************************************
- * 描 述 : 主机给从机发送复位脉冲
- * 入 参 : 无
- * 返回值 : 无
- ****************************************************************************/
- staticvoid DS18B20_Rst(void)
- {
- DS18B20_Mode_Out_PP(); //主机设置为推挽输出
- DS18B20_DATA_OUT(LOW); //主机至少产生不少于480us的低电平复位信号
- sw_delay_us(750);
- DS18B20_DATA_OUT(HIGH); //主机在产生复位信号后,需将总线拉高
- sw_delay_us(15); //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
- }
代码清单:MCU检测DS18B20返回的存在脉冲
- /**************************************************************************
- * 描 述 : 检测从机给主机返回的存在脉冲
- * 入 参 : 无
- * 返回值 : 0:成功 1:失败
- **************************************************************************/
- static uint8_t DS18B20_Presence(void)
- {
- uint8_t pulse_time = 0;
- DS18B20_Mode_IPU(); //主机设置为上拉输入
- //等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
- //如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
- while( DS18B20_DATA_IN() && pulse_time<100 )
- {
- pulse_time++;
- sw_delay_us(1);
- }
- if( pulse_time >=100 ) //经过100us后,存在脉冲都还没有到来
- return 1; //读取失败
- else //存在脉冲及时到来
- pulse_time = 0; //清零计时变量,执行下面的代码
- //存在脉冲到来,且存在的时间不能超过240us
- //如果存在脉冲超过240us则做超时处理
- while( !DS18B20_DATA_IN() && pulse_time<240 )
- {
- pulse_time++;
- sw_delay_us(1);
- }
- if( pulse_time >=240 ) //存在脉冲到来,但存在的时间超过了240us
- return 1; //读取失败
- else //有效的存在脉冲
- return 0; //读取成功
- }
然后,在对DS18B20写ROM和RAM指令时用到DS18B20_Write_Byte函数,在读取DS18B20相关数据时用到DS18B20_Read_Byte函数。这两个函数清单如下。
代码清单:写一个字节数据到DS18B20
- /**************************************************************************
- * 描 述 : 写一个字节到DS18B20,低位先行
- * 入 参 : uint8_t
- * 返回值 : 无
- ***************************************************************************/
- void DS18B20_Write_Byte(uint8_t dat)
- {
- uint8_t i, testb;
- DS18B20_Mode_Out_PP();
- for( i=0; i<8; i++ )
- {
- testb = dat&0x01;
- dat = dat>>1;
- /* 写0和写1的时间至少要大于60us */
- if (testb)
- {
- DS18B20_DATA_OUT(LOW);
- sw_delay_us(8); //1us < 这个延时 < 15us
- DS18B20_DATA_OUT(HIGH);
- sw_delay_us(58); //58us+8us>60us
- }
- else
- {
- DS18B20_DATA_OUT(LOW);
- /* 60us < Tx 0 < 120us */
- sw_delay_us(70);
- DS18B20_DATA_OUT(HIGH);
- /* 1us < Trec(恢复时间) < 无穷大*/
- sw_delay_us(2);
- }
- }
- }
代码清单:从DS18B20读取一个字节数据
- /***********************************************************************
- * 描 述 : 从DS18B20读一个字节,低位先行
- * 入 参 : 无
- * 返回值 : uint8_t
- *************************************************************************/
- uint8_t DS18B20_Read_Byte(void)
- {
- uint8_t i, j, dat = 0;
- for(i=0; i<8; i++)
- {
- j = DS18B20_Read_Bit(); //从DS18B20读取一个bit
- dat = (dat) | (j<<i);
- }
- return dat;
- }
最后,MCU从DS18B20读取温度值(没有进行CRC校验,这样程序执行效率会高些),并且在主函数中通过串口实时显示温度信息。
代码清单:从DS18B20读取温度值
- /**************************************************************************
- * 描 述 : 从DS18B20读取温度值
- * 入 参 : 无
- * 返回值 : float
- ***************************************************************************/
- float DS18B20_Get_Temp(void)
- {
- uint8_t tpmsb, tplsb;
- short s_tem;
- float f_tem;
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_Write_Byte(0XCC); //ROM指令: 跳过 ROM
- DS18B20_Write_Byte(0X44); //RAM指令: 开始温度转换
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_Write_Byte(0XCC); //ROM指令: 跳过 ROM
- DS18B20_Write_Byte(0XBE); //RAM指令: 读温度值
- tplsb = DS18B20_Read_Byte(); //读温度值低8位
- tpmsb = DS18B20_Read_Byte(); //读温度值高8位
- s_tem = tpmsb<<8;
- s_tem = s_tem | tplsb;
- if( s_tem < 0 ) //读取的温度值是负值,代表温度是负温
- f_tem = (~s_tem+1) * 0.0625;
- else //读取的温度值是正值,代表温度是正温
- f_tem = s_tem * 0.0625;
- return f_tem;
- }
代码清单:主函数
- int main(void)
- {
- //初始化USART1并配置USART1中断优先级
- USART1_Init();
- //主循环
- while(DS18B20_Init())
- {
- printf("\r\n no ds18b20 exit \r\n"); //温度传感器初始化失败,即DS18B20_Init()值为1
- }
- printf("\r\n ds18b20 exit \r\n"); //温度传感器初始化成功,即DS18B20_Init()值为0
- for(;;)
- {
- printf("\r\n temperature %.1f\r\n",DS18B20_Get_Temp()); //实时读取温度值,并将温度值串口打印出来
- sw_delay_ms(1500); // 1.5s 读取一次温度值
- }
- }
实验步骤
- 解压“…\第3部分:标准库教程和实验源码\ 2 – 传感器实验程序\”目录下的压缩文件“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”,将解压后得到的文件夹拷贝到合适的目录,如“D\STM32F103ZET6”。
- 启动MDK5.23。
- 在MDK5中执行“Project→Open Project”打开“…\DS18B20\projec”目录下的工程“DS18B20.uvproj”。
- 点击编译按钮编译工程。注意查看编译输出栏,观察编译的结果,如果有错误,修改程序,直到编译成功为止。编译后生成的HEX文件“DS18B20.hex”位于工程目录下的“Objects”文件夹中。
- 点击下载按钮下载程序 。如果需要对程序进行仿真,点击Debug按钮,即可将程序下载到STM32F103ZET6中进行仿真。
- 程序运行后,打开串口调试助手选择正确的串口号,波特率设置为19200,数据位为8、停止位为1,可以观察到串口调试助手1.5s显示一次读取到的温度信息。
DS18B20温度串口调试助手显示实验(RS485)
- 注:本节的实验源码是在“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”的基础上修改。本节对应的实验源码是:“实验3-4-2:DS18B20温度传感器 - 串口调试助手显示(RS485)”。
工程需要用到的库文件
在使用库函数建“实验3-4-2:DS18B20温度传感器 - 串口调试助手显示(RS485)”工程时,需要用到的c文件以及添加头文件包含路径的方法与介绍“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”完全一样,在此不再赘述。
编写代码
首先ds18b20.c相关的函数与“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”的代码完全一样,在此不再赘述。
然后,在主函数中会对所使用RS485接口进行初始化,在使用RS485接口上传DS18B20温度信息时主函数代码如下。
程序清单:主函数
- int main(void)
- {
- //初始化RS485所用GPIO口及所用USART2配置
- RS485_Init();
- //使能RS485接收,关闭发送
- RS485RX;
- //主循环
- while(DS18B20_Init())
- {
- RS485TX; //使能发送,关闭接收
- sw_delay_ms(1); //延时1ms,不可省去
- printf("\r\n no ds18b20 exit \r\n"); //温度传感器初始化失败,即DS18B20_Init()值为1
- sw_delay_ms(1); //延时1ms,不可省去
- RS485RX; //使能接收,关闭发送
- }
- RS485TX; //使能发送,关闭接收
- sw_delay_ms(1); //延时1ms,不可省去
- printf("\r\n ds18b20 exit \r\n"); //温度传感器初始化成功,即DS18B20_Init()值为0
- sw_delay_ms(1); //延时1ms,不可省去
- RS485RX; //使能接收,关闭发送
- for(;;)
- {
- RS485TX; //使能发送,关闭接收
- sw_delay_ms(1); //延时1ms,不可省去
- printf("\r\n temperature %.1f\r\n",DS18B20_Get_Temp()); //实时读取温度值,并将温度值串口打印出来
- sw_delay_ms(1); //延时1ms,不可省去
- RS485RX; //使能接收,关闭发送
- sw_delay_ms(1500); // 1.5s 读取一次温度值
- }
- }
实验步骤
- 解压“…\第3部分:标准库教程和实验源码\ 2 – 传感器实验程序\”目录下的压缩文件“实验3-4-2:DS18B20温度传感器 - 串口调试助手显示(RS485)”,将解压后得到的文件夹拷贝到合适的目录,如“D\STM32F103ZET6”。
- 启动MDK5.23。
- 在MDK5中执行“Project→Open Project”打开“…\DS18B20\projec”目录下的工程“DS18B20.uvproj”。
- 点击编译按钮编译工程。注意查看编译输出栏,观察编译的结果,如果有错误,修改程序,直到编译成功为止。编译后生成的HEX文件“DS18B20.hex”位于工程目录下的“Objects”文件夹中。
- 点击下载按钮下载程序 。如果需要对程序进行仿真,点击Debug按钮,即可将程序下载到STM32F103ZET6中进行仿真。
- 程序运行后,打开串口调试助手,选择USB转RS485模块对应的串口号,波特率设置为19200,数据位为8、停止位为1,可以观察到串口调试助手1.5s显示一次读取到的温度信息。
DS18B20温度串口调试助手显示实验(CRC校验)
- 注:本节的实验源码是在“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”的基础上修改。本节对应的实验源码是:“实验3-4-3:DS18B20温度传感器 - CRC校验 - 串口调试助手显示(串口1)”。
工程需要用到的库文件
在使用库函数建“实验3-4-3:DS18B20温度传感器 - CRC校验 - 串口调试助手显示(串口1)”工程时,需要用到的c文件以及添加头文件包含路径的方法与介绍“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”完全一样,在此不再赘述。
编写代码
首先ds18b20.c相关的函数与“实验3-4-1:DS18B20温度传感器 - 串口调试助手显示(串口1)”的代码只有读取温度信息时对读取的信息进行了CRC校验,该函数的代码如下。
代码清单:CRC校验(适合DS18B20的校验算法)
- /***************************************************************************
- * 描 述 : 读温度寄存器的值(原始数据),带CRC校验。
- * 入 参 : uint8_t *buf:待校验数组指针 uint8_t size:校验数
- * 返回值 : 经CRC校验值
- ***************************************************************************/
- uint8_t dallas_crc8(uint8_t *buf, uint8_t size)
- {
- unsigned char bit,crc_nbyte;
- crc_nbyte=0;
- while(size--)
- {
- crc_nbyte ^= *buf++; //先与需要计算的数异或,再指向下一个数
- for (bit = 8; bit > 0; --bit)
- {
- if (crc_nbyte & 0x01) //判断最低位是否为1
- {
- crc_nbyte = (crc_nbyte >> 1) ^ 0x8C; //最低位为1,右移一位与多项式异或
- }
- else
- {
- crc_nbyte = (crc_nbyte >> 1); //最低位为0,直接右移一位
- }
- }
- }
- return crc_nbyte;
- }
程序清单:MCU读取DS18B20温度等信息并进行校验
- /*************************************************************************
- * 描 述 : 从DS18B20读取温度值
- * 入 参 : 无
- * 返回值 : float
- **************************************************************************/
- float DS18B20_Get_Temp(void)
- {
- uint8_t temp[8], crc;
- short s_tem;
- float f_tem;
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
- DS18B20_Write_Byte(0X44); /* 开始转换 */
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
- DS18B20_Write_Byte(0XBE); /* 读温度值 */
- temp[0] = DS18B20_Read_Byte(); /* 读温度值低字节 */
- temp[1] = DS18B20_Read_Byte(); /* 读温度值高字节 */
- temp[2] = DS18B20_Read_Byte(); /* Alarm High Byte */
- temp[3] = DS18B20_Read_Byte(); /* Alarm Low Byte */
- temp[4] = DS18B20_Read_Byte(); /* Reserved Byte 1 */
- temp[5] = DS18B20_Read_Byte(); /* Reserved Byte 2 */
- temp[6] = DS18B20_Read_Byte(); /* Count Remain Byte */
- temp[7] = DS18B20_Read_Byte(); /* Count Per degree C */
- crc = DS18B20_Read_Byte(); /* CRC校验值 */
- //对读取的前8字节进行CRC校验,所得校验值与第9字节比对
- if(crc != dallas_crc8(temp, 8))
- {
- return 0x800;
- }
- s_tem = temp[1]<<8;
- s_tem = s_tem | temp[0];
- if( s_tem < 0 ) //读取的温度值是负值,代表温度是负温
- f_tem = (~s_tem+1) * 0.0625;
- else //读取的温度值是正值,代表温度是正温
- f_tem = s_tem * 0.0625;
- return f_tem;
- }
然后,在主函数中通过串口实时显示温度信息。代码清单如下。
程序清单:主函数
- int main(void)
- {
- //初始化USART1并配置USART1中断优先级
- USART1_Init();
- //主循环
- while(DS18B20_Init())
- {
- printf("\r\n no ds18b20 exit \r\n"); //温度传感器初始化失败,即DS18B20_Init()值为1
- }
- printf("\r\n ds18b20 exit \r\n"); //温度传感器初始化成功,即DS18B20_Init()值为0
- for(;;)
- {
- printf("\r\n temperature %.1f\r\n",DS18B20_Get_Temp()); //实时读取温度值,并将温度值串口打印出来
- sw_delay_ms(1500); // 1.5s 读取一次温度值
- }
- }
实验步骤
- 解压“…\第3部分:标准库教程和实验源码\ 2 – 传感器实验程序\”目录下的压缩文件“实验3-4-3:DS18B20温度传感器 - CRC校验 - 串口调试助手显示(串口1)”,将解压后得到的文件夹拷贝到合适的目录,如“D\STM32F103ZET6”。
- 启动MDK5.23。
- 在MDK5中执行“Project→Open Project”打开“…\DS18B20\projec”目录下的工程“DS18B20.uvproj”。
- 点击编译按钮编译工程。注意查看编译输出栏,观察编译的结果,如果有错误,修改程序,直到编译成功为止。编译后生成的HEX文件“DS18B20.hex”位于工程目录下的“Objects”文件夹中。
- 点击下载按钮下载程序 。如果需要对程序进行仿真,点击Debug按钮,即可将程序下载到STM32F103ZET6中进行仿真。
- 程序运行后,打开串口调试助手,选择正确的串口号,波特率设置为19200,数据位为8、停止位为1,可以观察到串口调试助手1.5s显示一次读取到的温度信息。