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

[复制链接]
2010|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 库与传感器进行通信。
代码实现
  1. #include "main.h"
  2. #include "onewire.h"
  3. #include "ds18b20.h"

  4. void SystemClock_Config(void);
  5. static void MX_GPIO_Init(void);

  6. int main(void) {
  7.     HAL_Init();
  8.     SystemClock_Config();
  9.     MX_GPIO_Init();

  10.     float temperature = 0.0;

  11.     // 初始化 DS18B20
  12.     DS18B20_Init();

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

  21. // DS18B20 初始化函数
  22. void DS18B20_Init(void) {
  23.     Onewire_Init();
  24.     // 其他初始化代码
  25. }

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

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

  35.     uint8_t temp_lsb = Onewire_ReadByte();
  36.     uint8_t temp_msb = Onewire_ReadByte();
  37.     int16_t temp = (temp_msb << 8) | temp_lsb;

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

  40. static void MX_GPIO_Init(void) {
  41.     __HAL_RCC_GPIOA_CLK_ENABLE();
  42.     GPIO_InitTypeDef GPIO_InitStruct = {0};

  43.     // 初始化 GPIO 引脚,用于与 DS18B20 进行通信
  44.     GPIO_InitStruct.Pin = GPIO_PIN_1;
  45.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  46.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  47.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  48.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  49. }
代码解析
  • 初始化部分:我们在主函数 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 | 显示全部楼层
代码看起来不错,已经开始动手实验了,谢谢分享!
万图 发表于 2024-10-9 08:06 | 显示全部楼层
之前一直搞不清楚单总线协议,这篇文章讲得清楚多了。
Wordsworth 发表于 2024-10-9 08:07 | 显示全部楼层
请问怎么在LCD上显示温度呢?能不能再详细点?
Bblythe 发表于 2024-10-9 08:07 | 显示全部楼层
STM32和DS18B20的组合还真是不错,做传感器系统很方便。
Pulitzer 发表于 2024-10-9 08:07 | 显示全部楼层
我这边接了两个传感器,能不能讲讲多传感器的应用?
Uriah 发表于 2024-10-9 08:07 | 显示全部楼层
文章很有帮助,尤其是代码部分,写得很清晰。
Clyde011 发表于 2024-10-9 08:08 | 显示全部楼层
DS18B20 的数据读取有时不太稳定,可能是什么原因呢?
略略u 发表于 2024-10-11 21:48 来自手机 | 显示全部楼层
通过简单的编程实现数据的实时读取与显示
Stahan 发表于 2024-10-13 21:34 | 显示全部楼层
Clyde011 发表于 2024-10-9 08:08
DS18B20 的数据读取有时不太稳定,可能是什么原因呢?

刚开始的前几个数可以忽略掉
Stahan 发表于 2024-10-13 21:35 | 显示全部楼层
单总线对时间把握要严格点
您需要登录后才可以回帖 登录 | 注册

本版积分规则

172

主题

6228

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部