基于STM32的电子药盒提醒装置实现

一、系统架构设计

  1. 核心功能模块

    • 定时提醒:通过DS1302时钟模块获取时间,触发蜂鸣器与LED报警

    • 状态反馈:红外传感器检测药盒开合状态,通过蓝牙模块同步至手机APP

    • 人机交互:OLED显示屏实时显示时间与状态,按键设置提醒时间

  2. 硬件组成

    模块 型号/接口 功能说明
    主控芯片 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 红外传感器 低电平表示药盒开启

四、调试与优化建议

  1. 时间同步问题

    • 使用STM32CubeMX配置RTC时钟源为外部LSE(32.768kHz晶振)

    • 添加闰年补偿算法(参考DS1302_SetTime函数)

  2. 抗干扰措施

    • 在DS1302电源引脚并联10μF电解电容 + 0.1μF陶瓷电容

    • OLED数据线套磁环抑制高频噪声

  3. 低功耗优化

    // 进入睡眠模式(需外部中断唤醒)
    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
    

参考代码 基于STM32的一种电子药盒提醒装置 www.youwenfan.com/contentcnr/102265.html

五、扩展功能实现

  1. 药品余量检测

    // 使用HX711称重模块
    float Get_DrugWeight() {
      float weight = (HX711_GetValue() - OFFSET) * SCALE_FACTOR;
      return weight > 50.0f ? 1 : 0;  // 重量>50g表示充足
    }
    
  2. 语音播报模块

    // WT588D语音芯片控制
    void Play_Reminder() {
      WT588D_SendCommand(0xAA, 0x06, 0x01, 0x00, 0x00, 0x00);  // 播放语音1
    }
    
posted @ 2026-03-06 16:29  hczyydqq  阅读(2)  评论(0)    收藏  举报