历史上的今天
返回首页

历史上的今天

今天是:2024年08月27日(星期二)

正在发生

2021年08月27日 | 玩转STM32CubeMX | DS18B20温度传感器

2021-08-27 来源:eefocus

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发送所有的命令和数据都是字节的低位在前,下面介绍这几个信号的时序:


⏩ 初始化时序

内置闪存模块可以在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容并得到相应的数据。

⏩ 写时序

写时序包括写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

USART1串口

DS18B20

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;

  //设定TIM7计数器起始值

  __HAL_TIM_SET_COUNTER(&htim7,differ);

  //启动定时器

  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){

  DS18B

20_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指示灯不断闪烁,串口不断打印出当前温度值



推荐阅读

史海拾趣

依必安派特(ebmpapst)公司的发展小趣事

在实现了从贸易到制造的转变后,依必安派特并没有停止前进的步伐。在2012年,依必安派特亚太研发中心正式落户上海,开始了本土化研发之路。这一举措使得依必安派特能够更好地了解中国市场的需求和趋势,为中国客户提供更加符合其需求的产品和解决方案。同时,本土化研发也加速了依必安派特在中国市场的创新步伐,推动了公司业务的快速发展。

诚润电子(CHEVRON)公司的发展小趣事

随着公司业务的不断发展,诚润电子开始积极拓展海外市场。他们通过参加国际展会、与海外客户建立合作关系等方式,逐渐将产品推向全球。在这个过程中,诚润电子不仅提升了自身的品牌知名度,还积累了丰富的国际市场经验。如今,诚润电子的产品已经出口到多个国家和地区,成为了全球电子保护元件领域的重要供应商之一。

DBM Optix公司的发展小趣事

在竞争激烈的电子行业中,DBM Optix深知只有不断创新才能保持领先地位。因此,公司始终将研发作为核心竞争力之一,持续投入大量资金用于新技术、新产品的开发。通过与高校、研究机构等合作,DBM Optix不断引入新技术、新材料,并将其应用于产品中,从而不断提升产品的性能和品质。这些创新举措使得DBM Optix在光学通信领域始终保持领先地位。

ELM Technology Corporation公司的发展小趣事

ELM Technology Corporation非常重视企业文化的建设。公司倡导“创新、协作、诚信、责任”的企业精神,鼓励员工积极创新、勇于担当。同时,公司还为员工提供了良好的工作环境和福利待遇,增强了员工的归属感和凝聚力。这种积极向上的企业文化为ELM的持续发展提供了强大的动力。

请注意,以上故事仅为概述,具体细节和事实需要根据ELM Technology Corporation的实际情况进行补充和完善。

DESCO公司的发展小趣事

随着防静电产品市场的不断扩大,DESCO公司开始着手进行市场拓展和品牌塑造。公司通过参加国际展会、举办技术研讨会等方式,积极向全球客户展示其防静电产品的技术优势和应用前景。同时,DESCO还加大了品牌宣传力度,提高了品牌知名度和美誉度。这些举措为公司在全球范围内赢得了大量忠实客户,市场份额持续增长。

CHENMKO公司的发展小趣事

面对数字化浪潮和智能制造的兴起,DESCO公司积极拥抱变革。公司投入大量资金引进先进的自动化设备和智能化生产线,提高生产效率和产品质量。同时,DESCO还加强了数字化营销和客户服务体系建设,提升了客户体验和市场响应速度。这些举措使公司在激烈的市场竞争中保持了领先地位。

问答坊 | AI 解惑

ADSL宽带接入技术在韩国通信的应用1

一、概况 韩国通信开展ADSL业务的主要原因是由于激烈的市场竞争。由于电信业务完全放开,除韩国通信之外,还有不少宽带业务提供商也在提供电信业务。当韩国通信还在推广ISDN业务时,一些CATV公司已利用CableModem占去了不少宽带Internet接入市场。 ...…

查看全部问答>

DVD扫盲知识

本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑 来论坛这么久,一直是下载一些东西,感谢所有分享好东西的兄弟姐妹们! 今天我也发一点DVD扫盲知识来给大家分享一下,看完了这个绝对能让你对DVD有一个比较全面的了解,扫盲用的!呵呵 另外 ...…

查看全部问答>

如何关闭窗口

我用WINCE开发了一个MFC窗口函数,在关闭窗口时程序还在执行,如果想退出的程序的话,要重载哪个函数? 谢谢。。。…

查看全部问答>

PCI总线原理及编程指南

PCI总线原理及编程指南: 最近想研究一下PCI插槽上的控制器是如何工作的,谁那有详细的说明? 该从哪些方面找,有这方面的代码吗?谁有?给一份,谢谢了。…

查看全部问答>

MFC requires WINVER to be #defined to 0x0400 or greater

项目建立的时候是wm5.0,后来选择别的模拟器,编译的时候出现“MFC requires WINVER to be #defined to 0x0400 or greater”,应该如何解决?…

查看全部问答>

猎头职位——条码手持终端开发工程师

条码手持终端开发工程师 1.        2名,大专以上学历; 2.        了解制造业物流业务和条码/RFID技术,有仓库和生产线条码/RFID手持终端开发经验。 3.        熟悉C#语言编程 ...…

查看全部问答>

led冷光源与热光源的区别

热光源:利用热能激发的光源,如白炽灯在3,000-4,000K温度时热辐射发光。白炽灯有80-90%的能量转换能热能,10%左右的能量转换为光能。因此发光效率较低。我们不是根据灯具外壳的温度来定义为冷光源,还是热光源。灯具週边的温度高低,只能评判 ...…

查看全部问答>

高精度数控恒流源

各位大侠,目前手头有个设计任务,征集个方案主要情况是这个样子:板卡由BGA核心板(现有模块)+DA模拟输出部分+恒流源运放电路+AD采集模块几部分主要技术难点就在于高精度正负恒流源的设计和实现,技术要求如下: 1提供八路独立正负恒流源恒流源量 ...…

查看全部问答>

linux中inittab文件详解

转贴自:http://www.2cto.com/os/201108/98426.html   init的进程号是1(ps -aux | less),从这一点就能看出,init进程是系统所有进程的起点,Linux在完成核内引导以后,就开始运行init程序。 init程序需要读取配置文件/etc/ini ...…

查看全部问答>

这可怎么办

有两个电源16V和12V,平时使用12V,当12V被去掉后,要求PCB上实现能够自动切换到16V;这个怎么办?还请高手赐教。…

查看全部问答>