ARM嵌入式学习(四) --- 入门51(DS18B20传感器的使用)

发布时间:2026/7/10 8:02:00

ARM嵌入式学习(四) --- 入门51(DS18B20传感器的使用) 一、DS18B20主要参数参数数值说明测量范围-55℃ 125℃可覆盖绝大多数工业和环境温度精度±0.5℃-10℃85℃范围内典型值全量程精度稍低分辨率可配置9~12位对应温度分辨率9位0.5℃10位0.25℃11位0.125℃12位0.0625℃默认接口单总线1-Wire线与特性仅需一根数据线外加电源和地即可通信工作电压3.0V 5.5V兼容3.3V和5V系统通信方式异步半双工主机通过严格的时序读写数据唯一ID每个芯片有64位光刻ROM编码支持同一总线上挂接多个DS18B20转换时间最大750ms12位分辨率时分辨率越低转换越快二、配置DS18B20首先根据手册示例来使用传感器这里分为主要的三步一复位---二发送命令开启温度转换 ---延时---复位----三读取数据温度看开发板原理图可以知道这个传感器的引脚是P3.7第一步写复位脉冲定义三个宏#define DQ_HIGH (P3 | (1 7)) //拉高引脚 #define DQ_DOWN (P3 ~(1 7)) //拉低引脚 #define DQ_CHECK ((P3 (1 7)) ! 0) //当前引脚电平根据手册在DS18B20的通信协议中复位脉冲由主机拉低总线480~960μs后释放后DS18B20会等待15~60μs然后主动拉低总线60~240μs作为存在脉冲Presence Pulse以此告诉主机“我准备好了可以接收命令”。示例代码// ds18b20复位 int ds18b20_reset(void) { int time 0; // 复位脉冲 DQ_DOWN; Delay10us(70); DQ_HIGH; Delay10us(6); // 等低电平到来 while (DQ_CHECK time 30) { Delay10us(1); time; } if (time 30) { return -1; } // 等高电平到来 time 0; while (!DQ_CHECK time 30) { Delay10us(1); time; } if (time 30) { return -2; } return 1; }主机发送复位脉冲主机拉低总线至少480μs这里用Delay10us(70)≈ 700μs满足要求然后释放总线拉高。DS18B20响应存在脉冲在主机释放总线后DS18B20会等待15~60μsDelay10us(6))然后主动拉低总线60~240μs表示“我存在且准备好”之后释放总线恢复高电平。这里两个循环的作用超时检测1. 第一个循环等待低电平存在脉冲开始检测总线是否被DS18B20拉低。如果一直为高电平且超时300μs说明总线上没有器件响应或器件未工作返回 -1。2. 第二个循环等待高电平存在脉冲结束检测总线是否被DS18B20释放恢复高电平。如果一直为低电平且超时说明器件异常可能卡死、损坏或干扰导致总线被持续拉低返回 -2。第二步发送命令写发送数据函数复位好后给传感器发送命令0xCC跳过rom0xBE开启温度转换根据手册看单片机如何给传感器发送数据写0时序主机将总线拉低至少60us不超过120usds18b20在60us内来采样引脚电平若是低电平则代表主机发送了bit 0主机释放总线引脚变为高电平写1时序主机将总线拉低大于1us释放总线引脚变为高电平ds18b20在45us内对引脚的电平进行采样若是高电平代表主机发送了bit 1看图写这个函数很简单注意下面的us时间即可注意_nop_是空转1us的意思位于头文件:#include intrins.h//向ds18b20发送一个字节数据 void write_dsb18b20(unsigned char dat) { int i 0; for(i 0;i 8;i) { if(dat 1)//写1 { DQ_DOWN; _nop_(); //空转1us _nop_(); DQ_HIGH; Delay10us(5); } else//写0 { DQ_DOWN; Delay10us(6); DQ_HIGH; } dat 1; } }这里的dat 1意思是从低位逐个往高位发发完一位就把该位右移发下一位第三步读取数据一样根据手册写出读0读1的电平读时序主机将总线拉低大于1us释放总线引脚呈现高电平主机再15us内对引脚电平进行采样若采到一个低电平代表ds18b20发送了bit0若采到一个高电平代表ds18b20发送了bit1//接收ds18b20一个字节数据 unsigned char read_ds18b20(void) { int i 0; unsigned char dat 0; for(i0;i8;i) { DQ_DOWN; _nop_(); _nop_(); DQ_HIGH; _nop_(); _nop_(); _nop_(); if(DQ_CHECK)//当前引脚电平为1时 { dat | (1i);//把1写入该位置i即为当前数据的第几位 } Delay10us(6); } return dat; }定义dat 0当引脚高电平时就dat | (1i)即把1写入该位置i即为当前数据的第几位引脚为低电平时不不写入默认为0这样就读到了一个字节8bit读写函数和复位都写好后就可以使用传感器了。三、使用DS18B20根据手册示例读温度函数float get_temp(void) { unsigned char temp_low 0; unsigned char temp_high 0; short temp 0; ds18b20_reset(); //复位 write_dsb18b20(0xCC); //跳过rom write_dsb18b20(0x44); //开启温度转换 Delay1ms(1000); //延时1s ds18b20_reset();//复位 write_dsb18b20(0xCC);//跳过rom write_dsb18b20(0xBE); //读取温度数据 temp_low read_ds18b20(); temp_high read_ds18b20(); temp temp_high 8; //高位字节拼接进去 temp | temp_low; //低位 return temp *0.0625;//12位分辨率 }注意1.这里的分辨率默认是12位所以读到的数据要*0.06252.开启温度转换后需要延时是手册说的这里示例代码延时的1s3.为什么要跳过ROM系统只在P3^7口上接了一个DS18B20满足“只有一个从设备”的前提条件。在这种情况下使用 0xCC 跳过繁琐的64位ROM码识别可以直接执行后续的 0x44 和 0xBE 命令效率最高。如果你的总线上挂了多个DS18B20就不能简单地用 0xCC 了那时就需要用 0x55匹配ROM命令来指定具体要跟哪一个传感器对话。4.为什么read函数调用两次会读取到温度的高低位数据当你向 DS18B20 发送了 0xBE读暂存器命令后芯片内部会做两件事将内部地址指针指向暂存器的第 0 字节温度值 LSB。进入“发送数据”模式此后主机每执行一次读时隙即调用一次 read_ds18b20()芯片就会把当前指针指向的字节发送到总线上然后将指针自动加 1指向下一个字节。所以连续调用 read_ds18b20() 两次第一次调用 → 返回指针当前指向的字节暂存器 Byte 0即温度 LSB指针 → Byte 1。第二次调用 → 返回指针当前指向的字节暂存器 Byte 1即温度 MSB指针 → Byte 2。如果你继续调用第三次、第四次……还会依次得到 TH、TL、配置寄存器等直到 9 个字节全部读完。这正是 DS18B20 协议设计的“连续读出”机制。附上存储器地址四、总结写好函数后main里面循环调用即可接收到传感器的数据这里再使用之前用到的串口模块就可以把温度数据发给电脑了。#include reg51.h #include ds18b20.h #include uart.h #include stdio.h #include delay.h int main(void) { float t 0; char ds_temp[32]; uart_init(); while (1) { t get_temp(); sprintf(ds_temp,温度为%.2f°c\r\n,t); uart_sendstr(ds_temp); } return 0; }注意这个温度get_temp是浮点型定义变量不要错了结果

相关新闻