# TempController **Repository Path**: yanweiwei_1981/temp-controller ## Basic Information - **Project Name**: TempController - **Description**: No description available - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-28 - **Last Updated**: 2026-07-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TempController — 微型金属浴精密温控模块 ## 项目介绍 **TempController** 是一款基于 STM32F103C8T6 的微型精密温度控制模块,专为实验室比色皿溶液恒温场景设计。系统采用铜金属浴导热 + PID 闭环控制架构,配合 TMP117 高精度数字温度传感器,实现 **±0.1°C** 的温控精度,可广泛应用于生物化学实验中的酶反应、PCR 孵育、比色分析等对温度敏感的操作。 ### 核心亮点 - **高精度传感**:TI TMP117 数字传感器,出厂校准精度 ±0.1°C,分辨率 0.0078°C - **PID 闭环控制**:可调参数的增量式 PID 控制器,带积分抗饱和保护 - **双协议通信**:上位机 ASCII 协议 (UART1) + Modbus RTU 从站 (UART3),可接入 PLC/SCADA 系统 - **软/硬 SPI 双模式 OLED**:宏切换即可适配不同引脚布局,无需改代码 - **参数持久化**:内部 Flash 模拟 EEPROM + CRC32 校验,掉电不丢失 - **独立看门狗**:IWDG 约 409ms 超时保护,防止温控失控 - **完整上位机**:Python + tkinter + matplotlib 实时温度曲线监控 --- ## 软件架构 项目采用**三层模块化架构**,自底向上依次为: ``` ┌──────────────────────────────────────────────────┐ │ 应用层 │ │ temp_control (温控状态机) + pid (PID运算) │ │ oled (显示管理, 3种模式) │ ├──────────────────────────────────────────────────┤ │ 协议层 │ │ ascii_protocol (上位机) + modbus_rtu (PLC/SCADA) │ ├──────────────────────────────────────────────────┤ │ 驱动层 │ │ tmp117 (I2C传感) + eeprom_store (Flash存储) │ │ stm32f1xx_hal_msp (外设初始化) │ ├──────────────────────────────────────────────────┤ │ HAL 层 │ │ STM32F1xx HAL + CMSIS (STM32 官方库) │ └──────────────────────────────────────────────────┘ ``` ### 目录结构 ``` TempController/ ├── Core/ # 核心源码 │ ├── Inc/ # 头文件 (10个) │ │ ├── main.h # 主配置:MCU型号、外设、引脚、SPI模式宏 │ │ ├── tmp117.h / oled.h / pid.h / temp_control.h │ │ ├── eeprom_store.h / ascii_protocol.h / modbus_rtu.h │ │ ├── stm32f1xx_hal_conf.h / stm32f1xx_it.h │ └── Src/ # 源文件 (11个) │ ├── main.c # 主入口:系统初始化 + 主循环 (100ms周期) │ ├── tmp117.c / oled.c / pid.c / temp_control.c │ ├── eeprom_store.c / ascii_protocol.c / modbus_rtu.c │ ├── stm32f1xx_hal_msp.c / stm32f1xx_it.c / system_stm32f1xx.c ├── Drivers/ # STM32 官方驱动库 │ ├── CMSIS/ # Cortex-M3 软件接口标准 │ └── STM32F1xx_HAL_Driver/ # STM32F1 HAL 硬件抽象层 ├── MDK-ARM/ # Keil MDK-ARM 工程 │ ├── TempController.uvprojx # Keil 工程文件 │ └── startup_stm32f103xb.s # 启动汇编文件 ├── PC_Test_Software/ # Python 上位机测试软件 │ ├── main.py # tkinter GUI 主程序 │ ├── protocol.py # ASCII/Modbus 协议封装 │ └── requirements.txt # Python 依赖列表 ├── Docs/ # 项目文档 │ ├── 需求文档.md # 完整需求规格说明 (V1.4) │ └── 微型金属浴热控制项目(STM32F103).md # 开发记录 ├── TempController.ioc # STM32CubeMX 项目配置文件 └── README.md ``` --- ## 硬件配置 ### MCU 平台 | 参数 | 值 | |------|-----| | 型号 | STM32F103C8T6 | | 内核 | ARM Cortex-M3, 72 MHz | | Flash / RAM | 64 KB / 20 KB | | 封装 | LQFP-48 | ### 外设引脚分配 | 外设 | 功能 | 引脚 | 配置参数 | |------|------|------|----------| | **TMP117** | 温度传感器 | PB6 (SCL), PB7 (SDA) | I2C1, 100 kHz, 地址 0x48 | | **OLED** | 显示 | 见下方 SPI 模式选择 | SPI1, 128x64 像素, SSD1315 | | **Heater** | PWM 加热 | PA0 | TIM2 CH1, 1 kHz, 0-1000 分辨率 | | **上位机** | ASCII 协议通信 | PA9 (TX), PA10 (RX) | USART1, 9600 bps, 8N1 | | **Modbus** | RS-485 接口 | PB10 (TX), PB11 (RX) | USART3, 9600 bps, 8N1 | | **LED** | 状态指示 | PC13 | GPIO Output (低电平亮) | | **CAN** | 预留总线 | PB8 (RX), PB9 (TX) | CAN1, Normal/Loopback 可选 | ### SPI 模式切换 OLED 驱动支持**软件 SPI 和硬件 SPI 双模式**,通过 `Core/Inc/main.h` 中宏一键切换: ```c // 硬件 SPI1 模式 (当前配置) —— PA5(SCK), PA7(MOSI) #define OLED_SPI_MODE OLED_SPI_MODE_HARDWARE // 软件 bit-bang 模式 —— PA1(SCK), PA2(SDA) // #define OLED_SPI_MODE OLED_SPI_MODE_SOFTWARE ``` > **注意**:切换宏后需对应调整物理接线。DC、RES、CS 两个模式共用 PA3、PA8、PA15。 ### 加热系统 - **金属浴体**:紫铜材质 (20×20×45 mm 外部, 12×12×40 mm 内腔) - **加热片**:薄膜电阻 48Ω @ 12V, 峰值功率 3–5W, 恒温功耗 <1W - **控制方式**:PWM 输出经 MOSFET 驱动加热片 ### 时钟树 ``` HSE 8MHz → PLL ×9 → SYSCLK 72MHz ├── HCLK 72MHz ├── PCLK1 36MHz (APB1: I2C, USART2/3, TIM2-4) └── PCLK2 72MHz (APB2: USART1, SPI1, GPIO) ``` --- ## 安装教程 ### 1. 环境准备 - **IDE**:Keil MDK-ARM 5.x(推荐 5.36+) - **设备包**:Keil.STM32F1xx_DFP.2.x - **烧录工具**:ST-Link/V2 或 J-Link - **串口工具**:任意串口调试助手(或使用项目自带的 Python 上位机) ### 2. 编译与烧录 ```bash # 1. 打开 Keil 工程 # 双击 MDK-ARM/TempController.uvprojx # 2. 编译 (Build 或 Rebuild) # 快捷键: F7 (Build) / Ctrl+Alt+F7 (Rebuild) # 3. 连接 ST-Link 后下载 # 快捷键: F8 (Download), 或菜单 Flash → Download # 预期输出: Build Output 显示 0 Error(s), 0 Warning(s) ``` > **注意**: 首次编译需确保 Keil 已安装 STM32F1xx 设备包。如缺包,可在 Pack Installer 中检索安装。 ### 3. 上位机安装 (可选) ```bash cd PC_Test_Software pip install -r requirements.txt python main.py ``` 依赖包: `pyserial`, `matplotlib`, `tkinter`(Python 3.7+ 推荐)。 --- ## 使用说明 ### 1. 基本操作流程 1. **上电自检**:LED 闪烁 3 次确认程序启动,OLED 显示初始化信息 2. **串口确认**:USART1 输出启动诊断信息(系统时钟、传感器状态等) 3. **设定温度**:通过上位机 ASCII 命令 `:S037.5\r\n` 设置目标温度 4. **启动温控**:命令 `:M1\r\n` 进入 RUNNING 状态,PID 开始调节 5. **监控运行**:OLED 实时显示当前/目标温度,上位机可查看温度曲线 ### 2. 系统状态机 ``` INIT ──→ IDLE ──→ RUNNING ──→ ALARM ──→ ERROR ↑ │ ↑ │ └─────────────────┘ └───────────────────┘ (复位/停止) (严重故障) ``` - **INIT**:上电初始化 → 自动进入 IDLE - **IDLE**:等待指令,PWM 输出关闭 - **RUNNING**:PID 闭环控温,每 100ms 更新一次 PWM - **ALARM**:触发告警但继续运行(如温度偏差过大),LED 快速闪烁 - **ERROR**:不可恢复错误(如传感器故障),PWM 强制关闭 ### 3. ASCII 协议命令速查 | 命令 | 功能 | 格式示例 | 响应示例 | |------|------|----------|----------| | `R` | 读取当前温度 | `:R\r\n` | `:R+25.30\r\n` | | `S` | 设定目标温度 | `:S037.5\r\n` | `:ACK\r\n` | | `M` | 运行/停止 | `:M1\r\n` (启动) / `:M0\r\n` (停止) | `:ACK\r\n` | | `P` | 读取 PWM 占空比 | `:P\r\n` | `:P050\r\n` (50%) | | `G` | 获取完整状态 | `:G\r\n` | JSON 格式完整状态 | | `K` | 设置 PID 参数 | `:K1.5,0.2,0.3\r\n` | `:ACK\r\n` | | `H`/`L` | 设置高/低温告警阈值 | `:H50.0\r\n` | `:ACK\r\n` | | `O`/`B`/`I` | OLED 开关/亮度/模式 | `:B128\r\n` | `:ACK\r\n` | | `W` | 保存参数到 EEPROM | `:W\r\n` | `:ACK\r\n` | | `D` | 恢复默认参数 | `:D\r\n` | `:ACK\r\n` | | `T` | 温度偏移校准 | `:T+0.5\r\n` | `:ACK\r\n` | | `V` | 查询固件版本 | `:V\r\n` | `:V1.0.0\r\n` | | `A` | 读取告警状态 | `:A\r\n` | `:A03\r\n` (bit: 高温|低温|传感器) | ### 4. Modbus RTU 寄存器映射(从站地址 0x01) | 地址 | 名称 | 类型 | 读写 | 说明 | |------|------|------|------|------| | 0x00 | 当前温度 | INT16×100 | R | 实际温度值=寄存器值/100 | | 0x01 | 目标温度 | INT16×100 | R/W | 设定温度值=寄存器值/100 | | 0x02 | 温度偏移 | INT16×100 | R/W | 校准偏移量 | | 0x03 | PWM 输出 | UINT16 | R | 0–1000 对应 0%–100% | | 0x04 | 运行模式 | UINT16 | R/W | 0=停止, 1=运行 | | 0x05 | 高温告警阈值 | UINT16 | R/W | | | 0x06 | 低温告警阈值 | UINT16 | R/W | | | 0x07-0x09 | PID Kp/Ki/Kd | UINT16×1000 | R/W | | | 0x0A | OLED 亮度 | UINT16 | R/W | 0–255 | | 0x0B | OLED 模式 | UINT16 | R/W | 0=温度, 1=状态, 2=简洁 | | 0x0C | 固件版本 | BCD | R | 如 0x0100 = V1.00 | ### 5. LED 状态指示 | 状态 | LED 行为 | 含义 | |------|----------|------| | 启动中 | 快闪×3 (100ms) | 上电初始化确认 | | 正常运行 | 500ms 周期翻转 | 系统运行正常 | | 告警 | 100ms 快速闪烁 | 温度偏差超过阈值 | | 致命错误 | 50ms 极快闪烁 | 传感器故障/硬件异常 | ### 6. 看门狗说明 独立看门狗 (IWDG) 约 409ms 超时,主循环每 100ms 喂狗一次。若主循环卡死超过 ~409ms,系统将自动复位,PWM 输出关闭,防止加热失控。 > **安全设计**:IWDG 在所有外设初始化完成、PWM 已配置安全默认值后才启动,避免上电初始化阶段误复位。 --- ## 上位机测试软件 `PC_Test_Software/` 提供完整的 Python 上位机调试工具: - **实时温度曲线**:蓝色实线 (当前温度) + 红色虚线 (目标温度),带网格和坐标轴 - **交互操作**:鼠标十字跟随线、框选放大、滚轮缩放 - **参数面板**:目标温度、运行模式、PID 参数、告警阈值设定 - **OLED 控制**:远程开关、亮度滑块、显示模式切换 - **历史记录**:可选 30 秒至 12 小时滚动时间窗口 - **通信日志**:实时显示 ASCII 协议收发数据 - **模拟模式**:无硬件连接时自动生成温度曲线用于软件调试 ### 启动步骤 ```bash cd PC_Test_Software pip install -r requirements.txt python main.py ``` --- ## 参与贡献 1. Fork 本仓库 2. 新建功能分支 (`git checkout -b Feat_xxx`) 3. 提交代码 (`git commit -m 'feat: 新增xxx功能'`) 4. 推送到远程 (`git push origin Feat_xxx`) 5. 新建 Pull Request 到 master 分支 ### 代码规范 - C 代码遵循 STM32 HAL 库命名风格 - Python 代码遵循 PEP 8 规范 - 提交信息格式:`: <简短描述>`(如 `feat:`、`fix:`、`chore:`、`docs:`) --- ## 注意事项 1. **传感器配置**:若未焊接 TMP117 传感器,系统会自动进入模拟模式,温度数据为软件生成值 2. **SPI 模式切换**:修改 `main.h` 第 105 行的 `OLED_SPI_MODE` 宏后需重新编译,并确认物理接线匹配 3. **CAN 总线**:无外部 CAN 收发器的环境下建议设为 Loopback 模式,否则会影响正常初始化 4. **加热安全**:PWM 输出连接加热片前务必确认 MOSFET 驱动电路完好,避免短路 5. **Flash 擦写寿命**:STM32F103 内部 Flash 约 10,000 次擦写寿命,"保存参数"操作应避免高频调用