news 2026/10/29 6:55:10

STM32F103野火指南者温度读取工程包实战:从环境配置到串口输出

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F103野火指南者温度读取工程包实战:从环境配置到串口输出

简介:这份资源面向正在学习STM32嵌入式开发、需要动手实践外设驱动的初学者与进阶者,围绕野火STM32F103指南者开发板,提供一套简易温度读取的完整工程实现,可用于课程实验、自学练手或项目参考。压缩包共366个文件,约17.18MB,以C语言源文件与头文件为主体,涵盖stm32f10x_adc、tim、rcc、usart等标准外设库驱动,并包含Keil工程文件、编译中间产物、hex烧录文件及少量说明文档,目录结构保留了完整的工程组织方式,便于直接打开编译与二次修改。目前已有51人学习下载。读者可从中获得温度采集的完整代码框架、ADC采样与串口输出等模块的调用思路,以及标准库工程的搭建与调试参考,适合对照开发板逐步理解外设配置流程,快速上手STM32基础项目开发。

1. 从一份野火指南者工程包说起:STM32F103 读温度到底难在哪

很多人第一次拿到「基于 STM32 的简易温度读取」这类工程包,第一反应是打开 Keil 直接编译下载,结果要么卡在芯片包没装、要么串口助手一片乱码,最后怀疑代码本身有问题。实际上,STM32F103 读温度这件事,硬件链路和软件链路各有一半坑:硬件上要确认传感器是板载的还是外接的、供电和上拉电阻对不对;软件上要确认用的是标准库还是 HAL 库、时钟树配没配对、串口波特率是否一致。这份基于野火 STM32F103 指南者的工程包,价值就在于它把「最小可运行的温度采集 + 串口输出」这条链路完整封好了,适合刚上手 STM32F103 最小系统、想先跑通一个完整闭环再往深里做的从业者。它不追求功能多,追求的是你能在半小时内看到温度数值从串口稳定吐出来,而不是在环境配置上耗掉一整天。

2. 拆开工程包:文件结构、外设依赖与选型逻辑

2.1 工程目录里每个文件夹在干什么

拿到压缩包解压后,常见做法是先别急着打开工程文件,而是把目录结构扫一遍。野火系工程一般会分成几个固定区域:USER放main.c和中断服务函数,HARDWARE放外设驱动,SYSTEM放延时和串口底层,CORE放内核启动文件,STM32F10x_FWLib放标准库源码。这个划分不是随便定的,它对应的是「应用逻辑 / 硬件抽象 / 系统支撑 / 芯片底层」四层,改代码时能快速定位该动哪一层。

目录典型内容改动频率
USERmain.c、stm32f10x_it.c高
HARDWARE传感器驱动、LCD、LED中
SYSTEMdelay.c、usart.c、sys.c低
COREcore_cm3.c、startup_stm32f10x_md.s几乎不动
STM32F10x_FWLib标准外设库不动

提示:如果解压后看到的是.uvprojx而不是.uvproj,说明是较新的 Keil MDK 工程格式,用 MDK5 打开更稳。

2.2 温度传感器走的是哪条总线

STM32F103 读温度,常见方案有三种:片内温度传感器(接 ADC 内部通道)、DS18B20(单总线)、LM75 或 TMP102(I2C)。这份工程包标题写的是「简易温度读取」,结合野火指南者的板载资源,大概率走的是片内 ADC 温度传感器通道或者外接 DS18B20。片内方案的好处是不用额外接线,缺点是精度差、需要校准;DS18B20 精度够用,但时序要求严,延时函数稍微不准就读出 85 这个经典错误值。

判断方法很简单:打开HARDWARE目录,看有没有ds18b20.c或者adc_temperature.c这类文件。如果是 ADC 方案,重点看ADC_Channel_x选的是哪个通道;如果是 DS18B20,重点看delay_us的精度。这一步决定了后面调试时该盯哪里。

2.3 为什么用标准库而不是 HAL

野火 F103 指南者的老工程大多基于标准外设库(SPL),不是 HAL。原因很实际:F103 资源小、标准库代码量少、执行路径清晰,适合教学和快速验证。HAL 库抽象层厚,移植方便但代码体积大,在 F103 这种 64KB Flash 的片子上容易吃紧。如果你后续想换到 CubeMX 生成工程,注意标准库和 HAL 的初始化写法完全不兼容,不能混着抄。

常见做法是:先用这份标准库工程把温度读通,确认硬件没问题,再决定要不要迁到 HAL。迁移时重点重写GPIO_Init、USART_Init、ADC_Init这几块,业务逻辑基本可以保留。

3. 从零跑通:Keil 环境、时钟配置与串口输出

3.1 装芯片包和打开工程

第一步不是写代码,是把环境补齐。Keil MDK5 默认不带 STM32F1 的器件支持包,需要单独装Keil.STM32F1xx_DFP。装完之后打开工程,如果弹出「Device not found」,八成是包没装或者装错版本。

# 确认芯片包安装路径(Windows 默认) C:\Keil_v5\ARM\PACK\Keil\STM32F1xx_DFP\ # 目录下应能看到 .pdsc 文件和 Flash 算法文件夹

逻辑说明:Keil 通过.pdsc文件识别器件型号和 Flash 烧写算法。如果这个目录为空,编译能过但下载会失败。参数上注意 DFP 版本和 MDK 版本的兼容性,太新的包在老 MDK 上可能不认。

3.2 时钟树:72MHz 是怎么来的

STM32F103 标准库工程一般把系统时钟配到 72MHz,路径是 HSE(8MHz 外部晶振)→ PLL 9 倍频 → 72MHz。这段代码在system_stm32f10x.c里,通过SetSysClockTo72()完成。如果外部晶振没起振,芯片会回退到 HSI(8MHz 内部 RC),此时串口波特率会整体偏掉,表现为乱码。

// system_stm32f10x.c 中的关键判断 if (HSEStatus == (uint32_t)0x01) { // HSE 起振成功,走 PLL 到 72MHz RCC->CFGR |= (uint32_t)RCC_CFGR_PLLMULL9; } else { // HSE 失败,保持 HSI,此时系统频率只有 8MHz }

逻辑说明:HSEStatus来自RCC_CR寄存器的HSERDY位。如果这里走了 else 分支,后面所有基于 72MHz 算出来的延时和波特率全错。排查时可以先点灯确认程序在跑,再用示波器或逻辑分析仪看串口波形周期,反推实际时钟。

3.3 串口配置与 printf 重定向

温度值要能看到,靠的是串口。标准库工程一般用 USART1,PA9 做 TX、PA10 做 RX,波特率 115200。关键一步是重定向printf,否则你只能自己拼字符串。

// usart.c 中重定向 printf 到 USART1 int fputc(int ch, FILE *f) { while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1, (uint8_t)ch); return ch; }

逻辑说明:USART_FLAG_TC是发送完成标志,等它置位再写下一个字节,避免数据覆盖。参数上注意在 Keil 的 Target 选项里勾选Use MicroLIB,否则printf重定向可能不生效。串口助手那边波特率、数据位 8、停止位 1、无校验,和代码里USART_InitStructure保持一致。

3.4 温度读取主循环

主循环通常很短:初始化外设,然后 while(1) 里读温度、格式化、打印、延时。

int main(void) { float temp; delay_init(); // 延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); // 串口初始化 DS18B20_Init(); // 或 ADC_Temp_Init() while (1) { temp = DS18B20_Get_Temp(); // 读温度 printf("Temp: %.1f C\r\n", temp); delay_ms(1000); } }

逻辑说明:delay_init()必须在串口和传感器初始化之前,因为 DS18B20 的时序依赖微秒延时。printf里的%.1f在 MicroLIB 下支持浮点,如果没勾 MicroLIB,浮点打印可能输出空白或乱码,这时改成整数部分和小数部分分开打印更稳。

4. 避坑与排查:温度读不出、串口乱码、下载失败

4.1 串口助手全是乱码

现象:打开串口助手,收到的不是温度字符串,而是一堆不可读字符。原因通常是波特率不匹配或系统时钟不是 72MHz。先确认串口助手波特率和代码里uart_init参数一致,再检查外部晶振是否起振。如果 HSE 没起振,系统跑在 8MHz,实际波特率会变成设定值的约 1/9。解决方法是换一个 8MHz 晶振,或者临时改用 HSI 并在代码里重新计算波特率。

4.2 DS18B20 一直返回 85

现象:温度值恒定显示 85.0,不随环境变化。原因有两个:一是 DS18B20 上电默认输出就是 85,说明转换命令没发出去或时序不对;二是delay_us精度不够,单总线时序错位。解决方法是先用示波器看 DQ 线上的复位脉冲和存在脉冲,确认传感器有响应;再检查delay_us是否基于 SysTick 实现,如果是空循环延时,编译优化等级一变就会失准。

4.3 片内温度传感器读数偏高

现象:用 ADC 内部通道读温度,数值比实际环境高十几度。原因是片内传感器测的是芯片结温,不是环境温度,芯片自身发热会让读数偏高。解决方法是把它当相对值用,或者外接 DS18B20、LM75 这类独立传感器。如果一定要用片内通道,记得按参考手册里的公式做偏移校准,别直接拿原始 ADC 值当温度。

4.4 下载时提示 Flash 算法缺失

现象:编译通过,点下载报「Flash Download failed」。原因是 Keil 工程里选的 Flash 算法和芯片型号不匹配,或者 DFP 包没装全。解决方法是打开 Options → Debug → Settings → Flash Download,确认算法列表里有STM32F10x Med-density Flash,没有就手动添加。F103C8T6 属于中容量,选 128KB 的算法。

4.5 改了代码但现象没变

现象:修改了main.c里的打印内容,重新下载后串口输出还是旧的。原因是 Keil 没有重新编译,或者下载的是旧 axf 文件。解决方法是先 Build 再 Download,别直接点 Download。另外检查工程里有没有多个main.c被同时加入编译,这种情况链接器可能选了另一个。

5. 进阶:把温度数据用起来与工程迁移技巧

跑通串口打印只是起点。真正做项目时,温度数据要进缓冲区、要上传、要触发告警。一个实用技巧是在main.c里加一个环形缓冲区,把每次读到的温度存进去,主循环负责采集,另一个定时器中断负责发送,这样采集和通信解耦,不会因为串口阻塞导致采样周期抖动。

#define TEMP_BUF_SIZE 16 static float temp_buf[TEMP_BUF_SIZE]; static volatile uint8_t temp_wr = 0, temp_rd = 0; void temp_push(float t) { temp_buf[temp_wr] = t; temp_wr = (temp_wr + 1) % TEMP_BUF_SIZE; } float temp_pop(void) { float t = temp_buf[temp_rd]; temp_rd = (temp_rd + 1) % TEMP_BUF_SIZE; return t; }

逻辑说明:temp_wr和temp_rd用volatile修饰,因为会在中断和主循环之间共享。缓冲区大小取 2 的幂可以用位与代替取模,但这里为了可读性用取模。注意读写指针相等时无法区分空和满,实际项目里可以加一个count变量或者留一个空位。

如果你要把这份标准库工程迁到 CubeMX + HAL,重点不是重写业务逻辑,而是重配时钟树和外设句柄。CubeMX 里把 USART1 配成 115200、ADC1 配好通道、GPIO 配好,生成代码后把DS18B20_Get_Temp这类驱动函数原样搬过去,只改底层读写 GPIO 的部分。迁移后验证方法很简单:先点灯,再串口发固定字符串,最后读温度,三步都过再往下做。

从那以后我每次拿到一份新的 STM32 工程包,都强制先做三件事:确认芯片包和 Flash 算法、用示波器或逻辑分析仪看一眼串口波形、把延时函数单独测一遍。这三步走完,后面九成的玄学问题都能提前排掉。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/29 6:54:11

图书馆座位预约系统源码解析:SpringBoot+Vue前后端分离实战

简介:这是一套面向Java Web开发者与计算机专业学生的图书馆座位预约系统完整项目源码,采用SpringBoot后端与Vue前端的前后端分离架构,配合关系型数据库存储用户、座位与预约记录,可用于课程设计、毕业设计或信息化管理类项目的学习…

作者头像 李华
网站建设 2026/10/29 6:54:08

链接变PPT实战:GLM-4.5-Air与python-pptx自动化提案生成

1. 一条链接变一份提案,这件事到底靠不靠谱先说结论:靠谱,但前提是你得搞清楚"链接变PPT"这条链路里,哪些环节是AI真正擅长的,哪些环节必须人工兜底。我从去年开始陆续试了七八种不同的方案,从最…

作者头像 李华
网站建设 2026/10/29 6:53:54

C++20 ranges适配器视图的编译期可变性检查机制

1. 项目概述:C ranges适配器视图的编译期可变性检查在C20标准引入的ranges库中,适配器视图(adapter views)提供了一种声明式操作数据序列的优雅方式。但当我们尝试通过视图修改底层元素时,编译器需要确保原序列确实允许…

作者头像 李华
网站建设 2026/10/29 6:53:21

抖音电商数据可视化全链路:从爬虫到Hadoop再到Flask实战

简介:这份资源是面向高校学生与技术学习者的抖音电商数据可视化完整项目源码,采用Hadoop、Flask、MySQL 5.7与Vue构建前后端分离架构,可作为毕业设计、课程设计、大作业或工程实训的实践素材。压缩包共406个文件,约17.24MB&#x…

作者头像 李华
网站建设 2026/10/29 6:53:20

AI工具如何提升继续教育学术效率:10款精选工具评测

1. 学术生产力革命:AI工具如何重塑继续教育体验十年前我刚开始攻读在职硕士时,为了完成一篇课程论文,需要连续三周泡在图书馆翻检文献。如今我的研究生只需在咖啡厅用平板电脑操作几款AI工具,三小时就能完成文献综述初稿。这种效率…

作者头像 李华