打印
[STM32F1]

基于ST MCU的温度传感器数据采集系统实现

[复制链接]
509|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
童雨竹|  楼主 | 2024-10-9 08:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ST MCU广泛应用于各类嵌入式系统中,尤其在工业自动化、家用电器以及传感器应用方面表现出色。本文将介绍如何使用ST MCU实现一个温度传感器数据采集系统,通过简单的编程实现数据的实时读取与显示。

系统设计温度数据采集系统的核心是ST MCU与温度传感器的通信。我们使用 STM32F103C8T6 作为主控芯片,DS18B20 数字温度传感器作为数据采集模块。DS18B20 传感器基于单总线协议,具有精度高、易于集成的特点。

硬件连接
  • STM32F103C8T6 MCU
  • DS18B20 温度传感器
  • 4.7kΩ 上拉电阻
将 DS18B20 的数据引脚连接到 STM32 的某个 GPIO 引脚,数据线上拉 4.7kΩ 电阻。DS18B20 的供电引脚接 3.3V,地引脚接 GND。

使用 STM32CubeMX 进行初始化首先使用 STM32CubeMX 生成基本的系统配置代码。选择使用内部高速时钟(HSE),并初始化相应的 GPIO 引脚。通过 CubeMX 可以快速生成硬件初始化代码,节省了大量的手工配置工作。

主程序实现主程序使用单总线协议读取 DS18B20 的温度数据。这里我们将使用 HAL 库与传感器进行通信。
代码实现
#include "main.h"
#include "onewire.h"
#include "ds18b20.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    float temperature = 0.0;

    // 初始化 DS18B20
    DS18B20_Init();

    while (1) {
        // 读取温度值
        temperature = DS18B20_GetTemp();
        // 打印温度值到串口(或LCD显示)
        printf("Temperature: %.2f°C\n", temperature);
        HAL_Delay(1000); // 延迟1秒,等待下一次读取
    }
}

// DS18B20 初始化函数
void DS18B20_Init(void) {
    Onewire_Init();
    // 其他初始化代码
}

// DS18B20 获取温度值函数
float DS18B20_GetTemp(void) {
    Onewire_Reset();
    Onewire_WriteByte(0xCC); // 跳过ROM指令
    Onewire_WriteByte(0x44); // 启动温度转换
    HAL_Delay(750); // 等待温度转换

    Onewire_Reset();
    Onewire_WriteByte(0xCC); // 跳过ROM指令
    Onewire_WriteByte(0xBE); // 读取温度寄存器

    uint8_t temp_lsb = Onewire_ReadByte();
    uint8_t temp_msb = Onewire_ReadByte();
    int16_t temp = (temp_msb << 8) | temp_lsb;

    return temp * 0.0625; // 转换为实际温度值,分辨率为0.0625°C
}

static void MX_GPIO_Init(void) {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 初始化 GPIO 引脚,用于与 DS18B20 进行通信
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
代码解析
  • 初始化部分:我们在主函数 main 中初始化了系统时钟、GPIO、并调用了 DS18B20 的初始化函数 DS18B20_Init()。这个函数通过初始化单总线协议,确保传感器能够正常工作。
  • 温度读取:在循环体中,每隔 1 秒通过 DS18B20_GetTemp() 函数读取一次温度数据。这个函数首先发送命令让 DS18B20 启动温度转换,然后读取转换后的温度值,并将其转换为实际温度值,单位为摄氏度。
  • 数据输出:这里我们通过 printf 函数将读取到的温度值输出到串口。用户可以将输出重定向到 LCD 或其他显示设备上,实时显示温度数据。


单总线协议解析DS18B20 使用的单总线协议是一种特殊的通信协议,允许多个设备共享同一条数据线。在本例中,我们只使用了一个传感器,因此通信相对简单。单总线协议要求 MCU 先发送复位脉冲,等待传感器的响应,然后发送读取或写入命令。
我们通过 HAL 库封装的 Onewire_Init()、Onewire_WriteByte()、Onewire_ReadByte() 函数来实现这些操作,避免了手动编写低级别的时间控制代码。

系统扩展通过本项目的代码,可以扩展更多的功能。例如:
  • 多传感器读取:在同一条单总线上挂载多个 DS18B20 传感器,通过发送不同的 ROM 命令来获取不同传感器的数据。
  • 数据存储:将读取到的温度数据存储到 EEPROM 或 SD 卡中,方便后续分析。
  • 警报系统:设置温度上下限,当温度超出设定范围时,通过蜂鸣器或 LED 进行报警提示。

总结本文介绍了如何使用 ST MCU 结合 DS18B20 温度传感器实现温度数据采集。通过单总线协议与 HAL 库的结合,我们能够高效地获取传感器数据,并实现实时显示。系统设计简单,易于扩展,非常适合嵌入式系统初学者和开发者学习和使用。


使用特权

评论回复
沙发
公羊子丹| | 2024-10-9 08:05 | 只看该作者
这篇文章太详细了,之前还不会用 DS18B20,现在总算搞明白了。

使用特权

评论回复
板凳
周半梅| | 2024-10-9 08:05 | 只看该作者
我用的也是STM32F103,这个例子真的挺好用的,学习了。

使用特权

评论回复
地板
帛灿灿| | 2024-10-9 08:06 | 只看该作者
代码看起来不错,已经开始动手实验了,谢谢分享!

使用特权

评论回复
5
万图| | 2024-10-9 08:06 | 只看该作者
之前一直搞不清楚单总线协议,这篇文章讲得清楚多了。

使用特权

评论回复
6
Wordsworth| | 2024-10-9 08:07 | 只看该作者
请问怎么在LCD上显示温度呢?能不能再详细点?

使用特权

评论回复
7
Bblythe| | 2024-10-9 08:07 | 只看该作者
STM32和DS18B20的组合还真是不错,做传感器系统很方便。

使用特权

评论回复
8
Pulitzer| | 2024-10-9 08:07 | 只看该作者
我这边接了两个传感器,能不能讲讲多传感器的应用?

使用特权

评论回复
9
Uriah| | 2024-10-9 08:07 | 只看该作者
文章很有帮助,尤其是代码部分,写得很清晰。

使用特权

评论回复
10
Clyde011| | 2024-10-9 08:08 | 只看该作者
DS18B20 的数据读取有时不太稳定,可能是什么原因呢?

使用特权

评论回复
11
略略u| | 2024-10-11 21:48 | 只看该作者
通过简单的编程实现数据的实时读取与显示

使用特权

评论回复
12
Stahan| | 2024-10-13 21:34 | 只看该作者
Clyde011 发表于 2024-10-9 08:08
DS18B20 的数据读取有时不太稳定,可能是什么原因呢?

刚开始的前几个数可以忽略掉

使用特权

评论回复
13
Stahan| | 2024-10-13 21:35 | 只看该作者
单总线对时间把握要严格点

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

3751

帖子

0

粉丝