IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32与DS18B20数字温度传感器寄生供电方式的新方案与1-wire总线程序设计 -> 正文阅读

[嵌入式]STM32与DS18B20数字温度传感器寄生供电方式的新方案与1-wire总线程序设计

STM32与DS18B20数字温度传感器寄生供电方式的新方案与1-wire总线程序设计

DS18B20是常用的一种数字温度传感器,通过1-wire总线实现传感器内部寄存器的访问。传感器有两种供电方式,一种是恒定供电,也就是VDD端一直供电,是大部分参考设计采用的方式,然而此种方式会对芯片产生一定的通流加热过程,所以在环境温度不变时,测量温度在缓慢上升,直到升到一个工作电流发热和环境散热的平衡点,这个测量温度可能比实际的环境温度高几度,因此存在测量温差。这种方式的官方连接关系如下图所示:
在这里插入图片描述
另一种是寄生供电,VDD接到地,通过Open-drain方式的数据端DQ的上拉通道对内部电容的预充电提供基本访问的供电,然后芯片内部做温度转换的过程需要抽取更多的电流,因此需要在发布转换命令后10us内将DQ拉到强供电端以提供转换电流,此种方式的官方连接如下图所示:
在这里插入图片描述

可见寄生供电的方式需要MCU提供一个GPIO控制增强电流供电端的MOS管或三级管。在温度转换过程前打开供电,在温度转换后关闭供电。由于VDD没有保持供电,因此寄生供电模式没有造成额外温升,测量温度的稳定性更高。

DS18B20寄生供电方式新方案

温度转换过程所要抽拉的额定电流规格为1.5mA:
在这里插入图片描述
1.5mA在MCU的GPIO电流安全输出范围内,这里提出新的寄生供电方式方案,去除了MOS管或三级管的使用,简化了电路连接,并成功验证。具体的方案如下:
在这里插入图片描述
方案的改进是直接将DS18B20 VDD接到STM32的一个GPIO, 在基本访问过程GPIO输出0即DS18B20 VDD接地,在转换过程前GPIO输出1即提供电压给DS18B20 VDD, 从而在转换过程中DS18B20处于VDD供电状态,转换完成后GPIO再输出0即DS18B20 VDD接地,继续基本访问的读操作。本方案的寄生供电特点是从DS18B20 VDD提供转换过程电流,原方案是从DS18B20 DQ提供转换过程电流。

STM32工程配置

这里以STM32G030F6P6芯片及STM32CUBEIDE开发工具实现DS18B20寄生供电方式的代码案例。

首先建立工程并配置时钟系统:
在这里插入图片描述
然后配置管脚A0为Open Drain输出(连接DS18B20 DQ),配置A1为Push Pull输出(连接DS18B20 VDD)。在这里插入图片描述
在这里插入图片描述

并配置USART2作为温度检测结果输出接口,全部采用默认参数即可。
在这里插入图片描述
保存并生成初始工程代码:
在这里插入图片描述

STM32访问DS18B20工程代码

模拟1-wire协议要用到微秒级延时函数,这里采用的微秒延时函数: STM32 HAL us delay(微秒延时)的指令延时实现方式及优化
在进行DS18B20前,要先读取64位的ROM ID, 然后对此读到的ROM ID进行校验,以验证1-wire的访问是否正确,然后再进行后续的温度读取操作。ROM ID由1个字节的家族码,6个字节的产品码和1个字节的CRC-8校验码组成。因此校验方式是将家族码和产品码总共7个字节进行CRC-8计算得到计算码,然后将计算码和最后一个字节的校验码进行比较,相同则证明1-wire访问正确。这里采用的CRC-8计算函数: C语言标准CRC-8校验函数

STM32模拟1-wire访问DS18B20的函数定义为:

#define DQ_0		 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
#define DQ_1		 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

#define DQ_IS_LOW    HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0?1:0

#define CONVERSION_VOLTAGE 1 //0: DS18B20 constant VCC mode. 1: DS18B20 short term VCC mode only supplying for conversion process.
#define CV_ON    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)  //supply power to DS18B20 VCC
#define CV_OFF   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET) //not supply power to DS18B20 VCC

#define GPIO_EXEC_DELAY_us 8

uint8_t DS18B20_Reset(void) //Bus reset timing in page 15 of spec
{
	__disable_irq();
	DQ_1;
	PY_Delay_us_t(10); //Pull high, ready to send reset request

    DQ_0;
	PY_Delay_us_t(520); //Minimum 480us
	DQ_1;

	PY_Delay_us_t(15+55-GPIO_EXEC_DELAY_us);

	if (DQ_IS_LOW)
	{
		 PY_Delay_us_t(420);
		 __enable_irq();
		 return 1;
	}
	else
	{
		 PY_Delay_us_t(420);
		 __enable_irq();
		 return 0;
	}

}

void DS18B20_WriteByte(uint8_t val)
{
	__disable_irq();
	for (uint8_t i = 0; i < 8; i++)
	{
		DQ_0;
		PY_Delay_us_t(15-GPIO_EXEC_DELAY_us);

		if (val & 0x01)
		{
			DQ_1;
		}
		else
		{
			DQ_0;
		}
		PY_Delay_us_t(100);
		DQ_1;
		PY_Delay_us_t(4);
		val >>= 1;
	}
	__enable_irq();
}

uint8_t DS18B20_ReadByte(void)
{
	uint8_t read = 0;
	__disable_irq();
	for (uint8_t i = 0; i < 8; i++)
	{
		read >>= 1;
		DQ_0;
		PY_Delay_us_t(2);
		DQ_1;
		PY_Delay_us_t(12-GPIO_EXEC_DELAY_us);

		if (!DQ_IS_LOW)	read |= 0x80;

		PY_Delay_us_t(50);
	}

	PY_Delay_us_t(60);
	__enable_irq();
	return read;
}

uint16_t DS18B20_ReadTempReg(void)
{
	uint8_t tempL, tempH;

	if(CONVERSION_VOLTAGE) CV_ON;

	DS18B20_Reset();
	DS18B20_WriteByte(0xcc);
	DS18B20_WriteByte(0x44);

	PY_Delay_us_t(2);
	DQ_0;
	PY_Delay_us_t(2);
	DQ_1;

    PY_Delay_us_t(800000); //conversion delay

    if(CONVERSION_VOLTAGE) CV_OFF;

    DS18B20_Reset();
	DS18B20_WriteByte(0xcc);
	DS18B20_WriteByte(0xbe);

	tempL = DS18B20_ReadByte();
	PY_Delay_us_t(60);
	tempH = DS18B20_ReadByte();

    DS18B20_Reset();


	if (tempH>7) return 0;
	else {return ((((uint16_t)tempH) << 8) | (uint16_t)tempL);}
}

uint64_t DS18B20_ReadID()
{
	uint64_t ROMID=0;
	uint8_t RD[8];

	if (DS18B20_Reset() == 0)
	{
		return 0;
	}

	DS18B20_WriteByte(0x33);
	for (uint8_t i = 0; i < 8; i++)
	{
		ROMID <<=8;
		ROMID |= DS18B20_ReadByte();
	}
	DS18B20_Reset();

	for(int8_t i=7;i>=0;i--)
	{
	    RD[7-i] = (ROMID>>(i*8));
	}

	if (PY_CRC_8(RD, 7)==RD[7]) ROMID= *(uint64_t *)RD;
	else ROMID = 0xFFFFFFFFFFFFFFFF;

	return ROMID;
}

uint16_t DS18B20_ReadTempByID(uint64_t ROMID)
{
	uint8_t tempL, tempH;
	uint8_t i;

	uint64_t ROMID_t = ROMID;

	if(CONVERSION_VOLTAGE) CV_ON;

	DS18B20_Reset();
	DS18B20_WriteByte(0x55);
	for (i = 0; i < 8; i++)
	{
		DS18B20_WriteByte((uint8_t)ROMID_t);
		ROMID_t>>=8;
	}
	DS18B20_WriteByte(0x44);

	PY_Delay_us_t(2);
	DQ_0;
	PY_Delay_us_t(2);
	DQ_1;

	PY_Delay_us_t(800000); //conversion delay

	if(CONVERSION_VOLTAGE) CV_OFF;

	ROMID_t = ROMID;
	DS18B20_Reset();
	DS18B20_WriteByte(0x55);
	for (i = 0; i < 8; i++)
	{
		DS18B20_WriteByte((uint8_t)ROMID_t);
		ROMID_t>>=8;
	}
	DS18B20_WriteByte(0xbe);

	tempL = DS18B20_ReadByte();
	tempH = DS18B20_ReadByte();

	DS18B20_Reset();



    if (tempH>7) return 0;
	else return ((((uint16_t)tempH) << 8) | (uint16_t)tempL);
}

其中,“#define GPIO_EXEC_DELAY_us 8” 是做时序校正优化的参数,是GPIO代码驱动输出模式下的输出延时,因为DS18B20有三个时序关键点需要控制准确,所以要在这三个时序关键点进行时序校正优化:

  1. 总线复位后的响应的MCU采样时间点
    在这里插入图片描述

  2. 写bit时序的开始15us低电平长度,保证DS18B20采样到正确状态
    在这里插入图片描述

  3. 读bit时序的MCU采样时间点
    在这里插入图片描述

STM32串口工程代码

这里在工程里引入usart.h和usart.c,便于调用print函数打印输出结果。
usart.h:

#ifndef _USART_H
#define _USART_H

#include "stm32g0xx_hal.h"
#include "stdio.h"	 	  	


int fputc(int ch, FILE *f) ;

#endif

usart.c:

#include "usart.h"   


extern UART_HandleTypeDef huart2;   //声明串口

/* USER CODE BEGIN 1 */
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}
/* USER CODE END 1 */

STM32完整工程代码及效果

如下为STM32完整工程代码,首先读取ROM ID 并校验,然后进行温度的读取及串口输出:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
//Written by Pegasus Yu in 2022
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"

#include <stdio.h>
#include <stdlib.h>

uint8_t PY_CRC_8(uint8_t *di, uint32_t len)
{   //Written by Pegasus Yu 2022/04/22
	uint16_t crc_poly = 0x0107; //X^8+X^2+X^1+1 total 9 effective bits. Computed total data shall be compensated 8-bit '0' before CRC computing.
	uint8_t *datain;
	uint64_t cdata = 0; //Computed total data
	uint16_t data_t = 0; //Process data of CRC computing

	uint16_t index_t = 63;  ///bit shifting index for initial '1' searching
	uint16_t index = 63;    //bit shifting index for CRC computing
	uint8_t rec = 0; //bit number needed to be compensated for next CRC computing

	uint32_t cn=(len+1)/7;
	uint32_t cr=(len+1)%7;

	uint32_t j;

	datain = malloc(len+1);
	for(j=0;j<len;j++)
	{
		datain[j]=di[j];
	}
	    datain[len]=0; //Compensate 8-bit '0' for input data

     if(len<=7)
     {
    	 for(j=0;j<=len;j++)
    	 {
    		 cdata = (cdata<<8);
    		 cdata = cdata|datain[j];
    	 }
    	 cn = 1;
     }
     else
     {
    	 if(cr==0)
    	 {
    		 cr=7;
    	 }
    	 else
    	 {
    		 cn++;
    	 }

    	 for(j=0;j<cr;j++)
    	 {
    		 cdata = (cdata<<8);
    		 cdata = cdata|datain[j];
    	 }
     }

     do
     {
 		cn--;

 		while(index_t>0)
 		{
 			if( (cdata>>index_t)&1 )
 			{
 				index = index_t;
 				index_t = 0;

 				data_t |= (cdata>>(index-8));
 				{
 					data_t = data_t ^ crc_poly;
 				}

 	            while((index!=0x5555)&&(index!=0xaaaa))
 	            {
 	            	/*
 	    			if ((data_t>>7)&1) rec = 1;
 	    			else if ((data_t>>6)&1) rec = 2;
 	    			else if ((data_t>>5)&1) rec = 3;
 	    			else if ((data_t>>4)&1) rec = 4;
 	    			else if ((data_t>>3)&1) rec = 5;
 	    			else if ((data_t>>2)&1) rec = 6;
 	    			else if ((data_t>>1)&1) rec = 7;
 	    			else if ((data_t>>0)&1) rec = 8;
 	    			else rec = 9; */

	 	    		for(uint8_t n=1;n<9;n++)
	 	    		{
	 	    			if ((data_t>>(8-n))&1) {rec = n;break;}
	 	    			if (n==8) rec=9;
	 	    		}

 	    			if((index-8)<rec)
 	    			{
 	    				data_t = data_t<<(index-8);
 	    				data_t |=  (uint16_t)((cdata<<(64-(index-8)))>>(64-(index-8)));
 	    				index = 0x5555;
 	    			}
 	    			else
 	    			{
 	        			for(uint8_t i=1;i<=rec;i++)
 	        			{
 	        				data_t = (data_t<<1)|((cdata>>(index-8-i))&1) ;
 	        			}

 	        			if(rec!= 9)
 	        			{
 	        				data_t = data_t ^ crc_poly;
 	        				index -= rec;
 	        			}
 	        			else
 	        			{
 	        				data_t = 0;
 	        				index_t = index-8-1;
 	        				index = 0xaaaa;

 	        			}

 	    			}

 	            }
 				if(index==0x5555) break;
 			}
 			else
 			{
 				index_t--;
 				if(index_t<8) break;
 			}
         }

 		if(cn>0)
 		{
  			cdata = data_t&0x00ff;

 			for(uint8_t k=0;k<7;k++)
 			{
 	    		 cdata = (cdata<<8);
 	    		 cdata = cdata|datain[j++];

 			}

 	    	data_t = 0;
 	 		index_t = 63;  ///bit shifting index for initial '1' searching
 	 		index = 63;    //bit shifting index for CRC computing
 	 		rec = 0; //bit number needed to be compensated for next CRC computing
 		}

     }
     while(cn>0);

     free(datain);
     return (uint8_t)data_t;
}

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define DQ_0		 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
#define DQ_1		 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

#define DQ_IS_LOW    HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)==0?1:0

#define CONVERSION_VOLTAGE 1 //0: DS18B20 constant VCC mode. 1: DS18B20 short term VCC mode only supplying for conversion process.
#define CV_ON    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)  //supply power to DS18B20 VCC
#define CV_OFF   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET) //not supply power to DS18B20 VCC
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = HAL_GetTick()+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = HAL_GetTick();
  PY_Delay_us_t(1000000) ;
  secondms = HAL_GetTick();

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}

void PY_Delay_us(uint32_t Delay)
{
  __IO uint32_t delayReg;

  __IO uint32_t msNum = Delay/1000;
  __IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);

  if(msNum>0) HAL_Delay(msNum);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}


/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define GPIO_EXEC_DELAY_us 8

uint8_t DS18B20_Reset(void) //Bus reset timing in page 15 of spec
{
	__disable_irq();
	DQ_1;
	PY_Delay_us_t(10); //Pull high, ready to send reset request

    DQ_0;
	PY_Delay_us_t(520); //Minimum 480us
	DQ_1;

	PY_Delay_us_t(15+55-GPIO_EXEC_DELAY_us);

	if (DQ_IS_LOW)
	{
		 PY_Delay_us_t(420);
		 __enable_irq();
		 return 1;
	}
	else
	{
		 PY_Delay_us_t(420);
		 __enable_irq();
		 return 0;
	}

}

void DS18B20_WriteByte(uint8_t val)
{
	__disable_irq();
	for (uint8_t i = 0; i < 8; i++)
	{
		DQ_0;
		PY_Delay_us_t(15-GPIO_EXEC_DELAY_us);

		if (val & 0x01)
		{
			DQ_1;
		}
		else
		{
			DQ_0;
		}
		PY_Delay_us_t(100);
		DQ_1;
		PY_Delay_us_t(4);
		val >>= 1;
	}
	__enable_irq();
}

uint8_t DS18B20_ReadByte(void)
{
	uint8_t read = 0;
	__disable_irq();
	for (uint8_t i = 0; i < 8; i++)
	{
		read >>= 1;
		DQ_0;
		PY_Delay_us_t(2);
		DQ_1;
		PY_Delay_us_t(12-GPIO_EXEC_DELAY_us);

		if (!DQ_IS_LOW)	read |= 0x80;

		PY_Delay_us_t(50);
	}

	PY_Delay_us_t(60);
	__enable_irq();
	return read;
}

uint16_t DS18B20_ReadTempReg(void)
{
	uint8_t tempL, tempH;

	if(CONVERSION_VOLTAGE) CV_ON;

	DS18B20_Reset();
	DS18B20_WriteByte(0xcc);
	DS18B20_WriteByte(0x44);

	PY_Delay_us_t(2);
	DQ_0;
	PY_Delay_us_t(2);
	DQ_1;

    PY_Delay_us_t(800000); //conversion delay

    if(CONVERSION_VOLTAGE) CV_OFF;

    DS18B20_Reset();
	DS18B20_WriteByte(0xcc);
	DS18B20_WriteByte(0xbe);

	tempL = DS18B20_ReadByte();
	PY_Delay_us_t(60);
	tempH = DS18B20_ReadByte();

    DS18B20_Reset();


	if (tempH>7) return 0;
	else {return ((((uint16_t)tempH) << 8) | (uint16_t)tempL);}
}

uint64_t DS18B20_ReadID()
{
	uint64_t ROMID=0;
	uint8_t RD[8];

	if (DS18B20_Reset() == 0)
	{
		return 0;
	}

	DS18B20_WriteByte(0x33);
	for (uint8_t i = 0; i < 8; i++)
	{
		ROMID <<=8;
		ROMID |= DS18B20_ReadByte();
	}
	DS18B20_Reset();

	for(int8_t i=7;i>=0;i--)
	{
	    RD[7-i] = (ROMID>>(i*8));
	}

	if (PY_CRC_8(RD, 7)==RD[7]) ROMID= *(uint64_t *)RD;
	else ROMID = 0xFFFFFFFFFFFFFFFF;

	return ROMID;
}

uint16_t DS18B20_ReadTempByID(uint64_t ROMID)
{
	uint8_t tempL, tempH;
	uint8_t i;

	uint64_t ROMID_t = ROMID;

	if(CONVERSION_VOLTAGE) CV_ON;

	DS18B20_Reset();
	DS18B20_WriteByte(0x55);
	for (i = 0; i < 8; i++)
	{
		DS18B20_WriteByte((uint8_t)ROMID_t);
		ROMID_t>>=8;
	}
	DS18B20_WriteByte(0x44);

	PY_Delay_us_t(2);
	DQ_0;
	PY_Delay_us_t(2);
	DQ_1;

	PY_Delay_us_t(800000); //conversion delay

	if(CONVERSION_VOLTAGE) CV_OFF;

	ROMID_t = ROMID;
	DS18B20_Reset();
	DS18B20_WriteByte(0x55);
	for (i = 0; i < 8; i++)
	{
		DS18B20_WriteByte((uint8_t)ROMID_t);
		ROMID_t>>=8;
	}
	DS18B20_WriteByte(0xbe);

	tempL = DS18B20_ReadByte();
	tempH = DS18B20_ReadByte();

	DS18B20_Reset();



    if (tempH>7) return 0;
	else return ((((uint16_t)tempH) << 8) | (uint16_t)tempL);
}
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint64_t ROM_ID;
uint8_t FAMILY_CODE;
uint64_t SERIAL_NUM;
uint16_t TData;

uint8_t TD_Flag; //temperature data flag(0:positive or 1:negative)
uint8_t TD_Absi;  //temperature data absolute integral value
uint8_t TD_Absf;  //temperature data absolute fraction value
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  PY_usDelayTest();
  PY_usDelayOptimize();

  ROM_ID = DS18B20_ReadID();
  FAMILY_CODE = ROM_ID; //8-bit family code
  SERIAL_NUM = (ROM_ID>>8)&0x0000ffffffffffff; //48-bit serial number

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(ROM_ID==0xffffffffffffffff)
	  {
		  TData = 0xffff;
		  printf("Read ROMID Error!!");
		  PY_Delay_us(100000);
	  }
	  else
	  {
		  printf("FAMILY_CODE: 0x%x\r\n", FAMILY_CODE);
		  PY_Delay_us(500);
		  printf("SERIAL_NUM: 0x%lx%lx\r\n", (uint32_t)(SERIAL_NUM>>32),(uint32_t)(SERIAL_NUM));
		  PY_Delay_us(500);

		  TData = DS18B20_ReadTempReg();
		  if ((TData&0x8000)==0)
		  {
			  TD_Flag = 0;
			  TD_Absi = TData/16;
			  TD_Absf = TData%16;
			  //|temperature|=TD_Absi+TD_Absf*0.0625

			  if(TD_Absf==0) printf("Current temperature is %u degree Celsius\r\n",TD_Absi);
			  else if(TD_Absf*625<1000) printf("Current temperature is %u.0%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
			  else printf("Current temperature is %u.%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
		  }
		  else
		  {
			  TD_Flag = 1;
			  TD_Absi = (0x10000 - TData)/16;
			  TD_Absf = (0x10000 - TData)%16;
			  //|temperature|=TD_Absi+TD_Absf*0.0625

			  if(TD_Absf==0) printf("Current temperature is -%u degree Celsius\r\n",TD_Absi);
			  else if(TD_Absf*625<1000) printf("Current temperature is -%u.0%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
			  else printf("Current temperature is -%u.%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
		  }

		  PY_Delay_us(1000);


		  printf("ROMID: 0x%lx%lx\r\n", (uint32_t)(ROM_ID>>32),(uint32_t)(ROM_ID));
		  PY_Delay_us(500);

		  TData = DS18B20_ReadTempByID(ROM_ID);
		  PY_Delay_us(500);
		  if ((TData&0x8000)==0)
		  {
			  TD_Flag = 0;
			  TD_Absi = TData/16;
			  TD_Absf = TData%16;
			  //|temperature|=TD_Absi+TD_Absf*0.0625

			  if(TD_Absf==0) printf("Current temperature is %u degree Celsius\r\n",TD_Absi);
			  else if(TD_Absf*625<1000) printf("Current temperature is %u.0%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
			  else printf("Current temperature is %u.%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
		  }
		  else
		  {
			  TD_Flag = 1;
			  TD_Absi = (0x10000 - TData)/16;
			  TD_Absf = (0x10000 - TData)%16;
			  //|temperature|=TD_Absi+TD_Absf*0.0625

			  if(TD_Absf==0) printf("Current temperature is -%u degree Celsius\r\n",TD_Absi);
			  else if(TD_Absf*625<1000) printf("Current temperature is -%u.0%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
			  else printf("Current temperature is -%u.%u degree Celsius\r\n",TD_Absi,TD_Absf*625);
		  }

		  PY_Delay_us(1000);

	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
  RCC_OscInitStruct.PLL.PLLN = 64;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

将ROM ID, FAMILY ID, SERIAL NUMBER交叉输出及温度输出的效果:
在这里插入图片描述

例程下载

STM32G030F6P6-DS18B20例程下载(STM32CUBEIDE工程)

–End–

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:27:45  更:2022-09-04 01:29:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 17:34:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计