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 MAXIM格式校验函数 。

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 8uint8_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 requestDQ_0;PY_Delay_us_t(520); //Minimum 480usDQ_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 delayif(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_MAXIM(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 delayif(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 printfset 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_MAXIM(uint8_t *di, uint32_t len)
{   //Written by Pegasus Yu 2022/09/07uint16_t crc_poly = 0x0131; //X^8+X^5+X^4+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 datauint16_t data_t = 0; //Process data of CRC computinguint16_t index_t = 63;  ///bit shifting index for initial '1' searchinguint16_t index = 63;    //bit shifting index for CRC computinguint8_t rec = 0; //bit number needed to be compensated for next CRC computinguint32_t cn=(len+1)/7;uint32_t cr=(len+1)%7;uint32_t j;datain = malloc(len+1);for(j=0;j<len;j++)  //bit sequence inversion for input bytes{datain[j]=0;for(uint32_t m=0; m<8; m++){datain[j] <<= 1;datain[j] |= ((di[j]>>m)&0x01);}}datain[len]=0; //Compensate 8-bit '0' for input dataif(len<=7){for(j=0;j<=len;j++){cdata = (cdata<<8);cdata = cdata|datain[j];}cn = 1;}else{if(cr==0){cr=7;}if(cr==1){cr=8;}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' searchingindex = 63;    //bit shifting index for CRC computingrec = 0; //bit number needed to be compensated for next CRC computing}}while(cn>0);//bit sequence inversion for output bytedatain[0] = data_t;data_t = 0;for(uint32_t m=0; m<8; m++){data_t <<= 1;data_t |= ((datain[0]>>m)&0x01);}free(datain);return 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 8uint8_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 requestDQ_0;PY_Delay_us_t(520); //Minimum 480usDQ_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 delayif(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_MAXIM(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 delayif(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 codeSERIAL_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.0625if(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.0625if(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.0625if(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.0625if(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–

STM32与DS18B20数字温度传感器寄生供电方式的优化方案与1-wire总线程序设计相关推荐

  1. STM32应用(八)数字温度传感器DS18B20、数字温湿度传感器DHT11(软件模拟I2C)

    文章目录 1.DS18B20 数字温度传感器实验 1.1 DS18B20简介 1.2 硬件与IO口配置 1.3 实物图与接线 1.4 工程配置 1.5 驱动和检测代码编写 1.5.1 ds18b20. ...

  2. 【正点原子STM32连载】第三十九章 DS18B20数字温度传感器实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  3. 【正点原子FPGA连载】第二十七章DS18B20数字温度传感器实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  4. 【正点原子MP157连载】第二十六章 DS18B20数字温度传感器实验-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  5. Arduino基础篇(七)-- 如何使用DS18B20数字温度传感器(基于OneWire和DallasTemperature库)

    温度传感器是指能感受温度并转换成可用输出信号的传感器.按测量方式分为接触式和非接触式,按照传感器材料及电子元件分为热电阻和热电偶两类,按照工作原理分为模拟式和数字式.本篇主要介绍数字温度传感器 DS1 ...

  6. DS18B20数字温度传感器

    目录 一.基础知识 1.基础介绍: 2.DS18B20特点: 3.单总线时序 4.相关操作时序 5.部分ROM指令 二.相关代码 1. 使用步骤(单点总线情况) 2. 代码展示 数字温度传感器你会用了 ...

  7. 基于DS18B20数字温度传感器的温度计设计

    基于DS18B20数字温度传感器的温度计设计 本报告为哈尔滨工业大学电子与信息工程学院大二学期微机原理课程的课设报告.请注意,本文所述代码均在Quartus II 13.0程序内使用汇编语言运行. 一 ...

  8. DS18B20数字温度传感器及单总线协议规定

    1,DS18B20数字温度传感器的主要特点 通信采用1-Wire接口 每个DS18B20都有唯一的64位序列码储存在板载ROM中 无需外部元件 可从数据线供电,电源范围为3.0V ~ 5.5V. 可测 ...

  9. 温度传感器的c语言程序,DS18B20数字温度传感器C语言程序实例

    51单片机DS18B20数字温度传感器设计 与C程序 #include #define uchar unsigned char #define uint unsigned int #define DQ ...

最新文章

  1. IIS利用X-Forwarded-For获得来访者的真实IP
  2. idea删除module
  3. 手写简版spring --4--注入属性和依赖对象
  4. 消息队列之ActiveMQ安装配置
  5. java自动装箱和拆箱_关于java自动装箱和自动拆箱
  6. 迷宫问题---递归解决
  7. wrapper 并集如何使用
  8. 西安python_西安找工作|西安人才网|西安全职招聘信息-西安58同城
  9. python核心装饰_《python核心编程》中高级闭包和装饰器理解?
  10. cpu 散热测试软件,游匣G15丨全方位跑分评测报告
  11. 易班打卡——自动填写健康日报
  12. opencv: 颜色通道 探究(图示+源码)
  13. ERROR: ld.so: object ‘/usr/local/lib/libc2.28.so‘ from /etc/ld.so.preload cannot be preloaded ...
  14. MacBook上有哪些相见恨晚的神器
  15. Windows 无法连接到无线网络
  16. 1.3 熟悉 Ubuntu 桌面环境
  17. 51单片机学习笔记——STC15W201S系列
  18. EXCEL中,不能调整行高。当把行高拉到409的时候就不能再拉高了,是什么原因?
  19. 7-42 打印倒直角三角形图案 (15 分)
  20. FI和MM集成自动记账-采购收货发票校验业务-OBYC

热门文章

  1. mysql到linux导出备份
  2. 《先知·法律》|《先知·买卖》
  3. ERP实施-采购业务集成(103和105移动类型两步入库)
  4. Python SQLAlchemy
  5. python fileinputstream_fileinputstream读取网络文件
  6. 【图】图的相关概念以及图的存储
  7. 微信小程序 navigation API
  8. c语言if语句教学设计,c语言if语句教学设计
  9. intellij idea build时出现Artifact contains illegal characters的解决
  10. PCB生产工艺流程二:图形电镀工艺流程说明