当前位置:首页 > 单片机 > 单片机
[导读]DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的数字化温度传感器。一线总线结构具有简洁且经

DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线”接口的温度传感器。与传
统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的
数字化温度传感器。一线总线结构具有简洁且经济的特点,可使用户轻松地组建传感器网络,
从而为测量系统的构建引入全新概念,测量温度范围为-55~+125℃ ,精度为±0.5℃。现场温
度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。它能直接读出被测温度,
并且可根据实际要求通过简单的编程实现 9~l2 位的数字值读数方式。它工作在 3—5. 5 V 的电
压范围,采用多种封装形式,从而使系统设计灵活、方便,设定分辨率及用户设定的报警温度

存储在 EEPROM 中,掉电后依然保存

其内部结构如下所示

DS18B20的通讯方式是单总线的,一般而言,我们遇到的封装都是如下

其中DQ就是主要的通讯线路,对DS的读取和写入都需要主机来控制DQ线路的DQ高低电平的时间来确定,具体如下

一般而言,DQ线需要接一个上拉电阻,所以,才写操作的最后一步都需要将总线拉高


向DS写0需要总线拉低至少60US最多120US就算完成,也就是说,1-->0(持续60-120us)-->1 写入了0

像DS写入1需要总线拉低最少1us最多15US,然后总线拉高,拉高时间至少15us,一般40us以上即可 1->0(1-15us,推荐5us)-->1(持续15us以上,推荐40us)

由此可见,DS的总线采样实在总线拉低之后的15us开始的

读取DS分别为读取1和读取0,但是这两者时序是统一的

首先总线拉低至少1us,最多15us,还是选择2us,然后释放总线(也就是说进入输入模式),等待15us以上的事件,然后采样,高电平为1低电平为0

1-->0(持续2us,最多15us)-->等待15us以上60us以下-->采样总线电平,得到1或者0,记得采样完成之后切换到输出模式将总线拉高便于下一次使用


DS18B20的命令

DS1820有三个主要数字部件:1)64位激光ROM,2)温度传感器,3)非易失性温度报警触发器TH和TL



启动温度转换的命令是0X44,读取命令是0XBE

所以一般而言,对于DS的驱动包含以下几步

复位-->发 SKIP ROM 命令(0XCC)-->发开始转换命令(0X44)-->延时-->复
位-->发送 SKIP ROM 命令(0XCC)-->发读存储器命令(0XBE)-->连续读出两个字节数据(即
温度)-->结束

我们在读取的时候只读取两个字节的原因在于DS的存储器布局

前两个就是我们需要的温度,当然也可以读取全部的,扩展驱动达到其他目的


以下是驱动代码,STM32驱动代码中使用了位段操作

#ifndef__Ds18b20H#define__Ds18b20H#include"ioremap.h"#include"delay.h"#include"uart.h"//IO方向设置#defineDs18b20IO_IN(){GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH"=8<<12;}#defineDs18b20IO_OUT(){GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}////IO操作函数#defineDs18b20DQ_OUTPGout(11)//数据端口PG11#defineDs18b20DQ_INPGin(11)//数据端口PG11u8Ds18b20Init(void);//初始化DS18B20shortDs18b20GetTemp(void);//获取温度voidDs18b20Start(void);//开始温度转换voidDs18b20WriteByte(u8dat);//写入一个字节u8Ds18b20ReadByte(void);//读出一个字节u8Ds18b20ReadBit(void);//读出一个位u8Ds18b20Check(void);//检测是否存在DS18B20voidDs18b20Rst(void);//复位DS18B20voidDs18b20Show(void);#endif

#include"ds18b20.h"//复位DS18B20voidDs18b20Rst(void){Ds18b20IO_OUT();//SETPA0OUTPUTDs18b20DQ_OUT=0;//拉低DQDelayUs(750);//拉低750usDs18b20DQ_OUT=1;//DQ=1DelayUs(15);//15US}//等待DS18B20的回应//返回1:未检测到DS18B20的存在//返回0:存在u8Ds18b20Check(void){u8retry=0;Ds18b20IO_IN();//SETPA0INPUTwhile(Ds18b20DQ_IN&&retry<200){retry++;DelayUs(1);};if(retry>=200)return1;elseretry=0;while(!Ds18b20DQ_IN&&retry<240){retry++;DelayUs(1);};if(retry>=240)return1;return0;}//从DS18B20读取一个位//返回值:1/0u8Ds18b20ReadBit(void)//readonebit{u8data;Ds18b20IO_OUT();//SETPA0OUTPUTDs18b20DQ_OUT=0;DelayUs(2);Ds18b20DQ_OUT=1;Ds18b20IO_IN();//SETPA0INPUTDelayUs(12);if(Ds18b20DQ_IN)data=1;elsedata=0;DelayUs(50);returndata;}//从DS18B20读取一个字节//返回值:读到的数据u8Ds18b20ReadByte(void)//readonebyte{u8i,j,dat;dat=0;for(i=1;i<=8;i++){j=Ds18b20ReadBit();dat=(j<<7)|(dat>>1);}returndat;}//写一个字节到DS18B20//dat:要写入的字节voidDs18b20WriteByte(u8dat){u8j;u8testb;Ds18b20IO_OUT();//SETPA0OUTPUT;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb){Ds18b20DQ_OUT=0;//Write1DelayUs(2);Ds18b20DQ_OUT=1;DelayUs(60);}else{Ds18b20DQ_OUT=0;//Write0DelayUs(60);Ds18b20DQ_OUT=1;DelayUs(2);}}}//开始温度转换voidDs18b20Start(void)//ds1820startconvert{Ds18b20Rst();Ds18b20Check();Ds18b20WriteByte(0xcc);//skipromDs18b20WriteByte(0x44);//convert}//初始化DS18B20的IO口DQ同时检测DS的存在//返回1:不存在//返回0:存在u8Ds18b20Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);//使能PORTG口时钟GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;//PORTG.11推挽输出GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOG,&GPIO_InitStructure);GPIO_SetBits(GPIOG,GPIO_Pin_11);//输出1Ds18b20Rst();returnDs18b20Check();}//从ds18b20得到温度值//精度:0.1C//返回值:温度值(-550~1250)shortDs18b20GetTemp(void){u8temp;u8TL,TH;shorttem;Ds18b20Start();//ds1820startconvertDs18b20Rst();Ds18b20Check();Ds18b20WriteByte(0xcc);//skipromDs18b20WriteByte(0xbe);//convertTL=Ds18b20ReadByte();//LSBTH=Ds18b20ReadByte();//MSBif(TH>7){TH=~TH;TL=~TL;temp=0;//温度为负}elsetemp=1;//温度为正tem=TH;//获得高八位tem<<=8;tem+=TL;//获得底八位tem=(short)((float)tem*0.625);//转换if(temp)returntem;//返回温度值elsereturn-tem;}voidDs18b20Show(void){shortt=0;t=Ds18b20GetTemp();printf("ds18b20tempis%drn",t);}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在嵌入式开发中,STM32的时钟系统因其灵活性和复杂性成为开发者关注的焦点。然而,看似简单的时钟配置背后,隐藏着诸多易被忽视的陷阱,轻则导致系统不稳定,重则引发硬件损坏。本文从时钟源选择、PLL配置、总线时钟分配等关键环...

关键字: STM32 时钟系统

在嵌入式系统开发中,STM32系列微控制器的内部温度传感器因其低成本、高集成度特性,广泛应用于设备自检、环境监测等场景。然而,受芯片工艺差异和电源噪声影响,其原始数据存在±1.5℃的固有误差。本文从硬件配置、校准算法、软...

关键字: STM32 温度传感器

在能源效率与智能化需求双重驱动下,AC-DC转换器的数字控制技术正经历从传统模拟方案向全数字架构的深刻变革。基于STM32微控制器的PFM(脉冲频率调制)+PWM(脉冲宽度调制)混合调制策略,结合动态电压调整(Dynam...

关键字: AC-DC STM32

当前智能家居产品需求不断增长 ,在这一背景下 ,对现有浇花装置缺陷进行了改进 ,设计出基于STM32单片机的全 自动家用浇花机器人。该设计主要由机械结构和控制系统构成 ,机械结构通过麦克纳姆轮底盘与喷洒装置的结合实现机器...

关键字: STM32 麦克纳姆轮 安全可靠 通过性强

用c++编程似乎是让你的Arduino项目起步的障碍吗?您想要一种更直观的微控制器编程方式吗?那你需要了解一下Visuino!这个图形化编程平台将复杂电子项目的创建变成了拖动和连接块的简单任务。在本文中,我们将带您完成使...

关键字: Visuino Arduino ESP32 STM32

基于STM32与LoRa技术的无线传感网络凭借其低功耗、广覆盖、抗干扰等特性,成为环境监测、工业自动化等场景的核心解决方案。然而,如何在复杂电磁环境中实现高效休眠调度与动态信道优化,成为提升网络能效与可靠性的关键挑战。本...

关键字: STM32 LoRa

在实时控制系统、高速通信协议处理及高精度数据采集等对时间敏感的应用场景中,中断响应延迟的优化直接决定了系统的可靠性与性能上限。STM32系列微控制器凭借其灵活的嵌套向量中断控制器(NVIC)、多通道直接内存访问(DMA)...

关键字: STM32 DMA

数字电源技术向高功率密度、高效率与高动态响应方向加速演进,STM32微控制器凭借其基于DSP库的算法加速能力与对LLC谐振变换器的精准控制架构,成为优化电源动态性能的核心平台。相较于传统模拟控制或通用型数字控制器,STM...

关键字: STM32 数字电源

STM32微控制器凭借其针对电机控制场景的深度优化,成为高精度、高可靠性驱动系统的核心选择。相较于通用型MCU,STM32在电机控制领域的核心优势集中体现在FOC(磁场定向控制)算法的硬件加速引擎与PWM死区时间的动态补...

关键字: STM32 电机控制

无线充电技术加速渗透消费电子与汽车电子领域,基于Qi协议的无线充电发射端开发成为智能设备能量补给的核心课题。传统模拟控制方案存在响应滞后、参数调整困难等问题,而基于STM32的数字PID控制结合FOD(Foreign O...

关键字: STM32 无线充电
关闭