简介本资源是一套面向嵌入式开发初学者与毕业设计学生的STM32智能医疗终端完整工程方案聚焦慢性病患者用药依从性与远程健康监护痛点适用于家庭护理、养老院及康复场景。项目基于STM32F103主控集成定时服药提醒、PPG心率监测及4G模组支持数据上传至云端/家属端具备软硬件协同设计能力训练价值。压缩包含224个文件主体为48个C源码与55个头文件涵盖HAL库驱动、cJSON解析、4G AT指令通信、心率算法处理等核心模块辅以38个XML配置、25个Kotlin移动端界面文件及12个UI资源图整体98.89MB结构清晰、模块解耦度高。已有61人学习下载提供可直接编译的Keil工程含.uvprojx/.uvoptx、完整调试日志、硬件原理图参考及MP4功能演示视频助力读者快速掌握传感器融合、低功耗时序控制与蜂窝网络接入等关键技术环节。1. 项目概述一个面向真实需求的智能健康监护终端看到这个项目标题——“基于STM32单片机智能药盒药箱定时吃药心率监测4G模块版本”我第一反应是这绝对是一个能解决实际痛点的好课题。它不像一些空中楼阁的毕业设计而是精准地切入了老年人健康管理和慢性病患者用药依从性这两个社会性难题。一个能定时提醒、监测心率、还能通过4G联网上报数据的药盒听起来简单但背后融合了嵌入式控制、传感器技术、无线通信和云端交互等多个软硬件模块技术栈相当完整非常适合作为电子、通信或物联网相关专业的毕业设计。这个项目的核心价值在于“监护”与“提醒”的结合。传统的智能药盒可能只做到了定时响铃但用户是否真的按时吃了药吃药时身体状态如何这些关键信息是缺失的。而本项目通过集成心率监测能在每次用药提醒时或用户主动触发时采集一次心率数据结合用药记录可以形成一个简单的健康日志。4G模块的加入更是点睛之笔它使得这个设备脱离了“信息孤岛”的状态可以将用药记录、心率数据、甚至药盒的开关状态实时同步到云端服务器方便子女或医护人员通过手机App或网页远程查看实现真正的远程健康监护。对于学习者而言完成这个项目意味着你需要打通从单片机选型、传感器驱动、定时器管理、到4G网络通信、数据协议设计乃至简单服务器交互的全链路。它考察的不仅是编程能力更是系统级的硬件设计和软硬件联调能力。接下来我将以一个实际开发者的视角为你深度拆解这个项目的设计思路、技术选型、实现细节以及那些在文档里找不到的“踩坑”经验。2. 核心硬件平台与器件选型解析一个项目的成功一半取决于前期的硬件选型是否合理。这里的每一个器件都关系到系统的稳定性、成本和开发难度。2.1 主控芯片为什么是STM32标题点名了STM32这是一个非常主流且明智的选择。STM32系列单片机基于ARM Cortex-M内核性能从M0到M7不等生态完善资料丰富。对于本项目我们不需要复杂的图形界面或浮点运算但对实时性精准定时、外设丰富度UART, I2C, GPIO和低功耗有一定要求。具体型号推荐STM32F103C8T6俗称“蓝桥杯”或“最小系统板”款。这款芯片是Cortex-M3内核主频72MHz拥有64KB Flash和20KB RAM完全足够承载本项目的逻辑。它具备多个定时器、USART串口和I2C接口正好用于连接4G模块和心率传感器。最关键的是其开发板价格低廉学习资源浩如烟海极大降低了开发门槛。备选方案如果考虑更低的功耗可以选用STM32L系列如STM32L151C8T6。但需要注意L系列在绝对性能和外设时钟配置上可能与F系列有差异部分库函数需要调整。注意采购开发板时务必确认板载的串口转换芯片如CH340、CP2102驱动是否完善这直接关系到你能否顺利通过USB进行程序下载和调试。2.2 4G通信模块连接世界的桥梁4G模块是本项目实现“智能”和“远程”的关键。它的作用是将STM32收集到的数据用药时间、心率值打包通过运营商的网络发送到指定的云服务器。模块选型市面上常见的4G模块有移远EC20、EC200S中移动ML302以及广和通FM150等。对于毕业设计我强烈推荐移远EC200S系列。原因如下成本与封装EC200S性价比高且多数提供Mini PCIe或LGA封装市面上有大量将其核心板与USB/UART转换电路集成在一起的“开发板”或“调试板”出售你只需要通过串口与之通信即可免去了自己设计射频电路和SIM卡座的巨大麻烦。协议支持它支持TCP/IP协议栈内嵌这意味着你可以通过简单的AT命令如ATQIOPEN,ATQISEND建立TCP连接并发送数据而不需要在STM32上实现复杂的PPP拨号或TCP/IP协议栈。资料与社区移远提供的文档AT命令集相对规范社区中关于EC200S的应用笔记和踩坑分享也非常多。通信方式选择模块与STM32通常通过UART串口连接。你需要为STM32配置两个串口USART一个用于连接4G模块如USART2另一个用于调试打印信息如USART1连接CH340到电脑。与4G模块通信的串口建议波特率设置为115200或9600并务必开启串口接收中断以高效处理模块返回的庞杂的AT命令响应数据。2.3 心率监测传感器生物信号的采集前端心率监测是项目的亮点也是难点。心率传感器主要分两类光电式PPG和心电式ECG。对于药盒这种非持续、非医疗级监护的场景光电式心率传感器是更合适的选择。传感器选型MAX30102这是最经典的光电心率血氧传感器模块。它集成红光和红外LED、光电探测器、环境光消除电路以及ADC通过I2C接口输出原始光电容积脉搏波PPG数据。优点是集成度高算法开源资料多缺点是需要单片机端运行心率计算算法对STM32的运算能力有一定要求。MAX30105MAX30102的升级版增加了绿光LED心率检测精度理论上更优。PulseSensor一个模拟输出的传感器需要STM32的ADC来采集其输出的模拟电压波形然后通过算法计算心率。成本更低但电路和算法需要自己处理抗干扰能力相对较弱。推荐方案对于大多数毕业设计选择MAX30102模块是最稳妥的。市面上有大量将MAX30102芯片、必要电阻电容和稳压电路集成好的模块直接通过I2C接口与STM32连接SCL, SDA引脚。你只需要专注于如何读取数据和实现心率算法即可。2.4 其他关键外围器件实时时钟RTC定时提醒的核心。STM32F103内部集成了RTC外设但它依赖于后备电池通常是一个纽扣电池如CR1220在系统断电时维持计时。务必在硬件设计上留出后备电池的焊盘或插座。在软件上需要初始化RTC并设置闹钟中断来实现精准的用药时间提醒。显示单元用于显示时间、下一次用药提醒、心率测量结果等。推荐使用0.96寸或1.3寸的OLED屏幕SSD1306驱动它同样是I2C接口显示清晰且功耗极低。如果信息量不大使用LCD1602字符液晶屏并行或I2C版本也是经济实惠的选择。声音与提示模块需要一个有源蜂鸣器来实现“哔哔”的提醒音。通过STM32的一个GPIO引脚控制三极管来驱动即可。为了增强提醒效果可以考虑增加一个振动电机类似手机振动器。药盒状态检测如何知道用户打开了药盒最简单的方法是使用一个干簧管或霍尔传感器配合小磁铁。当药盒盖子贴有磁铁打开时传感器状态变化触发STM32的外部中断记录一次“取药”事件。这是一个低成本且可靠的方案。电源管理整个系统可以由一个5V/2A的USB电源适配器供电。STM32开发板通常有AMS1117等LDO将5V转3.3V。4G模块在发射数据时峰值电流可能达到2A因此必须确保你的电源电路能提供足够且稳定的电流否则会导致系统重启。建议在4G模块的电源入口处并联一个大电容如470uF以缓冲电流冲击。3. 系统软件架构与核心逻辑设计硬件是骨架软件是灵魂。我们需要一个清晰、稳定且易于维护的软件架构来统筹所有功能。3.1 程序主循环与多任务调度在STM32这样的单线程环境中我们需要通过“时间片轮询”或基于中断的“前后台系统”来模拟多任务。对于本项目推荐一种清晰的结构int main(void) { // 1. 硬件初始化 HAL_Init(); SystemClock_Config(); UART_Init(); // 调试串口 4G模块串口 I2C_Init(); // 用于OLED和MAX30102 RTC_Init(); // 初始化并读取备份寄存器中的时间 GPIO_Init(); // 初始化蜂鸣器、按键、药盒开关检测引脚等 MAX30102_Init(); OLED_Init(); // 2. 读取存储的用药计划如从STM32内部Flash或外挂EEPROM Load_Medicine_Schedule(); // 3. 主循环 while (1) { // 任务1检查是否到达用药时间每秒检查一次 Check_Medicine_Time(); // 任务2处理心率传感器数据在定时器中断中采集在主循环中处理算法 Process_HeartRate_Sensor(); // 任务3处理4G模块的响应和数据发送任务 Process_4G_Module(); // 任务4扫描按键如手动测量心率、确认服药、设置时间等 Key_Scan(); // 任务5更新OLED显示 OLED_Refresh(); // 任务6低功耗管理如果没有紧急任务可以进入休眠由RTC闹钟或外部中断唤醒 Enter_LowPower_Mode_If_Idle(); } }这种结构将不同功能封装成任务函数在主循环中依次轮询每个函数内部实现非阻塞式的状态机避免长时间等待。3.2 定时用药提醒的实现细节这是项目的核心功能之一关键在于RTC闹钟的精准和使用体验。时间设置与存储首先需要提供一个方式如通过按键OLED菜单或首次上电时通过串口指令来设置当前时间。设置好的时间需要写入RTC的计数器。更重要的是用户设定的用药计划例如每天8:00, 12:00, 20:00需要被存储到非易失性存储器中。STM32F103C8T6的内部Flash可以划分出一小部分如最后一页来存储这些数据但需注意Flash的擦写寿命。更稳妥的做法是外挂一片SPI或I2C接口的EEPROM芯片如AT24C02。RTC闹钟配置STM32的RTC可以配置闹钟当RTC计数值与闹钟寄存器匹配时会产生一个闹钟中断。但RTC闹钟寄存器通常只能设置一个未来的时间点。对于一天多次的用药提醒我们需要采用一种“动态设置下一个闹钟”的策略在系统初始化时从存储的用药计划中找出下一个即将到来的用药时间点比如现在是9:00计划是8:00和12:00则下一个是12:00。将这个12:00的时间转换为RTC的计数值并设置为闹钟。当12:00闹钟触发中断时系统启动提醒蜂鸣器响、屏幕闪烁同时立即从计划中计算再下一个用药时间20:00并重新配置RTC闹钟为20:00。这样闹钟就像一根不断跳跃的指针永远指向下一个任务点。用户交互与确认闹钟响起后不能只是简单响铃。应该在OLED上清晰显示“请服用XX药”。用户可以通过按下“确认服药”按键来停止提醒。强烈建议将这次“确认”动作与药盒盖子的“打开”信号进行关联或互锁。例如只有检测到盖子打开再闭合或者按下确认键才认为一次服药完成并记录本次服药时间可能带有几分几秒的偏差和当时的心率如果支持自动测量。这个记录应立即准备通过4G模块上传。3.3 心率监测功能的集成与算法处理集成MAX30102获取心率数据是软件上的一个挑战点。数据采集MAX30102通过I2C接口可以FIFO的方式不断输出红光和红外光的ADC采样值。我们需要在STM32上用一个定时器如TIM2来产生固定的采样间隔通常为100Hz即10ms一次在定时器中断服务函数中快速读取FIFO中的数据存入一个全局的缓存数组。切记I2C读操作要快中断服务函数中不能做复杂运算。心率计算算法获取到的是原始的PPG波形数据需要经过滤波、寻峰等处理才能得到心率值。不建议从零开始写算法可以移植开源算法。开源库参考GitHub上有很多针对MAX30102的嵌入式心率算法库例如由“aromring”等人维护的MAX30102库里面包含了基于时域分析的“getHeartRate”函数。这些算法通常需要在主循环中调用处理缓存区里的数据。算法流程简述直流滤波去除信号中的直流分量得到交流的脉搏波。带通滤波使用软件滤波器如二阶IIR带通滤波器通带0.5Hz ~ 5Hz对应心率30-300 BPM滤除呼吸、运动等低频干扰和高频噪声。寻峰检测在滤波后的信号中寻找波峰。计算相邻波峰的时间间隔IBI。心率计算心率( BPM ) 60 / (平均IBI(秒))。为了提高稳定性通常会取最近4-8个IBI的平均值。测量时机心率测量不应一直进行因为LED发光比较耗电。可以在两种情况下启动测量定时关联测量每次用药提醒时自动启动一次持续30秒的心率测量并将结果与服药记录绑定。手动触发测量用户通过按键主动触发一次心率测量。实操心得MAX30102对佩戴即手指按压的力度和位置非常敏感。在代码中一定要加入信号质量检测。例如计算原始信号的幅度或方差如果信号太弱或饱和则在OLED上提示“请重新放置手指”而不是输出一个荒谬的心率值。这能极大提升用户体验和专业度。3.4 4G模块通信与数据上报协议让STM32通过4G模块与服务器通信是整个项目联调的“重头戏”也是问题最多的环节。AT命令流程与EC200S模块的交互是一系列AT命令。流程必须严格且包含错误重试机制。一个基本的TCP数据上报流程如下// 1. 检查模块是否就绪 Send_AT_Cmd(AT\r\n, expect:OK, timeout:1000ms); // 2. 检查SIM卡和网络注册状态 Send_AT_Cmd(ATCPIN?\r\n, expect:CPIN: READY); Send_AT_Cmd(ATCREG?\r\n, expect:CREG: 0,1); // 1表示已注册到本地网 Send_AT_Cmd(ATCGATT?\r\n, expect:CGATT: 1); // 1表示PS附着成功 // 3. 激活PDP上下文获取IP地址 Send_AT_Cmd(ATQIACT1\r\n, expect:OK, timeout:60000ms); // 激活可能需要较长时间 // 4. 建立TCP连接 Send_AT_Cmd(ATQIOPEN1,0,\TCP\,\your.server.ip\,your_server_port,0,0\r\n, expect:OK, timeout:60000ms); // 等待异步响应 QIOPEN: 0,0 // 5. 发送数据 char data_to_send[] {\device_id\:\123\,\event\:\take_medicine\,\time\:\2023-10-27 08:00:05\,\heart_rate\:75}; Send_AT_Cmd(ATQISEND0,%d\r\n, strlen(data_to_send), expect:, timeout:5000ms); UART_SendString(data_to_send); // 紧接着发送实际数据 Send_AT_Cmd(\x1A\r\n, expect:SEND OK, timeout:5000ms); // 以0x1ACtrlZ结束发送 // 6. 关闭连接如果是短连接 Send_AT_Cmd(ATQICLOSE0\r\n, expect:OK, timeout:5000ms);数据协议设计为了便于服务器解析数据格式推荐使用JSON。虽然JSON对STM32这样的MCU来说解析和生成有点负担但它的可读性和通用性无可替代。你可以使用轻量级的JSON库如cJSON但需要对其进行裁剪以适应有限的RAM。更简单的方法是直接用sprintf函数拼接一个JSON字符串char json_buffer[256]; sprintf(json_buffer, {\dev_id\:\%s\,\type\:%d,\time\:\%04d-%02d-%02d %02d:%02d:%02d\,\hr\:%d}, DEVICE_ID, event_type, // 0:心跳包1:服药2:心率测量 year, month, day, hour, min, sec, heart_rate);服务器端可以用Python Flask、Node.js等快速搭建只需要监听TCP端口接收并解析这个JSON字符串即可。心跳包与重连机制为了保持链路活跃和检测连接状态需要定时如每5分钟发送一个简单的心跳包{type:0}。如果发送失败或收到TCP错误程序需要能够从检查网络状态开始自动执行重连流程。重连逻辑一定要健壮并且加入指数退避策略比如第一次失败等2秒重试第二次等4秒第三次等8秒直到一个最大值避免网络暂时不佳时疯狂重试耗光电量或使模块过热。4. 系统整合与调试实战记录当各个模块单独调通后将它们整合在一起并稳定运行才是真正的挑战。4.1 电源与抗干扰设计电源隔离4G模块是最大的干扰源和耗电单元。务必在4G模块的电源输入端并联一个大容量电解电容如470uF和几个小容量陶瓷电容0.1uF, 10uF进行去耦。最好能为4G模块使用独立的LDO供电而不是与单片机共用同一个LDO的输出。信号线处理连接4G模块的UART_TX/RX线如果超过10厘米可以考虑在STM32端串联一个22欧姆到100欧姆的电阻以抑制信号反射。I2C总线SCL, SDA上需要接上拉电阻通常模块上已集成如果没有需要接4.7kΩ电阻到3.3V。地线设计保证整个系统有一个完整且低阻抗的“地平面”。所有模块的GND都要良好地连接在一起。4.2 多中断源的管理与优先级系统中可能存在多个中断源RTC闹钟中断低频率、定时器中断用于心率采样100Hz、串口接收中断处理4G模块响应高频率且不定时、外部中断药盒开关、按键。优先级设置最高优先级可以分配给系统关键的中断如用于心率采样的定时器中断必须准时否则采样波形失真。高优先级串口接收中断。4G模块返回的数据必须及时读取否则会覆盖缓冲区。但中断服务函数里只做最简单的数据搬运到环形队列复杂的解析放在主循环。中/低优先级RTC闹钟中断、外部中断。这些事件对实时性要求稍低。中断服务函数ISR原则快进快出不要在ISR里调用printf、执行复杂的字符串处理或等待循环。设置一个标志位、拷贝数据、清除中断标志然后立刻退出。具体的处理逻辑放到主循环中根据标志位去执行。4.3 调试技巧与问题定位分段调试绝对不要试图一次性整合所有代码。应该按以下顺序第一步让OLED显示“Hello World”测试I2C总线。第二步调通RTC能设置和读取时间并让OLED显示。第三步独立测试MAX30102用串口打印原始波形数据在电脑上用串口绘图工具查看波形是否正常。第四步独立测试4G模块用一个简单的测试程序能完成从开机、注册网络到发送一条“Hello Server”数据到测试服务器的全过程。第五步将各个模块的功能函数化然后在主循环中组合起来。善用调试串口预留一个USART给调试信息打印printf重定向。在关键流程节点如“开始连接网络”、“发送数据前”、“收到服务器响应”打印状态信息。这对于排查4G模块的AT命令交互问题至关重要。模拟服务器测试在前期你可以在自己的电脑上使用网络调试助手NetAssist创建一个TCP服务器让设备连接上来发送数据。这样可以快速验证4G模块的TCP通信功能是否正常无需等待后端开发。逻辑分析仪是神器如果时序问题诡异如I2C通信失败、UART数据错位一个几十块的逻辑分析仪配合PulseView软件可以清晰地看到总线上的每一个电平变化帮你快速定位是软件配置问题还是硬件连接问题。5. 常见问题排查与优化建议实录这里记录了一些开发中几乎必然会遇到的“坑”及其解决方案。问题现象可能原因排查步骤与解决方案4G模块无法开机或反复重启1. 电源供电不足。2. 开机时序不对。3. PWRKEY引脚电路错误。1.测量电压电流用万用表测模块VCC引脚电压在模块发射时是否被拉低如低于3.3V。用电流表测峰值电流是否超过电源供给能力。解决更换功率更大的电源适配器并在模块电源引脚就近加装大电容。2.检查开机时序查阅模块手册PWRKEY引脚通常需要拉低至少1秒再释放。确保程序中拉低时间足够。3.检查电路PWRKEY引脚是否通过一个电阻如4.7kΩ上拉到VCC并由STM32的GPIO通过一个三极管或MOS管控制下拉直接连接可能驱动能力不足。AT命令无响应或返回ERROR1. 串口波特率不匹配。2. 串口接线TX/RX反接。3. AT命令格式错误缺少回车换行。4. 模块未就绪。1.确认波特率先用电脑串口助手以模块默认波特率常为115200发送AT\r\n看是否有OK回复。2.检查接线STM32的TX接模块的RXSTM32的RX接模块的TX。3.检查命令格式确保发送的字符串以\r\n回车换行结尾。printf(“AT\r\n”)。4.等待就绪发送AT后模块可能回复CPIN: NOT READY需要等待几秒再操作。TCP连接建立失败1. 网络未注册CREG返回0,2等。2. PDP上下文未激活CGATT0。3. 服务器IP/端口错误或防火墙阻挡。4. SIM卡欠费或未开通数据业务。1.检查网络状态依次执行ATCPIN?,ATCREG?,ATCGATT?确保都返回正确值。2.检查APN有些地区需要手动设置APNATQICSGP1,1,”APN名称”如”CMNET”。3.Ping测试使用ATQPING1,”www.baidu.com”如果模块支持测试网络连通性。4.检查服务器用电脑上的网络调试工具先确认服务器端口是开放的。MAX30102读取数据全为0或0xFF1. I2C地址错误。2. I2C总线未正确初始化时钟速度、引脚模式。3. 传感器未正常工作供电、焊接。4. 读取时序过快。1.扫描I2C地址写一个I2C地址扫描程序确认能否找到0x57MAX30102的默认地址。2.检查初始化序列确保按照数据手册正确写入了配置寄存器如模式控制、LED电流、采样率等。3.检查硬件用万用表测量模块VCC是否为3.3VGND是否连通。重新焊接排针。4.增加延时在I2C读写操作间增加少量延时HAL_Delay(1)。心率计算结果极不稳定1. 信号质量差佩戴不当、环境光干扰。2. 算法参数不适合滤波器截止频率、寻峰阈值。3. 采样率不稳定定时器中断被高优先级中断打断。1.优化信号确保手指完全覆盖传感器施加适当压力。在传感器表面加装遮光海绵或橡胶圈阻挡环境光。2.调整算法在代码中增加信号质量判断只有信号幅度在合理范围内才进行计算。动态调整寻峰阈值。3.固定采样率确保用于采样的定时器中断优先级足够高且中断服务函数执行时间极短。系统运行一段时间后死机1. 堆栈溢出。2. 中断嵌套或资源冲突导致死锁。3. 看门狗未喂狗。4. 内存泄漏频繁malloc/free。1.增大堆栈在启动文件startup_stm32f103xe.s中适当增大Stack_Size和Heap_Size。2.简化中断检查所有ISR移除任何可能导致阻塞或调用非可重入函数的代码。3.启用看门狗使用STM32的独立看门狗IWDG在主循环中定期喂狗。如果程序跑飞看门狗会复位系统。4.避免动态内存在嵌入式系统尽量使用静态数组而非动态分配。最后的优化建议低功耗设计如果希望药盒能电池供电低功耗至关重要。在无任务时让STM32进入停止模式Stop Mode此时由RTC闹钟或外部中断药盒打开唤醒。同时4G模块在不需要通信时可以发送ATQSCLK1命令使其进入深度睡眠模式。数据本地缓存网络可能不稳定。所有关键的服药记录和心率数据除了上传一定要在本地Flash或EEPROM中备份一份。可以设计一个简单的循环队列存储最近N条记录网络恢复后尝试补传。固件升级OTA这是一个高级但非常有价值的功能。可以让4G模块从服务器下载一个固件包然后通过STM32的IAP在应用中编程功能自己更新自己的Flash。这为产品后续的功能迭代提供了可能。完成这样一个项目你收获的将不仅仅是一个毕业设计作品更是一套完整的嵌入式物联网产品开发方法论。从需求分析、器件选型、电路设计、驱动编写、协议制定到系统联调每一个环节的深入思考和问题解决都是你未来职业生涯中宝贵的经验。本文还有配套的精品资源点击获取