历史上的今天
返回首页

历史上的今天

今天是:2026年03月21日(星期六)

正在发生

2023年03月21日 | STM32CubeMX系列 | DS18B20温度传感器

2023-03-21 来源:zhihu

1. DS18B20简介

DS18B20是由DALLAS半导体公司推出的一种单总线接口的温度传感器,与传统的热敏电阻等测温元件相比,它是一种新型的体积小、实用电压宽、与微处理器接口简单的数字化温度传感器。 DS18B20的内部结构如下图示

ROM中的64位序列号是出厂前就被光刻好的,可以看做是DS18B20的地址序列号。64位光刻ROM的排列是:8位产品类型标号+48位DS18B20序列号+8位循环冗余校验码。光刻ROM 的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20

DS18B20的内部存储器(9个字节)包括一个高速暂存器RAM和一个EEPROM,EEPROM里存放高温和低温触发器和配置寄存器,存储器详细组成见下图:

配置寄存器是配置不同的位数来确定温度和数字的转化,其结构下图示:低五位都是1,TM是测试模式位(设置工作模式或测试模式,默认为0即工作模式),R1和R0用来设置精度,可设9~12位精度,对应的温度分辨率为0.5/0.25/0.125/0.0625℃

所有的单总线器件都要求采样严格的信号时序,以保证设局的完整性。DS18B20的时序有:初始化时序、写(0和1)时序、读(0和1)时序。DS18B20发送所有的命令和数据都是字节的低位在前,下面介绍这几个信号的时序:

  • 初始化时序:单总线上的所有通讯都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us(480 ~ 960us之间),以产生复位脉冲;接着主机释放总线,外部的上拉电阻将单总线拉高,延时15 ~ 60us,并进入接收模式;接着DS18B20拉低总线60 ~ 240us,以产生低电平应答脉冲,若为低电平,再延时480us;初始化时序图如下

  • 写时序:写时序包括写0和写1时序。所有写时序至少需要60us,并且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序,主机输出低电平,延时2us,然后释放总线,延时60us;写0时序,主机输出低电平,延时60us,然后释放总线,延时2us。写时序图如下

  • 读时序:单总线器件仅在主机发出读时序时,才向主机传输数据,所以在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us,主机在读时序器件必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为,主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us

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

2. 硬件设计

D1指示灯用来提示系统运行状态,DS18B20温度传感器用来检测环境温度,串口1用来打印温度值

  • D1指示灯

  • DS18B20

  • USART1

  • TIM7(提供us延时)

3. 软件设计

3.1 STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M

  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

  • PG11设置为GPIO推挽输出模式、上拉、高速

  • 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM编程

  • 在tim.c文件下实现微秒延时(us)函数

void delay_us(uint16_t us){

    uint16_t differ = 0xffff-us-5;              

    __HAL_TIM_SET_COUNTER(&htim7,differ);   //设定TIM7计数器起始值

    HAL_TIM_Base_Start(&htim7);     //启动定时器 


    while(differ < 0xffff-5){   //判断

        differ = __HAL_TIM_GET_COUNTER(&htim7);     //查询计数器的计数值

    }

    HAL_TIM_Base_Stop(&htim7);

}

创建按键驱动文件ds18b20.c 和相关头文件ds18b20.h

void DS18B20_IO_IN(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.Pin = GPIO_PIN_11;

    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;

    HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);

}


void DS18B20_IO_OUT(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.Pin = GPIO_PIN_11;

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);

}


void DS18B20_Rst(void){

    DS18B20_IO_OUT();

    DS18B20_DQ_OUT_LOW;

    delay_us(750);

    DS18B20_DQ_OUT_HIGH;

    delay_us(15);

}


uint8_t DS18B20_Check(void){

    uint8_t retry = 0;

    DS18B20_IO_IN();

    while(DS18B20_DQ_IN && retry < 200){

        retry++;

        delay_us(1);

    }


    if(retry >= 200)

        return 1;

    else

        retry = 0;


    while(!DS18B20_DQ_IN && retry < 240){

        retry++;

        delay_us(1);

    }


    if(retry >= 240)

        return 1;


    return 0;

}


uint8_t DS18B20_Read_Bit(void){

    uint8_t data;

    DS18B20_IO_OUT();

    DS18B20_DQ_OUT_LOW;

    delay_us(2);

    DS18B20_DQ_OUT_HIGH;

    DS18B20_IO_IN();

    delay_us(12);


    if(DS18B20_DQ_IN)

        data = 1;

    else

        data = 0;


    delay_us(50);

    return data;

}


uint8_t DS18B20_Read_Byte(void){

    uint8_t i,j,data;

    data = 0;

    for(i=1;i<=8;i++){

        j = DS18B20_Read_Bit();

        data = (j<<7)|(data>>1);

    }

    return data;

}


void DS18B20_Write_Byte(uint8_t data){

    uint8_t j;

    uint8_t testb;

    DS18B20_IO_OUT();

    for(j=1;j<=8;j++){

        testb=data&0x01;

        data=data>>1;

        if(testb){

            DS18B20_DQ_OUT_LOW;

            delay_us(2);

            DS18B20_DQ_OUT_HIGH;

            delay_us(60);

        }else{

            DS18B20_DQ_OUT_LOW;

            delay_us(60);

            DS18B20_DQ_OUT_HIGH;

            delay_us(2);

        }

    }

}


void DS18B20_Start(void){

    DS18B20_Rst();

    DS18B20_Check();

    DS18B20_Write_Byte(0xcc);

    DS18B20_Write_Byte(0x44);

}


uint8_t DS18B20_Init(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.Pin = GPIO_PIN_11;

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStructure.Pull = GPIO_PULLUP;

    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);


    DS18B20_Rst();

    return DS18B20_Check();

}


short DS18B20_Get_Temperature(void){

    uint8_t temp;

    uint8_t TL,TH;

    short temperature;


    DS18B20_Start();

    DS18B20_Rst();

    DS18B20_Check();

    DS18B20_Write_Byte(0xcc);

    DS18B20_Write_Byte(0xbe);

    TL = DS18B20_Read_Byte();

    TH = DS18B20_Read_Byte();


    if(TH>7){

        TH = ~TH;

        TL = ~TL;

        temp = 0;

    }else

        temp = 1;


    temperature = TH;

    temperature <<= 8;

    temperature += TL;

    temperature = (float)temperature*0.625;

    if(temperature)

        return temperature;

    else

        return -temperature;

}

在main.c文件下编写ds18b20测试代码

int main(void){

  float temperature;

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_TIM7_Init();

  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  while(DS18B20_Init()){

    printf("DS18B20 checked failed!!!rn");

    HAL_Delay(500);

  }

  printf("DS18B20 checked success!!!rn");

  /* USER CODE END 2 */

  while (1){

    temperature = DS18B20_Get_Temperature();

        if(temperature < 0)

            printf("temperature = -%.2f degreern",temperature/10);

        else

            printf("temperature = %.2f degreern",temperature/10);


        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);

        HAL_Delay(200);

  }

}

4. 下载验证

编译无误下载到开发板后,可以看到D1指示灯不断闪烁,串口不断打印出当前温度值


推荐阅读

史海拾趣

承兴(CX)公司的发展小趣事

进入21世纪,承兴公司不满足于现状,开始寻求跨界合作的机会。2000年,承兴成为诺基亚中国区合作伙伴,共同推出了一系列定制化的电子产品。这一合作不仅提升了承兴的品牌影响力,也为其带来了更多的商业机会。随后,承兴还与中国石油、建设银行等大型企业和金融机构建立了合作关系,进一步拓展了其业务范围。

Abbotec Incorporated公司的发展小趣事

随着电子行业的快速发展,市场竞争日益激烈。Abbotec在面对市场变革时,果断进行了战略调整。公司加大了对新兴技术的研发投入,同时优化了生产流程,降低了成本。这些措施使得Abbotec在激烈的市场竞争中保持了稳健的发展态势。

Hirose Electric公司的发展小趣事

在追求经济效益的同时,Abbotec也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和生产工艺,减少对环境的影响。此外,Abbotec还积极参与社会公益活动,为社会的发展做出贡献。

这五个故事都是基于电子行业发展的常见模式而虚构的,旨在展示一个电子企业可能经历的发展过程。请注意,这些故事并非针对任何真实存在的企业,也不涉及任何具体的褒贬评价。

Hoffman_Enclosures__Inc.公司的发展小趣事

Hoffman在追求企业发展的同时,也积极履行社会责任,致力于实现可持续发展。公司注重环保和节能,不断推出绿色、低碳的产品和技术。同时,Hoffman还积极参与公益事业,通过捐款、志愿服务等多种方式回馈社会。这些举措不仅提升了公司的社会形象,也促进了企业与社会的和谐共生。

以上五个故事展示了Hoffman Enclosures, Inc.在电子行业中的发展历程和关键节点,每个故事都体现了公司在技术创新、市场拓展、产品定制、标准制定以及社会责任等方面的努力和成就。

Condor公司的发展小趣事

面对客户日益多样化的需求,Hoffman提供了超过12,000种标准产品以及量身定制的解决方案。公司拥有一支专业的研发团队和完善的生产体系,能够根据客户的具体需求,快速设计出符合要求的电气机柜和温控产品。这种灵活的定制化服务不仅满足了客户的个性化需求,也进一步增强了客户对公司的信任和忠诚度。

ARCOL公司的发展小趣事

随着电子技术的飞速发展,ARCOL公司意识到只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了对研发的投入,积极引进先进的生产设备和技术,不断推出创新性的产品。通过不断优化生产工艺和提升产品质量,ARCOL的产品在市场上逐渐占据了领先地位。

问答坊 | AI 解惑

开关电源测试方法

开关电源测试方法 一. 耐电压(HI.POT,ELECTRIC STRENGTH ,DIELECTRIC VOLTAGE WITHSTAND)KV1.1 定义:于指定的端子间,例如:I/P-O/P,I/P-FG,O/P-FG间,可耐交流之有效值,漏电流一般可容许10毫安,时间1分钟。1.2 测试条件:Ta:25摄氏度;RH:室内湿 ...…

查看全部问答>

有关智能寻迹小车的问题 急急!

本帖最后由 paulhyde 于 2014-9-15 09:06 编辑 请问各位大虾有没有做过智能寻迹小车,你们用的是什么样的光电传感器,我用的红外反射式光电传感器RPR220为什么在白色区域也不能导通呢? 请各位大虾 教一下RPR220到底应该怎么用 确切的说怎么导通 ...…

查看全部问答>

上传“高速PCB设计指南”教程

WORD文档格式,一共8篇,值得一看。 [ 本帖最后由 lycdl 于 2008-7-10 12:17 编辑 ]…

查看全部问答>

串口驱动HW_VTBL结构体的问题

请问HW_VTBL结构体的函数就是和硬件有关的函数,即我们写驱动要实现的函数呢?或者在那里呢? typedef struct __HW_VTBL    {     PVOID        (*HWInit)(ULONG Identifier, PVOID pMDDContext, PHWOBJ ...…

查看全部问答>

请推荐有关NT内核编程讲的好的书或网络资源!抢分吧!

请推荐有关NT内核编程讲的好的书或网络资源! 书最好,电子书也好,有下载链接尤其好,给些blog连接也不错,视频资源下载连接最最好! 抢分吧!…

查看全部问答>

应急灯LED一致性测试

闲的无事,来测试一下LED的一致性怎么样,用应急灯的变压器输出18V,串联470欧电阻,5只LED串联,测量得5只LED压降分别为 3V   2.92V  2.92V  2.91V  2.87V   电流为6mA。以上参数供大家参考。…

查看全部问答>

阻抗匹配的问题

阻抗匹配仅适用于电子电路吗? 在电工电路中(即强电电路中)是否就不用考虑阻抗匹配?为什么?…

查看全部问答>

向tiankai001求助winavr+avrstudio C语言编译要求makefile问题

tiankai001你好,我正想学用avr,刚一上手就遇到编译问题,在avrstudio4环境下借助winavr用C编写程序, 要求makefile,不知怎么解决。在论坛里看到你在用winavr,希望能得到你的帮助,如何在avrstudio中用C 编译一个程序,如点亮一个LED,多谢!…

查看全部问答>

22nm已经成为过去!Intel发力5nm工艺

本帖最后由 jameswangsynnex 于 2015-3-3 20:02 编辑 他说:“我们的研究和开发是相当深远的,我是说(未来)十年。” …

查看全部问答>

51复位电路的分析

这个题目貌似很大白菜,然而,最近当我被一个朋友问到这个问题时,忽然发现,看似如此大白菜的电路,嘿嘿,不好意思,我也不会分析.......费了半天劲,好像才终于说出了个大概。但心里还是没啥底,于是决定在这发个帖,望各位老少看管给评论评论, ...…

查看全部问答>