STM32F103C8T6 + ESP8266 智能药盒:CubeMX 配置 Wi-Fi 通信 5 步实现

📅 2026/7/10 12:28:53 👁️ 阅读次数 📝 编程学习
STM32F103C8T6 + ESP8266 智能药盒:CubeMX 配置 Wi-Fi 通信 5 步实现

STM32F103C8T6与ESP8266智能药盒开发实战:CubeMX配置与Wi-Fi通信全解析

在医疗健康领域,智能药盒正逐渐成为慢性病患者的日常必需品。本文将深入探讨如何基于STM32F103C8T6微控制器和ESP8266 Wi-Fi模块构建一个功能完善的智能药盒系统。不同于市面上通用的教程,我们将从硬件选型到软件配置,提供一套完整的开发框架和优化方案。

1. 硬件架构设计与核心组件选型

智能药盒的硬件设计需要平衡性能、功耗和成本三个关键因素。经过多次原型验证,我们最终确定的硬件方案如下:

主控制器选择

  • STM32F103C8T6:这款基于Cortex-M3内核的MCU具有72MHz主频、64KB Flash和20KB SRAM,完全满足智能药盒的实时控制需求。其丰富的外设接口(多达3个USART、2个SPI和2个I2C)为系统扩展提供了充足空间。

通信模块选型对比

模块型号协议支持传输距离功耗开发难度成本
ESP8266Wi-Fi室内50m中等较低$3
HC-05Bluetooth10m中等$5
NRF24L012.4GHz100m较高$2

选择ESP8266的主要考虑是其成熟的AT指令集和直接连接云端的能力,这对远程监控功能至关重要。

传感器配置方案

  • DHT11温湿度传感器:监测药品存储环境
  • 光电开关阵列:检测每个药格的状态
  • 蜂鸣器+LED:多模式提醒组合
  • 0.96寸OLED:本地信息显示

硬件连接示意图:

STM32F103C8T6 <--UART2--> ESP8266 <--I2C1--> OLED <--GPIO--> 光电开关 <--GPIO--> 蜂鸣器 <--1-Wire--> DHT11

2. CubeMX工程配置关键步骤

STM32CubeMX是ST官方提供的可视化配置工具,能极大提高开发效率。以下是针对本项目的具体配置流程:

2.1 时钟树配置

  1. 选择外部高速时钟(HSE)作为时钟源
  2. 设置PLL倍频系数为9,得到72MHz系统时钟
  3. 配置APB1分频器为2(36MHz),APB2不分频(72MHz)
// 生成的时钟配置代码片段 void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 配置HSE和PLL RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; HAL_RCC_OscConfig(&RCC_OscInitStruct); // 配置时钟树 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); }

2.2 外设初始化

  1. USART2配置

    • 波特率:115200
    • 字长:8位
    • 停止位:1
    • 无校验位
    • 开启全局中断
  2. GPIO配置

    • 光电开关输入:上拉模式
    • 蜂鸣器输出:推挽输出
    • LED指示灯:推挽输出
  3. I2C配置

    • 标准模式(100kHz)
    • 7位地址模式

注意:CubeMX生成的代码默认使用HAL库,如需更高性能可考虑直接操作寄存器或使用LL库。

3. ESP8266通信模块深度配置

ESP8266作为Wi-Fi连接的核心,其稳定性和响应速度直接影响用户体验。我们采用AT指令进行控制,以下是优化后的配置流程:

3.1 基础AT指令测试

void ESP8266_Test(void) { char cmd[] = "AT\r\n"; char response[100]; HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY); HAL_Delay(100); if(HAL_UART_Receive(&huart2, (uint8_t*)response, sizeof(response), 100) > 0) { if(strstr(response, "OK") != NULL) { printf("ESP8266响应正常\n"); } } }

3.2 Wi-Fi连接配置

完整的连接流程应包括以下步骤:

  1. 设置Wi-Fi模式为STA(客户端模式)
    AT+CWMODE=1
  2. 连接到路由器
    AT+CWJAP="SSID","password"
  3. 获取本地IP地址
    AT+CIFSR
  4. 启用多连接模式
    AT+CIPMUX=1

常见问题处理

  • 连接超时:检查SSID和密码是否正确,信号强度是否足够
  • AT无响应:检查接线是否正确,波特率是否匹配
  • 频繁断开:尝试降低ESP8266发射功率(AT+RFPOWER=10)

3.3 MQTT协议实现

我们选择MQTT作为云端通信协议,因其轻量级和低功耗特性非常适合物联网设备。

void MQTT_Connect(void) { char cmd[150]; // 建立TCP连接 sprintf(cmd, "AT+CIPSTART=0,\"TCP\",\"%s\",%d\r\n", MQTT_SERVER, MQTT_PORT); HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY); HAL_Delay(1000); // 发送MQTT连接报文 uint8_t mqtt_connect[] = { 0x10, 0x1A, // 固定报头 0x00, 0x04, 'M', 'Q', 'T', 'T', // 协议名 0x04, // 协议级别 0xC2, // 连接标志(clean session) 0x00, 0x3C, // 保持连接时间 0x00, 0x07, 'c', 'l', 'i', 'e', 'n', 't', '1' // 客户端ID }; sprintf(cmd, "AT+CIPSEND=0,%d\r\n", sizeof(mqtt_connect)); HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), HAL_MAX_DELAY); HAL_Delay(100); HAL_UART_Transmit(&huart2, mqtt_connect, sizeof(mqtt_connect), HAL_MAX_DELAY); }

4. 系统软件架构与关键实现

智能药盒的软件设计采用分层架构,确保各模块高内聚低耦合。

4.1 主程序流程图

初始化硬件 ↓ 连接Wi-Fi ↓ 同步网络时间 ↓ 进入主循环: 读取传感器数据 → 处理数据 → 检查用药时间 → 触发提醒 → 上传云端

4.2 用药提醒逻辑实现

void CheckMedicationTime(void) { RTC_TimeTypeDef currentTime; HAL_RTC_GetTime(&hrtc, &currentTime, RTC_FORMAT_BIN); for(int i = 0; i < MAX_SCHEDULES; i++) { if(schedules[i].hour == currentTime.Hours && schedules[i].minute == currentTime.Minutes && !schedules[i].taken) { TriggerReminder(); UpdateLEDPattern(i); SendNotification(i); break; } } } void TriggerReminder(void) { // 渐进式提醒策略 for(int i = 0; i < 3; i++) { HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET); HAL_Delay(200); HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET); HAL_Delay(200); } }

4.3 低功耗优化策略

  1. 睡眠模式配置

    void EnterSleepMode(void) { HAL_SuspendTick(); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); HAL_ResumeTick(); }
  2. 外设时钟管理

    // 不使用时关闭外设时钟 __HAL_RCC_USART2_CLK_DISABLE();
  3. 动态频率调整

    void AdjustClockSpeed(uint8_t level) { RCC_ClkInitTypeDef RCC_ClkInitStruct; uint32_t pFLatency; HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency); // 根据需求调整系统时钟 if(level == LOW_POWER) { RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency); } }

5. 云端交互与手机APP对接

现代智能设备离不开云端支持,我们设计了简洁高效的通信协议。

5.1 数据格式定义

{ "device_id": "PILLBOX_001", "timestamp": 1634567890, "events": [ { "type": "MEDICATION", "compartment": 1, "status": "TAKEN", "time": "08:00" }, { "type": "TEMPERATURE", "value": 25.3, "unit": "Celsius" } ] }

5.2 OTA升级实现

安全可靠的OTA功能可以远程修复问题和添加新特性。

升级流程

  1. 检查新固件版本
    AT+HTTPGET="http://server.com/version"
  2. 下载固件包
    AT+HTTPGET="http://server.com/firmware.bin"
  3. 校验MD5值
  4. 跳转到Bootloader
    void JumpToBootloader(void) { void (*bootloader)(void) = (void (*)(void))(*((uint32_t*)0x1FFFF000)); HAL_RCC_DeInit(); HAL_DeInit(); SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; __set_MSP(*((uint32_t*)0x1FFFF000)); bootloader(); }

5.3 数据同步策略

采用"本地存储+云端同步"的双重保障机制:

  • 本地:使用STM32内部Flash模拟EEPROM存储关键数据
  • 云端:定时同步和事件触发同步相结合
#define EEPROM_START_ADDR 0x08080000 void SaveToFlash(uint8_t* data, uint16_t size) { HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef EraseInitStruct; EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = EEPROM_START_ADDR; EraseInitStruct.NbPages = 1; uint32_t PageError; HAL_FLASHEx_Erase(&EraseInitStruct, &PageError); for(uint16_t i = 0; i < size; i += 4) { uint32_t word = *(uint32_t*)(data + i); HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, EEPROM_START_ADDR + i, word); } HAL_FLASH_Lock(); }

在实际项目中,我们遇到了ESP8266在长时间运行后偶发断连的问题。通过分析发现是Wi-Fi信号干扰导致,最终解决方案是:

  1. 增加信号强度检测机制
  2. 实现自动重连功能
  3. 添加看门狗监控通信状态
  4. 优化天线布局和匹配电路