void IO_INPUT(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /*Configure GPIO pin : DS18B20_DQ_Pin */ GPIO_InitStruct.Pin = DSIO_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(DSIO_GPIO_Port, &GPIO_InitStruct); }
时间: 2024-03-04 22:52:05 浏览: 118
这段代码是用来配置单片机的一个GPIO引脚,将其设置为输入模式。在这个函数中,首先定义了一个GPIO_InitTypeDef类型的变量GPIO_InitStruct,用于存储GPIO的初始化参数。然后,通过设置这个变量的各个成员来配置GPIO引脚的模式和上下拉电阻的状态。其中,Pin成员用于指定GPIO的引脚编号,Mode成员用于指定GPIO的模式,这里是输入模式。Pull成员用于指定GPIO的上下拉电阻状态,这里是上拉电阻。最后,通过调用HAL_GPIO_Init函数来将GPIO配置为指定的模式和状态。这个函数通常会在初始化函数中调用,用于对GPIO进行配置。
相关问题
找不到错在哪,但是温度就是不变 /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 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. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "LCD.h" #include "DS18B20.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ float T; /* 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(); /* USER CODE BEGIN 2 */ lcd9648_init(); DS18B20_ConvertT(); lcd9648_clear(); lcd_show_string(0,0,96,48,16,"Temperature:"); lcd_reflash_gram(); // lcd9648_init(); // lcd9648_clear(); // lcd_show_string(0,0,96,48,12,"Hello World!"); // lcd_show_string(0,14,96,48,16,"Temperature:"); // //lcd_show_fontHZ(0, 30,"���пƼ�"); // lcd_reflash_gram(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { DS18B20_ConvertT(); T=DS18B20_ReadT(); if(T<0){ lcd_show_char(0,1*16,'-',16,0); lcd_reflash_gram(); T=-T; } else{ lcd_show_char(0,1*16,'+',16,0); lcd_reflash_gram(); } lcd_show_num(1*8,1*16,(int)T,3,16,0); lcd_show_char(4*8,1*16,'.',16,0); lcd_show_num(5*8,1*16,(unsigned long)(T*10000)%10000,4,16,0); lcd_reflash_gram(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(500); } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** 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.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 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_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, SCL_Pin|SDA_Pin|RS_Pin|CS_Pin |RST_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : SCL_Pin SDA_Pin RS_Pin CS_Pin RST_Pin */ GPIO_InitStruct.Pin = SCL_Pin|SDA_Pin|RS_Pin|CS_Pin |RST_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pin : DQ_Pin */ GPIO_InitStruct.Pin = DQ_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(DQ_GPIO_Port, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ HAL_GPIO_WritePin(DQ_GPIO_Port,DQ_Pin,GPIO_PIN_SET); /* USER CODE END MX_GPIO_Init_2 */ } /* 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 */
### STM32 DS18B20 温度读数不变的可能原因及解决方案
#### 一、硬件层面的原因与排查方法
1. **DS18B20供电异常**
如果DS18B20传感器没有稳定的电源供应,可能会导致其无法正常工作或者返回固定的错误值。建议检查DS18B20的VDD引脚是否有稳定电压[^4]。
2. **寄生供电模式下的拉高电阻不足**
当使用寄生供电模式时,如果没有合适的上拉电阻(通常是4.7kΩ),可能导致通信失败或数据不稳定。确认DQ引脚是否正确连接了一个适当阻值的上拉电阻[^4]。
3. **线路干扰或接触不良**
检查DS18B20的数据线是否存在物理损坏、虚焊或其他形式的电气噪声干扰。尝试重新焊接或更换更短更高质量的导线来减少信号衰减和外部电磁场的影响。
#### 二、软件层面的原因与优化措施
1. **初始化过程存在问题**
确认程序中针对DS18B20的一系列操作命令序列完全按照官方文档规定执行。这包括但不限于复位脉冲发送后的响应验证环节以及ROM匹配指令前后的逻辑处理部分[^4]。
2. **时间延迟不够充分**
在某些情况下,如果给予器件转换温度所需的时间不足以完成整个周期,则会引发连续多次获取相同旧数值的现象。因此,在发起新一轮测量请求之前应确保等待足够长的时间间隔以便让先前的任务彻底结束。
3. **代码实现细节上的缺陷**
下面给出一段经过改进后能够较好适应多种实际应用场景需求的标准C语言版本示例代码:
```c
#include "stm32f1xx_hal.h"
#define DQ_PIN GPIO_PIN_12
#define DQ_PORT GPIOD
void delay_us(uint16_t us){
__HAL_TIM_SET_COUNTER(&htim2, 0);
while (__HAL_TIM_GET_COUNTER(&htim2) < us);
}
void delay_ms(uint16_t ms){
HAL_Delay(ms);
}
uint8_t OneWireReset(){
uint8_t presence;
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
// Set pin as output push-pull mode.
GPIO_InitStruct.Pin = DQ_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DQ_PORT,&GPIO_InitStruct);
HAL_GPIO_WritePin(DQ_PORT,DQ_PIN,RESET);
delay_us(480);
HAL_GPIO_WritePin(DQ_PORT,DQ_PIN,SET);
delay_us(70);
// Switch to input floating mode immediately after releasing bus line low state.
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(DQ_PORT,&GPIO_InitStruct);
if(HAL_GPIO_ReadPin(DQ_PORT,DQ_PIN)==RESET){presence=1;}
else{presence=0;}
delay_us(410);
return presence;
}
// Other necessary functions omitted here for brevity...
float readTemperature(void){
float temp_celsius;
if(!OneWireReset())return -127;//Error handling
WriteByte(0xCC); //Skip ROM Command
WriteByte(0x44); //Convert Temperature Command
delay_ms(750); //Wait conversion complete
if(!OneWireReset())return -127;//Error handling again before reading data.
WriteByte(0xCC); //Skip ROM Command once more prior fetching results.
WriteByte(0xBE); //Read Scratchpad command
uint8_t lsb = ReadByte();
uint8_t msb = ReadByte();
int16_t raw_temp = ((msb << 8) | lsb);
temp_celsius = (raw_temp * 0.0625);
return temp_celsius;
}
```
此段代码展示了如何利用STM32微控制器平台精确地从DS18B20型数字温度计提取实时环境温度信息的过程,并特别注意到了几个容易忽视的关键点以提高整体系统的可靠性与准确性。
#### 三、综合考虑因素
除了上述提到的具体技术手段之外,还需要考虑到其他潜在的因素比如周围环境变化对于测量精度造成的影响等等。例如极端高低温条件下芯片本身的性能极限;或者是多个同型号设备共存同一总线下可能出现地址冲突等问题都需要提前做好预防准备措施[^4]。
---
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET);
### 使用 `HAL_GPIO_WritePin` 函数控制 DS18B20 的 GPIO 操作
在 STM32 中使用 HAL 库进行 GPIO 控制时,`HAL_GPIO_WritePin` 是一个非常重要的函数。该函数用于设置指定引脚的状态为高电平或低电平。
#### 定义宏来简化操作
为了方便调用和提高代码可读性,通常会定义一些宏来进行常见的 GPIO 操作:
```c
#define DS18B20_DQ_OUT_LOW() do{ HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET); }while(0)
#define DS18B20_DQ_OUT_HIGH() do{ HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET); }while(0)
```
上述两个宏分别用来将数据引脚置为低电平和高电平[^1]。
#### 初始化 GPIO 配置
初始化过程中需要配置好相应的 GPIO 口作为 DS18B20 数据线连接的接口。例如选择了 PE6 这个引脚,则可以在启动文件或其他合适位置完成如下配置:
```c
// 假设已经在硬件描述头文件中声明了这些变量
extern GPIO_TypeDef* DS18B20_GPIO_Port;
extern uint16_t DS18B20_Pin;
void DS18B20_GPIO_Init(void){
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PE6 */
GPIO_InitStruct.Pin = DS18B20_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不带上下拉电阻
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DS18B20_GPIO_Port, &GPIO_InitStruct);
}
```
这段代码实现了对选定 GPIO 引脚的基本参数设定,并将其配置成推挽输出模式以便于后续通信过程中的高低电平切换[^3]。
#### 实际应用案例
当执行温度采集任务时,可以通过下面的方式利用之前定义好的宏快速改变 IO 状态:
```c
short DS18B20_Get_Temperature(void){
// ...其他必要的准备动作...
// 将总线下拉一段时间触发ROM命令序列号匹配周期
DS18B20_DQ_OUT_LOW();
HAL_Delay_us(750);
// 释放总线让其通过外部上拉回到高阻态等待器件响应
DS18B20_DQ_OUT_HIGH();
// ...继续处理接收到的数据...
}
uint8_t DS18B20_Init(void){
// 执行初始化流程包括但不限于复位传感器等步骤
// 发送复位脉冲给设备
DS18B20_DQ_OUT_LOW();
HAL_Delay_us(480);
DS18B20_DQ_OUT_HIGH();
HAL_Delay_us(70);
// 判断是否存在应答信号
if (DS18B20_DQ_IN != RESET){return ERROR;}
return SUCCESS;
}
```
以上展示了如何基于 HAL 库实现基本的单总线协议交互逻辑,其中包含了发送指令前后的 IO 设置以及状态检测等内容。
阅读全文
相关推荐


















