STM32 HAL库 DS18B20驱动实现

发布于:2025-04-17 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、DS18B20 简介

DS18B20 是由 Dallas Semiconductor 公司生产的单总线数字温度传感器。它具有以下特点:

  • 单总线接口:仅需一个引脚即可与微控制器进行通信,减少了硬件连接的复杂度。
  • 数字输出:直接输出数字温度值,无需额外的模数转换电路。
  • 精度高:可编程分辨率为 9 - 12 位,对应的温度精度分别为 0.5°C、0.25°C、0.125°C 和 0.0625°C。
  • 宽温度范围:测量范围为 -55°C 到 +125°C。

二、硬件连接

在使用 STM32F407 与 DS18B20 进行连接时,需要将 DS18B20 的数据线(DQ)连接到 STM32F407 的一个 GPIO 引脚。同时,DS18B20 的电源引脚(VDD)接 3.3V 或 5V,接地引脚(GND)接地。为了保证通信的稳定性,通常需要在 DQ 引脚上拉一个 4.7KΩ 的电阻到电源。

三、驱动代码实现

1. 初始化 GPIO 引脚

首先,需要初始化与 DS18B20 连接的 GPIO 引脚。以下是使用 STM32Cube HAL 库进行初始化的代码:

#include "stm32f4xx_hal.h"

#define DS18B20_PORT GPIOA
#define DS18B20_PIN GPIO_PIN_0

void DS18B20_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin = DS18B20_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);
}
2. 单总线复位脉冲

DS18B20 的通信需要先发送一个复位脉冲,以检测设备是否存在。以下是复位脉冲的代码实现:

uint8_t DS18B20_Reset(void) {
    uint8_t presence;

    // 拉低总线480 - 960us
    HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);
    HAL_Delay(1);

    // 释放总线,等待15 - 60us
    HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);
    HAL_Delay(1);

    // 读取DS18B20的存在脉冲
    presence = HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN);
    HAL_Delay(4);

    return presence;
}
3. 写一位数据

向 DS18B20 写入一位数据的代码如下:

void DS18B20_WriteBit(uint8_t bit) {
    if (bit) {
        // 写1
        HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);
        __asm("nop");
        __asm("nop");
        HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);
        HAL_Delay(1);
    } else {
        // 写0
        HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);
        __asm("nop");
        __asm("nop");
    }
}
4. 读一位数据

从 DS18B20 读取一位数据的代码如下:

uint8_t DS18B20_ReadBit(void) {
    uint8_t bit;

    // 拉低总线1 - 15us
    HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_RESET);
    __asm("nop");
    __asm("nop");

    // 释放总线,等待1 - 15us后读取数据
    HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, GPIO_PIN_SET);
    __asm("nop");
    __asm("nop");
    bit = HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN);
    HAL_Delay(1);

    return bit;
}
5. 写一个字节数据

向 DS18B20 写入一个字节数据的代码如下:

void DS18B20_WriteByte(uint8_t byte) {
    uint8_t i;

    for (i = 0; i < 8; i++) {
        DS18B20_WriteBit(byte & 0x01);
        byte >>= 1;
    }
}
6. 读一个字节数据

从 DS18B20 读取一个字节数据的代码如下:

uint8_t DS18B20_ReadByte(void) {
    uint8_t i, byte = 0;

    for (i = 0; i < 8; i++) {
        byte >>= 1;
        if (DS18B20_ReadBit()) {
            byte |= 0x80;
        }
    }

    return byte;
}
7. 启动温度转换

启动 DS18B20 进行温度转换的代码如下:

void DS18B20_StartConversion(void) {
    DS18B20_Reset();
    DS18B20_WriteByte(0xCC); // 跳过ROM操作
    DS18B20_WriteByte(0x44); // 启动温度转换
}
8. 读取温度值

读取 DS18B20 的温度值的代码如下:

float DS18B20_ReadTemperature(void) {
    uint8_t temp_l, temp_h;
    int16_t temp;
    float temperature;

    DS18B20_StartConversion();
    HAL_Delay(750); // 等待转换完成

    DS18B20_Reset();
    DS18B20_WriteByte(0xCC); // 跳过ROM操作
    DS18B20_WriteByte(0xBE); // 读取温度寄存器

    temp_l = DS18B20_ReadByte();
    temp_h = DS18B20_ReadByte();

    temp = (temp_h << 8) | temp_l;
    temperature = (float)temp / 16.0;

    return temperature;
}

四、测试代码

以下是一个简单的测试代码,用于在主函数中调用 DS18B20 驱动函数并打印温度值:

#include "stm32f4xx_hal.h"
#include <stdio.h>

#define DS18B20_PORT GPIOA
#define DS18B20_PIN GPIO_PIN_0

// 前面定义的驱动函数

int main(void) {
    HAL_Init();
    DS18B20_GPIO_Init();

    while (1) {
        float temperature = DS18B20_ReadTemperature();
        printf("Temperature: %.2f °C\n", temperature);
        HAL_Delay(1000);
    }
}

五、代码解释

  1. GPIO 初始化:将与 DS18B20 连接的 GPIO 引脚初始化为开漏输出模式,以适应单总线通信的要求。
  2. 复位脉冲:通过拉低总线一段时间,然后释放总线,等待 DS18B20 返回存在脉冲,以检测设备是否正常工作。
  3. 读写位和字节:通过控制总线的高低电平,实现向 DS18B20 写入一位或一个字节的数据,以及从 DS18B20 读取一位或一个字节的数据。
  4. 启动温度转换:发送特定的命令字节,启动 DS18B20 进行温度转换。
  5. 读取温度值:在温度转换完成后,读取温度寄存器的值,并将其转换为实际的温度值。

六、注意事项

  • 延时时间:DS18B20 的通信协议对延时时间要求较高,需要确保延时时间的准确性。在上述代码中,使用了HAL_Delay()函数进行延时,实际应用中可以根据需要进行调整。
  • 上拉电阻:为了保证通信的稳定性,需要在 DQ 引脚上拉一个 4.7KΩ 的电阻到电源。
  • 温度转换时间:DS18B20 的温度转换时间与分辨率有关,最高分辨率(12 位)下的转换时间为 750ms。在读取温度值之前,需要等待转换完成。

七、总结

通过以上代码,你可以实现基于 STM32F407 HAL 库的 DS18B20 驱动。该驱动代码可以方便地集成到你的项目中,用于实时监测环境温度。在实际应用中,你可以根据需要对代码进行优化和扩展,例如添加错误处理、多设备支持等功能。

希望以上内容对你有所帮助。如果你在使用过程中遇到任何问题,可以随时进行提问。


网站公告

今日签到

点亮在社区的每一天
去签到