stm32 hal ds18b20
时间: 2025-05-29 09:02:48 浏览: 21
### STM32 HAL 库与 DS18B20 温度传感器
使用 STM32 的 HAL (Hardware Abstraction Layer) 库可以简化硬件操作流程,而 DS18B20 是一种常见的单总线数字温度传感器。为了实现两者之间的通信并读取温度数据,通常需要配置 GPIO 和定时器来模拟单总线协议。
以下是基于 STM32 HAL 库的一个简单代码示例,用于初始化和读取 DS18B20 数据:
#### 初始化 GPIO 配置
```c
#include "stm32f4xx_hal.h"
#define ONE_WIRE_PIN GPIO_PIN_5
#define ONE_WIRE_PORT GPIOD
void OneWire_Init(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOD_CLK_ENABLE(); // 启用GPIO端口时钟
// 设置为推挽模式
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);
}
```
此部分代码定义了一个函数 `OneWire_Init` 来设置 GPIO 引脚作为输出模式以便于控制 DS18B20 协议中的信号传输[^1]。
#### 实现单总线协议功能
由于 DS18B20 使用的是单总线通讯方式,在标准库或者 HAL 中并没有直接支持该协议的功能模块,则需手动编写相应驱动程序片段如下所示:
```c
// 延迟一段时间
static void delay_us(uint32_t us){
uint32_t ticks_start = HAL_GetTick();
while ((HAL_GetTick() - ticks_start)*1000 < us);
}
// 发送低电平脉冲给设备启动ROM命令序列匹配过程
uint8_t reset_bus(){
uint8_t presence_pulse=0;
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , RESET );
delay_us(480);
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , SET );
delay_us(70);
if(HAL_GPIO_ReadPin(ONE_WIRE_PORT , ONE_WIRE_PIN)==RESET ){
presence_pulse=1;//存在应答信号
}
delay_us(410);
return presence_pulse ;
}
// 写入字节到DS18B20芯片上
void write_byte(uint8_t byte_val){
uint8_t i;
for(i=0;i<8;i++){
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , RESET );
delay_us(10);
if(byte_val&0x01){
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , SET );
}else{
delay_us(60);
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , SET );
}
byte_val >>=1;
delay_us(10);
}
}
// 从DS18B20芯片读取字节
uint8_t read_byte(void){
uint8_t i,j=0;
for(i=0;i<8;i++){
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , RESET );
delay_us(2);
HAL_GPIO_WritePin(ONE_WIRE_PORT , ONE_WIRE_PIN , SET );
j>>=1;
if(HAL_GPIO_ReadPin(ONE_WIRE_PORT , ONE_WIRE_PIN)){
j |=0x80;
}
delay_us(60);
}
return j;
}
```
这些辅助方法实现了基本的单总线交互逻辑,包括重置总线状态检测是否存在连接器件以及逐位发送接收信息等功能[^2]。
#### 主循环中调用上述接口获取当前环境温度值
最后可以在应用程序主入口处通过不断轮询的方式周期性的测量周围空气温湿度情况并向串口打印出来供调试观察之用:
```c
int main(void){
HAL_Init();
SystemClock_Config();//系统时钟配置省略具体细节...
UART_HandleTypeDef huart1;
MX_USART1_UART_Init(&huart1);//UART初始化同样忽略实际参数设定...
OneWire_Init();
float temp_celsius;
char buffer[50];
while (true){
if(reset_bus()){
write_byte(0xCC); /* 跳过 ROM */
write_byte(0x44); /* 开始转换 */
delay_ms(750);
write_byte(0xCC);/*再次跳过*/
write_byte(0xBE);/*读寄存器*/
int lsb =read_byte();
int msb=read_byte();
short raw_temp=(msb<<8)|lsb;
temp_celsius=((float)(raw_temp)/16.0);
sprintf(buffer,"Current Temperature:%.2f C\r\n",temp_celsius);
HAL_UART_Transmit(&huart1,(uint8_t*)buffer,strlen((char const *)buffer),HAL_MAX_DELAY);
}
delay_ms(2000);
}
}
```
以上展示了如何利用STM32微控制器配合其官方提供的HAL抽象层框架快速搭建起针对特定型号外部元件的数据采集解决方案[^3]。
阅读全文
相关推荐


















