基于STM32的电子药盒提醒装置实现
一、系统架构设计
-
核心功能模块
-
定时提醒:通过DS1302时钟模块获取时间,触发蜂鸣器与LED报警
-
状态反馈:红外传感器检测药盒开合状态,通过蓝牙模块同步至手机APP
-
人机交互:OLED显示屏实时显示时间与状态,按键设置提醒时间
-
-
硬件组成
模块 型号/接口 功能说明 主控芯片 STM32F103C8T6 核心控制器 时钟模块 DS1302 精确时间管理 显示模块 OLED 0.96英寸(I2C) 时间/状态显示 通信模块 HC-05蓝牙模块 手机APP数据交互 传感器 红外对管(开盒检测) 药盒状态监测 提示装置 蜂鸣器+LED灯 声光报警
二、代码实现(HAL库+标准外设库)
1. 工程结构
├── Core/
│ ├── Inc/
│ │ ├── main.h
│ │ ├── ds1302.h
│ │ ├── oled.h
│ │ └── bluetooth.h
│ └── Src/
│ ├── main.c
│ ├── ds1302.c
│ ├── oled.c
│ └── bluetooth.c
├── Drivers/
│ ├── CMSIS/
│ └── STM32F1xx_HAL_Driver/
└── Middlewares/
└── Bluetooth/
2. 核心代码
(1) DS1302时钟驱动(ds1302.c)
#include "ds1302.h"
void DS1302_Init(void) {
// 初始化GPIO与SPI
__HAL_RCC_SPI1_CLK_ENABLE();
DS1302_RST = 0; // 复位信号
HAL_Delay(1);
DS1302_CLK = 0; // 时钟信号
HAL_Delay(1);
DS1302_RST = 1; // 释放复位
}
void DS1302_WriteByte(uint8_t addr, uint8_t dat) {
for(int i=0; i<8; i++) {
DS1302_IO = 0; // 发送地址位
DS1302_CLK = 1;
DS1302_CLK = 0;
DS1302_IO = (dat & 0x01);
dat >>= 1;
}
}
uint8_t DS1302_ReadByte(uint8_t addr) {
uint8_t dat = 0;
addr |= 0x80; // 读模式
for(int i=0; i<8; i++) {
DS1302_IO = 0;
DS1302_CLK = 1;
DS1302_CLK = 0;
dat >>= 1;
DS1302_IO = 1;
}
return dat;
}
(2) OLED显示驱动(oled.c)
#include "oled.h"
void OLED_Init(void) {
// 初始化I2C
HAL_I2C_Init(&hi2c1);
OLED_WriteCmd(0xAE); // 关闭显示
OLED_WriteCmd(0x20); // 设置内存地址模式
OLED_WriteCmd(0xB0); // 设置页起始地址
}
void OLED_DisplayTime(uint8_t hour, uint8_t min) {
char buf[16];
sprintf(buf, "Time: %02d:%02d", hour, min);
OLED_ShowString(0, 0, buf);
}
(3) 蓝牙通信处理(bluetooth.c)
#include "bluetooth.h"
void Bluetooth_Init(void) {
// 初始化USART2
MX_USART2_UART_Init();
}
void Bluetooth_ProcessCmd(char *cmd) {
if(strncmp(cmd, "SET:",4) == 0) {
sscanf(cmd+4, "%d:%d", &medicine_time[0], &medicine_time[1]);
sprintf(send_buf, "Time set to %02d:%02d", medicine_time[0], medicine_time[1]);
HAL_UART_Transmit(&huart2, (uint8_t*)send_buf, strlen(send_buf), 100);
}
}
(4) 主程序(main.c)
#include "main.h"
#include "ds1302.h"
#include "oled.h"
#include "bluetooth.h"
extern uint8_t medicine_time[2]; // 设定时间[小时][分钟]
int main(void) {
HAL_Init();
SystemClock_Config();
DS1302_Init();
OLED_Init();
Bluetooth_Init();
while(1) {
// 获取当前时间
RTC_TimeTypeDef sTime;
HAL_RTC_GetTime(&hrtc, &sTime, FORMAT_BIN);
// 时间匹配检测
if(sTime.Hours == medicine_time[0] && sTime.Minutes == medicine_time[1]) {
HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET);
OLED_DisplayString(2, 0, "Medicine Time!");
} else {
HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET);
}
// 蓝牙指令处理
if(USART2_RX_STA) {
Bluetooth_ProcessCmd(USART2_RX_BUF);
USART2_RX_STA = 0;
}
HAL_Delay(1000);
}
}
三、硬件连接说明
| STM32引脚 | 外设模块 | 连接说明 |
|---|---|---|
| PA0 | DS1302_SCLK | 时钟信号 |
| PA1 | DS1302_IO | 数据总线 |
| PA2 | DS1302_RST | 复位信号 |
| PB6 | OLED_SDA | I2C数据线 |
| PB7 | OLED_SCL | I2C时钟线 |
| PA9/PA10 | HC-05_UART | 蓝牙通信 |
| PC13 | 蜂鸣器 | 高电平触发 |
| PA8 | 红外传感器 | 低电平表示药盒开启 |
四、调试与优化建议
-
时间同步问题
-
使用
STM32CubeMX配置RTC时钟源为外部LSE(32.768kHz晶振) -
添加闰年补偿算法(参考
DS1302_SetTime函数)
-
-
抗干扰措施
-
在DS1302电源引脚并联10μF电解电容 + 0.1μF陶瓷电容
-
OLED数据线套磁环抑制高频噪声
-
-
低功耗优化
// 进入睡眠模式(需外部中断唤醒) HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
参考代码 基于STM32的一种电子药盒提醒装置 www.youwenfan.com/contentcnr/102265.html
五、扩展功能实现
-
药品余量检测
// 使用HX711称重模块 float Get_DrugWeight() { float weight = (HX711_GetValue() - OFFSET) * SCALE_FACTOR; return weight > 50.0f ? 1 : 0; // 重量>50g表示充足 } -
语音播报模块
// WT588D语音芯片控制 void Play_Reminder() { WT588D_SendCommand(0xAA, 0x06, 0x01, 0x00, 0x00, 0x00); // 播放语音1 }

浙公网安备 33010602011771号