STM32 HAL DS18B20
时间: 2025-06-12 18:45:08 浏览: 15
### STM32 HAL 库与 DS18B20 温度传感器交互的代码实现
在使用 STM32 的 HAL 库与 DS18B20 温度传感器进行交互时,需要通过单总线协议来实现通信。DS18B20 是一种数字温度传感器,支持单总线通信协议,而 STM32 的 GPIO 可以模拟单总线通信。
以下是一个基于 STM32 HAL 库的 DS18B20 温度读取示例代码:
```c
#include "stm32f4xx_hal.h"
#define ONE_WIRE_PIN GPIO_PIN_5
#define ONE_WIRE_PORT GPIOA
// 延时函数
void delay_us(uint32_t us) {
__HAL_TIM_SET_COUNTER(&htim2, 0); // 使用 TIM2 定时器清零计数器
while (__HAL_TIM_GET_COUNTER(&htim2) < us);
}
// 初始化单总线引脚
void OneWire_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能 GPIOA 时钟
GPIO_InitStruct.Pin = ONE_WIRE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(ONE_WIRE_PORT, &GPIO_InitStruct);
}
// 写一个位到单总线上
void OneWire_WriteBit(uint8_t bit) {
if (bit) {
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_RESET); // 拉低
delay_us(10);
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_SET); // 拉高
delay_us(60);
} else {
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_RESET); // 拉低
delay_us(80);
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_SET); // 拉高
delay_us(10);
}
}
// 从单总线上读取一个位
uint8_t OneWire_ReadBit(void) {
uint8_t bit;
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_RESET); // 拉低
delay_us(5);
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_SET); // 拉高
delay_us(5);
bit = HAL_GPIO_ReadPin(ONE_WIRE_PORT, ONE_WIRE_PIN); // 读取引脚状态
delay_us(50);
return bit;
}
// 写一个字节到单总线上
void OneWire_WriteByte(uint8_t byte) {
for (uint8_t i = 0; i < 8; i++) {
OneWire_WriteBit(byte & 0x01);
byte >>= 1;
}
}
// 从单总线上读取一个字节
uint8_t OneWire_ReadByte(void) {
uint8_t byte = 0;
for (uint8_t i = 0; i < 8; i++) {
byte >>= 1;
if (OneWire_ReadBit()) {
byte |= 0x80;
}
}
return byte;
}
// 复位单总线
uint8_t OneWire_Reset(void) {
uint8_t presence = 0;
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_RESET); // 拉低
delay_us(480);
HAL_GPIO_WritePin(ONE_WIRE_PORT, ONE_WIRE_PIN, GPIO_PIN_SET); // 拉高
delay_us(70);
if (!HAL_GPIO_ReadPin(ONE_WIRE_PORT, ONE_WIRE_PIN)) {
presence = 1;
}
delay_us(400);
return presence;
}
// 获取 DS18B20 温度值
float Get_DS18B20_Temperature(void) {
float temperature = 0;
uint16_t raw_data = 0;
OneWire_Reset();
OneWire_WriteByte(0xCC); // 跳过 ROM 命令
OneWire_WriteByte(0x44); // 转换温度命令
OneWire_Reset();
OneWire_WriteByte(0xCC); // 跳过 ROM 命令
OneWire_WriteByte(0xBE); // 读取寄存器命令
raw_data = OneWire_ReadByte(); // 读取低字节
raw_data |= (uint16_t)OneWire_ReadByte() << 8; // 读取高字节
if (raw_data & 0x8000) { // 如果符号位为1(负温度)
raw_data = ~raw_data + 1; // 取补码
temperature = -(float)(raw_data >> 4) + (float)(raw_data & 0xF) * 0.0625;
} else {
temperature = (float)(raw_data >> 4) + (float)(raw_data & 0xF) * 0.0625;
}
return temperature;
}
```
上述代码实现了 DS18B20 的基本功能[^1]。它包括了单总线的初始化、复位、写入和读取操作,并最终获取温度值。
### 注意事项
- 需要配置定时器(如 TIM2)用于微秒级延时。
- GPIO 引脚需要设置为推挽输出模式。
- DS18B20 的供电可以是寄生电源或外部电源,需根据实际硬件设计选择。
阅读全文
相关推荐


















