# DS18B20 多传感器温度采集与显示系统

基于 STM32F407 的多路 DS18B20 温度采集系统，支持自定义串口通信协议和 OLED 实时显示。

## 项目简介

本系统实现了以下核心功能：
- 自动检测并分配最多 8 个 DS18B20 传感器逻辑地址
- 基于 CRC16-Modbus 的自定义串口通信协议
- 支持串口命令查询指定传感器温度
- SSD1306 OLED 屏幕实时显示所有传感器温度及最近查询结果

## 硬件连接

| 外设       | 引脚                   | 说明                            |
| ---------- | ---------------------- | ------------------------------- |
| DS18B20    | PE6                    | 数据线（需外部 4.7kΩ 上拉电阻） |
| OLED (I2C) | PB10 (SCL), PB11 (SDA) | 7-bit 地址 0x3C                 |
| USART1     | PA9 (TX), PA10 (RX)    | 波特率 115200                   |
| TIM3       | 内部                   | 用于微秒级延时                  |

## 软件架构

```
├── Core/
│   ├── Inc/                      # 头文件目录
│   │   ├── CommProtocol.h        # 通信协议定义
│   │   ├── display_task.h        # 显示任务接口
│   │   ├── DS18B20.h             # DS18B20 驱动
│   │   ├── fonts.h               # 字体定义
│   │   ├── ProtocolTranslation.h # 应用调度
│   │   ├── ring_buffer.h         # 环形缓冲区
│   │   └── ssd1306.h             # OLED 驱动
│   └── Src/                      # 源文件目录
│       ├── main.c                # 主程序
│       ├── CommProtocol.c        # 协议实现（CRC、自动编号、帧解析）
│       ├── display_task.c        # 显示任务（I2C初始化、OLED刷新）
│       ├── DS18B20.c             # DS18B20 时序驱动
│       ├── fonts.c               # 字模数据
│       ├── ProtocolTranslation.c # 应用调度
│       ├── ring_buffer.c         # 环形缓冲区实现
│       └── ssd1306.c             # OLED 驱动实现
└── Drivers/                      # HAL 驱动（STM32Cube 生成）
```

## 串口通信协议

### 帧格式

| 字段     | 长度 | 说明                             |
| -------- | ---- | -------------------------------- |
| SOF      | 1    | 帧头固定 `0xAA`                  |
| 地址     | 1    | 逻辑地址 1~8                     |
| 功能码   | 1    | `0x01` 上报温度，`0x02` 查询温度 |
| 数据长度 | 1    | 数据字节数（查询时为 0）         |
| 数据     | N    | 温度数据（2 字节，单位 0.01℃）   |
| CRC16    | 2    | Modbus CRC16（低字节在前）       |
| EOF      | 1    | 帧尾固定 `0x55`                  |

### 查询命令示例

查询逻辑地址 `0x01` 的温度：
```
AA 01 02 00 [CRC_L] [CRC_H] 55
```

### 响应帧示例

地址 `0x01` 温度 25.50℃（`0x09F6`）：
```
AA 01 01 02 09 F6 [CRC_L] [CRC_H] 55
```

## OLED 显示内容

| 行   | 内容                                              |
| ---- | ------------------------------------------------- |
| 1    | 命令格式提示 `Q:AA ad 02 00 CRCL`                 |
| 2~6  | 传感器地址和温度（每行 2 个，如 `1:25.5 2:26.1`） |
| 6    | 最近查询结果（如 `Last Q:1->25.5C`）              |

## 使用方法

1. **硬件准备**
   - 连接 DS18B20 到 PE6，确保 4.7kΩ 上拉电阻
   - 连接 OLED 到 PB10/PB11
   - 连接 USART1 到串口调试工具

2. **编译与烧录**
   - 使用 STM32CubeIDE 打开项目
   - 编译并烧录到 STM32F407 开发板

3. **串口通信**
   - 串口参数：115200-8-N-1
   - 发送查询帧（HEX 模式），如 `AA 01 02 00 5E 4C 55`（CRC 需计算）
   - 系统会返回对应传感器的温度数据

4. **OLED 显示**
   - 上电后自动检测传感器并显示
   - 每秒刷新一次温度数据
   - 收到查询命令后，最后一行显示最近查询结果

## 关键代码说明

### 自动地址分配
系统启动时自动搜索所有连接的 DS18B20 传感器，并分配逻辑地址 1~8：
```c
void Protocol_Assign_Addresses(void) {
    ds18b20_search_rom();
    Device_Count = DS18B20_SensorNum;
    for (uint8_t i = 0; i < Device_Count; i++) {
        Logic_Addr_Map[i + 1] = i;
    }
}
```

### CRC16-Modbus 校验
所有通信帧均包含 Modbus CRC16 校验，确保数据传输可靠性：
```c
static uint16_t crc16_modbus(uint8_t *buf, uint16_t len);
```

### 环形缓冲区
串口接收使用环形缓冲区，中断服务程序安全写入，主循环处理：
```c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    RingBuffer_Put(&rx_ring, rx_byte);
    HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
}
```

## 注意事项

1. **DS18B20 上拉电阻**：必须外接 4.7kΩ 上拉电阻到 3.3V，否则无法正常工作
2. **CRC 计算**：发送查询命令时需正确计算 CRC16-Modbus，否则帧会被丢弃
3. **OLED I2C 地址**：默认 0x3C（7-bit），如需更改请修改 `ssd1306_defines.h`
4. **传感器数量**：最多支持 8 个 DS18B20 传感器

## 项目文件树

```
.
├── .cproject
├── .project
├── .settings/
├── Core/
│   ├── Inc/                    # 头文件（11 个）
│   └── Src/                    # 源文件（12 个）
├── Drivers/                    # STM32 HAL 驱动
└── .mxproject
```

## 许可证

本项目仅供学习和参考使用。

---

*创建日期：2026-08-03*