立创EDA实战:基于STM32F030与T117高精度传感器的无线电子体温仪全流程开发
本文详细介绍了使用立创EDA和STM32F030C8T6开发无线电子体温仪的全过程。项目核心在于集成T117高精度温度传感器,实现±0.1℃的医疗级测温精度,并通过蓝牙模块实现数据无线传输。文章涵盖了从硬件选型、原理图与PCB设计、3D结构设计到软件驱动开发的完整流程,为嵌入式开发者提供了一个从零到一的实战案例。
立创EDA实战:基于STM32F030与T117高精度传感器的无线电子体温仪全流程开发
很多朋友,特别是家里有孩子的,可能都遇到过跟我一样的烦恼:孩子生病发烧,用传统水银温度计测体温,孩子总是不配合,等得不耐烦就把温度计拿出来了,测半天白费劲。市面上的耳温枪、额温枪我也试过,精度有时候真不敢恭维。所以我就想,能不能自己做一款既便宜、精度又高、测量还快的体温计呢?最好还能无线传输数据,方便看护。
这个想法折腾了我好久,从画原理图、设计PCB、写代码到做外壳,踩了无数的坑。今天,我就把自己用立创EDA和STM32F030C8T6做这个无线电子体温仪的全过程分享出来,手把手带你走一遍。无论你是想学习STM32开发、传感器应用,还是想体验一个完整的小产品从零到一的过程,这篇文章都希望能帮到你。
1. 项目构思与硬件选型
做项目的第一步,不是急着画图写代码,而是想清楚你到底要做一个什么东西,它需要实现哪些功能。想明白了,后面的路才顺。
1.1 明确产品需求
我的核心需求很明确,就是解决给孩子量体温的痛点:
- 精度要高:至少要比耳温枪准,目标精度小于0.1℃。
- 带显示屏:方便家里老人使用,不用手机也能看。
- 必须支持蓝牙:既能用手机APP看数据、设报警,也能连电脑记录。
- 续航要久:最好能连续用12个小时以上,不用老充电。
- 使用要方便:最好能长时间贴着身体测,数据自动传到手机,家长不用时刻盯着,能设置温度报警就更好了。
基于这些需求,整个系统的框架就清晰了:需要一个高精度温度传感器测体温,一个单片机做控制和计算,一个蓝牙模块发数据,一个OLED屏做本地显示,再加上电池和充电管理保证续航。
1.2 核心器件选型心得
选型是个技术活,既要满足性能,又要控制成本。下面是我用的几个核心芯片,以及为什么选它们。
主控芯片:STM32F030C8T6 为什么选它?三个字:够用、便宜、功耗低。
- 够用:它是ARM Cortex-M0内核,48MHz主频,有64KB Flash和8KB RAM。对我们这个项目来说,驱动传感器、处理数据、控制显示和蓝牙通信,性能完全够用。它还有ADC(用来测电池电量)、I2C(连接传感器和屏幕)、USART(连接蓝牙模块)等丰富外设,正好匹配我们的需求。
- 便宜:在STM32家族里,F0系列是性价比的代名词,能有效控制整机成本。
- 功耗低:M0内核本身功耗就不高,芯片还支持多种低功耗模式,对于电池供电的设备很友好。
温度传感器:T117 这是本项目的精度担当。我对比了好几款,最终选了T117,它在人体温度范围(28℃~43℃)内精度能达到±0.1℃,完全满足医疗级需求。
- 超高精度:16位分辨率,能分辨0.004℃的温度变化。
- 测量速度快:最快2.2ms就能完成一次测量,我们完全可以用间歇工作的方式来省电。
- 接口简单:支持I2C和单总线,我用的是I2C,方便和单片机通信。
- 功耗极低:平均工作电流只有2μA(每秒测1次的情况下),对续航帮助巨大。
- 封装小:DFN6L封装,只有2x2mm,适合做进小型设备里。
注意:T117和另一款MTS4传感器都很优秀,立创商城都能买到。我选择T117是因为当时手头有存货。它们引脚兼容,如果你的项目对尺寸有极致要求,可以考虑更小的MTS4(1.6x1.2mm)。
蓝牙模块:KT6368A 我需要设备既能被普通手机(支持SPP蓝牙串口)连接,也能被智能手表等设备(支持BLE低功耗蓝牙)连接,所以选择了这款双模蓝牙芯片。
- 双模兼容:同时支持经典蓝牙(SPP)和低功耗蓝牙(BLE),适用性广。
- 使用简单:通过串口AT指令与STM32通信,大大降低了开发难度。你只需要让STM32通过串口发送数据,它就能帮你把数据广播出去。
- 也有纯BLE版本:如果项目只考虑连接手机APP且对功耗有极致要求,可以选用它的兄弟型号KT6328A,功耗会更低。
其他部件:
- 显示屏:0.91寸OLED,I2C接口,4个引脚(VCC, GND, SCL, SDA),便宜又好用。
- 电源管理:充电芯片用TP4057,便宜稳定;系统供电用LDO将电池电压降到3.3V。
- 电池:200mAh的锂电池,保证续航。
2. 硬件设计:从原理图到PCB
硬件是产品的骨架,设计好了,后面写软件才省心。我用的是立创EDA,对新手非常友好。
2.1 系统框图与原理图设计
先画个系统框图理清思路,这样画原理图时就不会漏东西。

电源部分: 核心就是Type-C输入,TP4057负责充电,LDO输出稳定的3.3V给整个系统。这里有个小经验,第一版我用了6Pin的Type-C,后来发现Micro USB更便宜,第二版就换掉了。做产品,成本一分一毛都得省。

主控与传感器连接: STM32F030C8T6的I2C1(PB6=SCL, PB7=SDA)同时连接了T117传感器和OLED屏幕。这里注意,I2C总线上可以挂多个设备,每个设备有独立的地址。T117的默认地址是0x80(写)/0x81(读),OLED的地址通常是0x78或0x7A,通过电阻配置,不会冲突。 蓝牙模块KT6368A连接在STM32的USART2(PA2=TX, PA3=RX)上。

2.2 PCB布局与打样
画PCB是个细致活,要考虑电气性能、散热、装配等等。
- 板层:我用了4层板。因为板子有一部分很窄(放传感器探头),如果用2层板会太软,容易变形。4层板中间有完整的地层和电源层,信号质量也好很多。
- 板厚:常规1.6mm。如果想更结实,可以加厚到2.0mm,但打样费会贵一些。
- 尺寸:为了享受立创的免费打样优惠,我把板子尺寸控制在了10cm x 10cm以内。
- 装配孔:用了M3的螺丝孔,后来觉得有点大,M2其实就够了,还能更省空间。

提示:PCB上给电池连接预留了2.54mm排针,调试阶段非常方便,可以直接插拔,不用焊接。
3. 结构设计:让产品有个“家”
硬件板子做好了,还得给它穿件“衣服”。我用立创EDA的3D建模功能设计了外壳,虽然过程磕磕绊绊,但成就感满满。
3.1 3D外壳设计
作为3D设计新手,我的经验是:尺寸一定要算准!立创EDA的3D模型库很全,但有些元件的3D模型尺寸可能和实物有细微差别,最好自己核对一下。 比如我设计开关位置时,以为居中了,结果装上去发现拨杆太靠上,这就是因为没算准开关本体的尺寸。所以,画完图最好能用嘉立创的“三维预览”功能多看几遍。

3.2 前面板设计
前面板我直接在立创EDA里用2D绘图工具设计,然后发去制版。这里有个超级实用的技巧:你可以先把PCB板边框导出为DXF文件,然后导入到面板设计文件中作为参考线。这样,屏幕开孔、按键位置就能和PCB板上的元件严丝合缝地对齐了。
我做了两个版本:
- 亚克力版本:硬度高,透光性好,但比较脆。
- PET薄膜版本:柔软,可以带背胶直接粘贴,更有质感。

实物出来效果非常棒,有了外壳,立马就有了“产品”的感觉。

4. 软件驱动与程序设计
硬件准备就绪,接下来就是让芯片“活”起来。我使用STM32CubeMX初始化工程,用Keil 5进行开发。
4.1 程序设计思路
整个程序围绕低功耗和实时监测展开,主循环里主要干这几件事:
- 电量检测:用STM32内部的ADC,通过DMA方式定时(每2秒)采集电池电压分压后的值,换算成电量百分比显示。为什么是2秒?因为1秒刷新太快,没必要,还耗电。
- 蓝牙状态检测:蓝牙模块KT6368A会有一个连接状态引脚(我接到了PA1),单片机读取这个引脚就知道手机是否连上了,并在屏幕上显示“OK”或“NO”。
- 温度读取:每2秒通过I2C去读取一次T117传感器的状态寄存器,检查一次温度转换是否完成。如果完成了,就把温度数据读出来。
- 数据显示与发送:把电量、时间、温度实时显示在OLED上。如果蓝牙已连接,就把这些数据通过串口发送给蓝牙模块,广播出去。
4.2 核心驱动代码解析
这里重点讲讲最核心的温度传感器T117的驱动。OLED和蓝牙的驱动网上资源很多,可以直接移植。
首先,要理解T117的寄存器。我们在头文件里用枚举定义好所有重要的寄存器和配置命令,这样代码可读性会高很多。
// senser.h 头文件部分内容
typedef enum
{
// 测温模式命令 (写入Temp_Cmd寄存器)
CONTI_CONVERT = 0x00, // 连续测量温度
STOP_CONVERT = 0x40, // 停止测量温度
SINGLE_CONVERT= 0xc0, // 单次测量温度
// 测温频率配置 (Temp_Cfg寄存器部分位)
FRE_1times = 0x60, // 每秒1次
FRE_2s = 0x80, // 每2秒1次
// 平均次数配置 (Temp_Cfg寄存器部分位)
AVG_1 = 0xe7, // 平均1次,转换最快(2.1ms)
AVG_32 = 0x18, // 平均32次,转换最慢(15.3ms),精度更高
// 低功耗模式
OFF_PD = 0xfe, // 不进入低功耗
ON_PD = 0x01, // 进入低功耗
} I2C_CMD;
typedef enum
{
Temp_lsb = 0x00, // 温度值低字节
Temp_msb = 0x01, // 温度值高字节
Status = 0x03, // 状态寄存器(重点!)
Temp_Cmd = 0x04, // 测温命令寄存器
Temp_Cfg = 0x05, // 配置寄存器
} REG;
关键点:状态寄存器 (Status) 它的第5位(bit 5)是“温度转换状态位”。当这位为0时,表示温度转换完成,可以读取了;为1时表示还在转换中。我们程序里就是靠查询这个位来判断能不能读温度。
初始化函数:
// senser.c
void T117_Init(void)
{
// 1. 设置测温模式:连续测量,不开启加热
T117_W_REG(Temp_Cmd, CONTI_CONVERT);
// 2. 配置测量参数:每2秒测1次,32次平均,开启低功耗模式
// 0x99 = FRE_2s (0x80) | AVG_32 (0x18) | ON_PD (0x01)
T117_W_REG(Temp_Cfg, 0x99);
// 3. 配置报警模式:这里我们不使用报警功能,将报警引脚配置为“测温完成标志位”输出
T117_W_REG(Alert_Mode, 0x10);
}
初始化就是告诉传感器怎么工作。这里我配置成每2秒自动测量一次,并且做32次采样取平均,这样得到的温度值更稳定、更准确。同时开启低功耗模式,不测量的时候芯片几乎不耗电。
读取温度函数: 这是最核心的函数,把传感器读回来的两个字节数据,转换成我们熟悉的摄氏度。
// senser.c
uint8_t T117_R_TEMP(float *DAT)
{
uint16_t rx = 0;
uint8_t data = 0;
// 1. 先读高字节 (地址0x01)
if(T117_R_REG(0x01, &data)) return 1;
rx = data;
rx <<= 8; // 左移8位,为合并低字节做准备
// 2. 再读低字节 (地址0x00)
if(T117_R_REG(0x00, &data)) return 2;
rx += data; // 合并成16位数据
// 3. 数据转换
// T117的输出是16位有符号整数,每1个单位代表1/256摄氏度
// 0x0000 对应 0摄氏度,0x0100 对应 1摄氏度
// 转换公式:温度 = 25 + (原始值 / 256)
// 这里的25是一个偏移量,具体参考T117数据手册
*DAT = (int16_t)rx; // 先转为有符号数
*DAT = 25.0 + (*DAT) / 256.0;
return 0; // 成功返回0
}
注意:公式
温度 = 25 + (原始值 / 256)中的“25”是T117传感器特有的一个校准偏移值。不同型号、甚至不同批次的传感器这个值可能不同,一定要以你购买的传感器数据手册为准!
I2C底层读写函数: 我这里为了移植方便,用的是GPIO模拟I2C(软件I2C)。好处是不受STM32硬件I2C引脚固定的限制,想用哪个GPIO就用哪个。代码比较长,但逻辑很标准:起始信号->发送设备地址->发送寄存器地址->(如果是读)重新起始->读数据->停止信号。
4.3 主程序逻辑
主程序在 main.c 的 while(1) 循环中,按照之前的设计思路运行:
// main.c 主循环部分核心逻辑
while (1)
{
// 1. 处理电量显示(每2秒由ADC DMA中断触发Flag=1)
if(Flag)
{
Flag = 0;
// ... 计算电池电压并转换为百分比 ...
OLED_ShowString(0, 0, battery_percent_str, 8, 1);
// ... 更新时间显示 ...
}
// 2. 检查并读取温度
uint8_t status;
if(T117_R_REG(Status, &status) == 0) // 读取状态寄存器
{
if((status & 0x20) == 0) // 判断bit5是否为0(转换完成)
{
float current_temp;
T117_R_TEMP(¤t_temp); // 读取温度值
sprintf(temp_str, "%5.2fC", current_temp);
OLED_ShowString(0, 7, temp_str, 16, 1); // 在OLED第7行显示温度
}
}
// 3. 检查蓝牙状态并发送数据
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)) // PA1为高,表示蓝牙已连接
{
sprintf(s, "BT:OK");
OLED_ShowString(18, 0, s, 8, 1);
// 通过printf发送数据到串口(蓝牙模块)
printf("T=%5.2fC\r\n", current_temp);
printf("V=%6.3fV\r\n", battery_voltage);
}
else
{
sprintf(s, "BT:NO");
OLED_ShowString(18, 0, s, 8, 1);
}
// 4. 刷新OLED屏幕
OLED_Refresh();
HAL_Delay(2000); // 主循环延迟2秒,与温度测量节奏同步
}
ADC DMA中断回调函数: 这个函数每2秒被触发一次,用于更新计时和触发电量计算。
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
Flag = 1; // 主循环中处理电量的标志
second += 2; // 总计时增加2秒
HAL_ADC_Start_DMA(hadc, (uint32_t *)(&adc_value[0]), 4); // 重新启动ADC DMA采集
}
5. 效果验证与后续改进
程序烧录进去,组装好外壳,就可以测试了。我拍了两个视频放在B站,展示了温度测量和蓝牙数据传输的效果。
- 整体展示:可以看到OLED屏上实时显示温度、电量、运行时间和蓝牙连接状态。
- 蓝牙传输:用手机上的蓝牙调试APP(我用的叫“e调试”)或者电脑的蓝牙串口助手,都能稳定接收到设备发过来的温度和电量数据。
踩坑与改进:
- 第一版功耗:带屏幕的版本虽然方便,但OLED屏比较耗电。所以我在设计第二版时去掉了屏幕,完全依赖手机APP查看数据,这样设备可以做得更薄,续航也更长。
- 传感器焊接:T117是DFN封装,引脚在底部,没有引线伸出来,焊接需要一些技巧。建议用好的烙铁(比如刀头),配合助焊膏和热风枪,会容易很多。
- APP开发:目前我用的都是通用的蓝牙调试工具。一个真正的产品还需要一个专用的手机APP,可以显示温度曲线、设置报警阈值等。这是我下一步要学习的方向。
这个项目从想法到实物,让我对嵌入式产品开发的完整流程有了更深的体会。硬件设计要考虑成本、可制造性;软件编写要兼顾功能、稳定性和低功耗;结构设计要注重用户体验。每一步都有挑战,但每一步解决后都充满乐趣。希望我的分享能给你带来一些启发,也欢迎你一起动手,做出属于自己的小设备。
更多推荐
所有评论(0)