STM32F4 ds18b20
时间: 2025-05-05 07:04:22 浏览: 33
### STM32F4 上使用 DS18B20 温度传感器的驱动实现
#### 一、硬件连接
在 STM32F4 微控制器上使用 DS18B20 数字温度传感器时,需将其通过单线接口 (One-Wire) 连接到微控制器的一个 GPIO 引脚。通常推荐使用外部上拉电阻来确保信号稳定性[^1]。
以下是典型的硬件连接方式:
- **VDD**: 接到电源正极 (+3.3V 或 +5V),具体取决于供电需求。
- **GND**: 接地。
- **DQ**: 单线数据引脚,连接至 STM32 的某个 GPIO 引脚(例如 PA0),并通过一个约 4.7kΩ 的上拉电阻连接到 VCC。
---
#### 二、软件初始化与配置
为了使能 One-Wire 总线协议,在 STM32 中需要完成以下操作:
1. **GPIO 初始化**
将用于通信的 GPIO 配置为推挽模式或开漏输出模式,并设置初始状态为高电平。这一步可通过 HAL 库或其他底层库实现。
2. **延时函数**
提供精确的时间延迟功能以满足 DS18B20 的时序要求。可以利用 `HAL_Delay()` 函数或者编写更精细的微秒级延时函数。
3. **总线复位**
发送复位脉冲给 DS18B20 设备并等待其响应。如果设备存在,则会返回低电平作为应答信号[^2]。
```c
// 定义宏和变量
#define DS18B20_PIN GPIO_PIN_x // 替换为实际使用的 GPIO PIN 编号
#define DS18B20_PORT GPIOA // 替换为实际使用的端口名称
void DS18B20_Init() {
__HAL_RCC_GPIOA_CLK_ENABLE(); // 启用 GPIOA 时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 设置为输入模式
GPIO_InitStruct.Pin = DS18B20_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);
}
u8 DS18B20_Reset(void) {
u8 retry = 0;
// 切换到输出模式
HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);
// 延迟至少 480us 来发出复位脉冲
for(int i=0;i<12;i++) asm("nop");
// 转回输入模式
HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);
// 等待 DS18B20 回应
while(HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN) && retry < 200){
delay_us(1);
retry++;
}
if(retry >= 200) return 1; // 如果超时则表示无器件
retry = 0;
while(!(HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN)) && retry < 240){
delay_us(1);
retry++;
}
if(retry >= 240) return 1; // 若长时间保持低电平也视为错误
return 0; // 成功检测到器件
}
```
---
#### 三、读取温度数据
要获取当前环境中的温度值,按照如下流程执行命令序列:
1. 复位总线;
2. 发送跳过 ROM 命令 (`0xCC`);
3. 发起转换指令 (`0x44`);
4. 等待一段时间让芯片完成 A/D 转换过程;
5. 再次复位后依次发送读寄存器命令 (`0xBE`), 并接收两个字节的结果数据。
下面展示了一个简化版的例子用来说明这些步骤:
```c
float DS18B20_ReadTemp(){
uint8_t data[2];
float temp;
// 步骤1: Reset Bus
if(DS18B20_Reset()) return -1000;
// Step2&3 Send SkipROM and ConvertT Command
DS18B20_SendCmd(0xCC);
DS18B20_SendCmd(0x44);
// Wait conversion time (~750ms max)
HAL_Delay(800);
// Repeat reset before reading temperature value.
if(DS18B20_Reset()) return -1000;
DS18B20_SendCmd(0xCC);
DS18B20_SendCmd(0xBE);
// Read two bytes of raw temperature data from scratchpad memory locations
data[0]=DS18B20_ReadByte();
data[1]=DS18B20_ReadByte();
// Calculate actual temperature based on datasheet formula
int16_t raw_temp=(data[1]<<8)|data[0];
temp=((float)(raw_temp)/16.0f);
return temp;
}
```
上述代码片段实现了基本的功能逻辑,但可能还需要针对特定应用场景做进一步优化调整[^3]。
---
#### 四、注意事项
- 确保所选 MCU 工作频率能够支持所需的定时精度。
- 使用中断机制代替轮询可提高效率减少 CPU 开销。
- 对于多节点网络情况下的地址解析问题也需要额外考虑进去。
---
阅读全文
相关推荐


















