基于MAX32650FTHR的智能定时服药提醒系统项目总结报告
一、项目描述
所选任务:基于 MAX32650FTHR开发板的智能定时服药提醒系统
本项目提出一种基于 MAX32650FTHR 的智能定时服药提醒系统。项目是 MAX32650FTHR 的 GPIO、RTC、I²C、UART 等外设资源的综合应用,同时结合 CodeFusion Studio™ 完成程序编写、编译、烧录和调试,实现一个具有实际应用意义的嵌入式智能健康管理终端。
系统以“定时—提醒—确认—记录”为基本工作逻辑,通过多个硬件模块协同实现智能服药管理:
- 设备正常运行时,OLED 显示当前时间以及下一次服药时间。系统内部 RTC 持续计时,并与预先保存的用药计划进行比较。当 RTC 时间达到某一设定的服药时间时,系统进入提醒状态,此时红色 LED 闪烁,同时蜂鸣器周期鸣叫,OLED 显示“请服药”等提示信息,并通过 BLE 模块向手机发送提醒消息。
- 用户服药后,可按下开发板上的确认按键。系统检测到按键后关闭蜂鸣器与提醒 LED,并将该次提醒状态由“未完成”修改为“已完成”。OLED 随后显示确认信息,并自动等待下一次服药提醒。
- 在功能扩展方面,本系统支持一天设置多次服药时间,例如 08:00、13:00、18:00 和 22:00。后续还可通过 BLE 接收手机发送的配置数据,从而实现用药次数、提醒时间以及药品名称等信息的无线设置,使系统具备较好的扩展性。
二、硬件介绍
1. 主控制器:MAX32650FTHR
处理器:MAX32650,Arm Cortex-M4F 内核,主频最高可达 100MHz
存储:片上 Flash 和 SRAM,可用于存放程序、用药计划及运行数据
接口:GPIO、UART、I2C、SPI、Timer、RTC 等
开发方式:支持通过 CodeFusion Studio™ 进行程序编写、编译、烧录和调试
特点:处理能力较强、外设资源丰富、功耗较低,适合作为本项目的核心控制平台,可统一完成时间管理、显示控制、按键检测、蜂鸣器控制和 BLE 数据通信等功能

2. 显示模块:1.3英寸 OLED
显示类型:OLED 显示屏
显示内容:当前时间、下一次服药时间、药品信息、服药提醒状态及蓝牙连接状态等
接口方式:通过 I2C 接口与 MAX32650FTHR 通信
供电电压:根据所使用模块规格,可采用 3.3V 供电
特点:显示清晰、功耗较低、体积小,不需要背光,适合在智能医药箱中作为主要人机交互显示设备
3. 无线通信模块:BLE 蓝牙模块
通信方式:Bluetooth Low Energy(BLE)
接口方式:通过 UART 与 MAX32650FTHR 进行数据通信
主要功能:用于手机与智能医药箱之间的数据交互
通信内容:可接收手机端设置的服药次数、服药时间及药品信息,也可向手机发送服药提醒和服药状态信息
供电电压:优先选择支持 3.3V 电平的 BLE 模块
特点:功耗低、连接方便,可实现手机端无线配置和提醒功能,提高系统的智能化和便捷性
4. 时间管理模块:MAX32650 内部 RTC
计时方式:使用 MAX32650 内部 RTC 实时时钟外设
时钟来源:MAX32650FTHR 板载 32.768kHz 低频晶振
主要功能:记录系统当前时间,并与预设服药时间进行比较
提醒方式:当 RTC 时间达到设定时间后,触发 LED、蜂鸣器、OLED 和 BLE 等提醒功能
特点:无需额外外接 RTC 模块,可直接利用开发板已有硬件资源,减少外围器件数量并简化系统结构
5. 声音提醒模块:有源蜂鸣器
提醒方式:通过声音提示用户到达服药时间
控制方式:由 MAX32650 GPIO 输出控制信号,并通过三极管或 MOS 管驱动蜂鸣器
工作模式:可设置周期鸣叫,例如 500ms 响、500ms 停,实现持续提醒效果
供电方式:根据蜂鸣器规格选择 3.3V 或 5V 供电
特点:结构简单、提醒效果明显,可与 LED 和手机 BLE 提醒配合使用,形成声、光、无线多重提醒方式
6. 状态指示模块:LED 指示灯
控制对象:MAX32650FTHR 板载红色和绿色 LED
控制方式:通过 GPIO 输出控制 LED 点亮、熄灭或闪烁
状态定义:红色 LED 可用于表示“到达服药时间”或“等待用户确认”,绿色 LED 可用于表示“系统正常”或“服药确认成功”
供电方式:直接使用开发板板载电路,无需额外外接供电
特点:显示直观、响应速度快,便于用户快速判断设备当前工作状态,也方便开发阶段进行 GPIO 功能测试
7. 用户输入模块:按键
输入设备:MAX32650FTHR 板载用户按键
接口方式:通过 GPIO 输入读取按键状态,也可配置为 GPIO 中断方式
主要功能:用于确认服药、停止提醒、切换 OLED 显示页面或进入功能设置状态
控制方式:可采用短按、长按等方式区分不同操作
特点:操作简单,无需复杂输入设备即可完成服药确认和基本系统控制,适合智能医药箱的人机交互需求
三、方案框图与设计思路
- MAX32650FTHR 作为中央控制器,内部 RTC 周期更新当前时间。程序维护一个服药时间表,当检测到当前时间与某个启用状态下的服药时间一致时,系统切换至提醒状态。
- 进入提醒状态后,同时启动 LED、蜂鸣器、OLED 和 BLE 提醒。用户按键确认后,系统退出提醒状态,并保存服药完成信息。

图1:智能医药箱系统整体架构图
四、硬件连接设计
本项目主要基于开发板和现成模块搭建,没有单独设计完整 PCB,因此 PCB 设计部分暂不展开。
外围硬件连接关系如下:
- OLED 通过 I²C 与 MAX32650FTHR 相连,建议使用 P2.17 作为 I2C1_SDA,P2.18 作为 I2C1_SCL。
- BLE 模块通过 UART 与 MAX32650FTHR 相连,建议使用 P2.16 作为 UART1_TX,P2.14 作为 UART1_RX。
- 蜂鸣器由一个 GPIO 控制,并通过三极管驱动。LED 和按键可优先使用开发板板载资源。

图2:系统硬件连接图
实际工程主要引脚配置如下:
功能 | MAX32650 引脚 | 说明 |
|---|---|---|
红色 LED | P1.14 | GPIO 输出 |
绿色 LED | P1.18 | GPIO 输出 |
确认按键 | P1.19 | GPIO 输入,上拉 |
设置按键 | P1.21 | GPIO 输入,上拉 |
蜂鸣器 | P1.23 | GPIO 输出 |
BLE RX | P2.14 | UART1_RX |
BLE TX | P2.16 | UART1_TX |
OLED SDA | P2.17 | I2C1_SDA |
OLED SCL | P2.18 | I2C1_SCL |
OLED 和 BLE 模块均建议采用 3.3 V 逻辑电平,并与开发板共地。蜂鸣器等负载建议通过三极管驱动,避免直接由 MCU GPIO 提供较大工作电流。
五、软件流程图与设计说明
系统软件采用循环检测与状态机相结合的设计方式。
软件采用分模块开发方法,首先验证最基本的 LED 和按键功能,再逐步加入 OLED、RTC、蜂鸣器和 BLE。

图3:MAX32650FTHR 主控软件流程图
主控程序采用三个主要运行状态:
typedef enum {
SYS_STATE_IDLE,
SYS_STATE_ALARM,
SYS_STATE_CONFIRMED,
} system_state_t;
分别代表正常等待、正在提醒和已经确认三个状态。
系统启动后依次初始化各硬件模块,并从 Flash 加载用药计划。随后进入主循环:
while (1) {
sys_mgr_run();
}
sys_mgr_run() 首先检查 BLE 是否收到新的控制命令,然后依据当前状态调用不同处理函数:
switch (g_sys.state) {
case SYS_STATE_IDLE:
handle_idle();
break;
case SYS_STATE_ALARM:
handle_alarm();
break;
case SYS_STATE_CONFIRMED:
handle_confirmed();
break;
}
正常状态下,系统不断读取 RTC,并利用 alarm_mgr_check() 检查是否有需要执行的服药计划:
if (a->enable && !a->taken && !a->notified &&
a->hour == hour && a->minute == minute) {
return a;
}
满足条件后进入提醒状态。
提醒期间红色 LED 闪烁、蜂鸣器周期鸣叫、OLED 显示服药信息,同时定期通过 BLE 发送提醒。如果用户一直没有确认,系统仍保持提醒状态,并按照程序设计周期继续发送 BLE 提醒。
当检测到确认键:
if (drv_button_is_pressed(DRV_BUTTON_OK)) {
drv_led_off(DRV_LED_RED);
drv_buzzer_off();
alarm_mgr_mark_taken(g_sys.current_alarm);
}
系统停止声光提醒并更新服药状态。
每天进入 00:00 后,alarm_mgr_reset_daily() 会重新清除当天的 taken 和 notified 标志,使每日服药计划可以循环执行。
六、BLE 软件流程与指令设计

图4:手机 APP / BLE 软件流程图
目前项目采用串口文本协议实现手机与设备之间的数据交互,手机端可以暂时使用 BLE 串口调试软件完成测试,后续可再开发独立 APP。
主要指令包括:
TIME,8,30
设置当前时间为 08:30。
ADD,08:00,MedicineA
添加一条服药计划。
SET,08:00,MedicineA,12:00,MedicineB
一次设置多组服药计划。
GET查询所有服药计划及执行状态。
SAVE将当前计划保存到 Flash。
RESET恢复默认服药计划。
设备回复通常为:
OK
ERR
COUNT=4
1:08:00 MedicineA WAIT
到达服药时间后主动发送:
ALARM,08:00,MedicineA
用户确认以后发送:
TAKEN,08:02,MedicineA
因此,本系统不仅能够由设备本地提醒,还具备手机端设置、查询和状态回传能力。
七、Flash 用药计划保存
为了避免断电后所有服药计划丢失,工程编写了独立的 flash_store.c/.h 模块。
Flash 数据中除了保存用药计划外,还加入了:
MAGIC = 0x50424F58
即 "PBOX" 标志,以及 CRC 校验值。
读取时首先检查 Magic Number,再重新计算 CRC。如果两者均正确才认为 Flash 中的数据有效,否则加载默认服药计划。
这种方式可以减少 Flash 数据损坏或者首次启动时随机数据被错误识别为有效配置的问题,提高系统可靠性。
当前最多支持:
#define ALARM_MAX_COUNT 10
即最多保存 10 条服药计划。
八、开发与调试软件说明
本项目采用 CodeFusion Studio™ 2.2.1 作为主要软件开发环境,工程使用 Analog Devices MSDK。
工程主要配置为:
Soc : MAX32650
Board : FTHR
MSDK Board: FTHR_APPS_A
Core : Cortex-M4
CodeFusion Studio 的 System Planner 用于进行 GPIO、I²C、UART 和 RTC 等资源配置,并自动生成 soc_init.c 等初始化代码。
项目主要源文件包括:
main.c
system_manager.c
alarm_manager.c
flash_store.c
drv_led.c
drv_button.c
drv_buzzer.c
drv_rtc.c
drv_uart1.c
ssd1306.c
项目编译后生成:
CM4.elf
CM4.map
当前工程 ELF 的代码和数据规模约为:
text ≈ 109 KB
bss ≈ 3.5 KB
相对于工程配置的 3 MB Flash 和 1 MB SRAM,仍具有较大的后续扩展空间。
程序通过 CFS 调用 GDB 和 OpenOCD,经 CMSIS-DAP/SWD 接口烧录到 MAX32650FTHR。实际调试中已经出现 .text、.data 下载及 matched 校验信息,表明固件成功写入目标芯片。

图5:CodeFusion Studio 工程界面截图

图6:System Planner 引脚配置截图

图7:CodeFusion Studio 编译成功截图

图8:程序烧录成功终端截图
九、项目开发过程中遇到的难点及解决方法
1. RTC 驱动编译依赖错误
在初期编译时出现:
No rule to make target 'include/rtc.h'
错误。
经过逐级检查发现 MAX32650/rtc.h 实际存在,sys_me10.c 中的:
#include "rtc.h"
也没有问题。进一步检查发现问题来源于 PeriphDrivers 旧的 .d 依赖缓存文件,其中记录了错误的 include/rtc.h 路径。
最终通过:
clean
distclean
清除工程构建目录以及:
PeriphDrivers/bin/MAX32650/spi-v1_softfp
缓存后重新编译,RTC、GPIO、I²C、UART 等驱动全部正常生成,CM4.elf 成功链接。
2. OLED 的 I²C 初始化问题
OLED 调试过程中发现,MXC_I2C_Init() 可能重新设置引脚 PAD 属性,导致原本的 I²C 上拉配置被覆盖。
因此项目在初始化 I2C1 后重新对 P2.17 和 P2.18 设置:
ALT1
PULL_UP
VDDIOH
并在 OLED 驱动中避免重复调用 I²C 初始化,从而保证总线正常工作。
这一问题也体现了仅在图形化配置工具中设置引脚并不代表运行期间配置一定不会被 SDK 驱动修改,因此需要结合数据手册和实际寄存器行为进行排查。
3. 多模块程序容易互相影响
如果一开始同时加入 OLED、BLE、RTC、LED、蜂鸣器和 Flash,出现异常时很难判断具体故障来源。
因此实际调试采用:
LED
↓
按键
↓
OLED
↓
RTC
↓
蜂鸣器
↓
UART/BLE
↓
Flash
↓
整体联调
的顺序逐步验证。每个模块单独通过后再集成到 system_manager 状态机中,明显降低了调试难度。
4. BLE 数据接收完整性问题
手机或 BLE 模块发送的数据并不一定一次完整到达 UART FIFO,因此程序不能简单地认为“一次读取就是一条完整指令”。
项目使用缓存数组逐字节收集 UART 数据,并通过换行符或者一定时间的数据间隔判断一条命令结束,再进行解析,提高了通信稳定性。
十、实物演示及说明
首先展示 MAX32650FTHR、1.3 英寸 OLED、BLE 模块以及蜂鸣器连接完成后的系统实物。设备上电后,OLED 显示当前时间以及 Next Alarm 信息,绿色 LED 表示系统处于正常等待状态。
随后通过手机 BLE 终端发送:
TIME,07,59
设置当前时间,并设置一条:
ADD,08:00,MedicineA
服药计划。
当时间达到 08:00 时,应拍摄 OLED 显示:
MEDICINE TIME!
08:00
MedicineA
Press OK
同时红色 LED 闪烁、蜂鸣器鸣叫,手机端收到:
ALARM,08:00,MedicineA
用户按下开发板确认键后,蜂鸣器和红色 LED 停止,OLED 显示 Confirmed 和 Taken OK,手机收到 TAKEN 信息

图9:系统整体接线实物图

图10:OLED 正常工作界面照片

图11:到达服药时间后的提醒状态照片

图12:手机 BLE 设置与提醒信息照片
十一、心得体会
通过本次智能定时服药提醒系统的设计与调试,我对 MAX32650FTHR 的软硬件开发流程有了更加完整的认识。项目最初看似只是 RTC 定时、OLED 显示和蜂鸣器提醒几个简单功能,但实际完成以后涉及 GPIO、I²C、UART、RTC、Flash、状态机、字符串协议、数据校验以及 SDK 构建系统等多个方面,是一个比较完整的嵌入式系统实践。
在硬件设计方面,一个比较重要的体会是,应首先充分了解主控芯片和开发板已经提供的资源,再决定增加哪些外部模块。例如 MAX32650 已经具有 RTC,MAX32650FTHR 又提供了板载按键和 LED,因此这些功能没有必要重复外接器件,可以降低整体硬件复杂度。
在软件方面,本项目让我更加认识到模块化设计的重要性。当前工程将 LED、按键、蜂鸣器、RTC、UART 和 OLED 分别封装为独立驱动,同时将用药计划、Flash 存储和系统状态分别放在不同模块中。与把全部功能直接写入 main.c 相比,这种结构更加容易阅读、维护和扩展。
另一个重要收获来自实际排错过程。例如 RTC 头文件依赖错误并不是源代码错误,而是旧构建缓存导致;OLED 调试问题也不是简单的接线问题,而是 I²C 初始化过程中引脚 PAD 配置被修改。这些问题使我认识到嵌入式调试不能只检查自己的应用代码,还需要关注 SDK、Makefile、外设初始化顺序以及底层寄存器状态。
目前系统已经完成智能医药箱的基本软件框架,能够支持多次服药计划、定时提醒、OLED 显示、LED 与蜂鸣器声光提示、按键确认、BLE 无线设置以及 Flash 数据保存。后续还可以增加霍尔传感器检测药盒开盖状态、重量传感器判断药物是否被取出、独立手机 APP、低功耗休眠以及服药历史统计等功能,使系统从“提醒设备”进一步扩展为完整的智能用药管理终端。
总体而言,本次项目不仅完成了 MAX32650FTHR 多类外设的综合应用,也锻炼了从需求分析、硬件接口规划、驱动开发、程序架构设计到整机调试的完整工程能力,对后续开展更加复杂的嵌入式和物联网项目具有较好的实践意义。