用STM32F103C8T6和OLED屏,我复刻了一个迷你自动售货机(附完整代码和接线图)
2026/6/12 0:46:26 网站建设 项目流程

从零打造迷你自动售货机:STM32F103C8T6全流程实战

去年夏天,我在清理工作室时翻出一堆闲置的电子元件——几块吃灰的STM32开发板、0.96寸OLED屏、矩阵键盘模块,还有上次项目剩下的继电器。这些看似不相关的零件突然让我萌生一个想法:何不做一个迷你自动售货机模型?既能消化库存元件,又能复刻我们每天都能见到的商业设备工作原理。经过三周的反复调试,这个巴掌大的装置不仅能完整模拟真实售货机的商品选择、投币找零流程,还加入了LED指示灯和音效反馈。下面就将整个制作过程拆解成可复用的经验,特别适合有一定嵌入式基础的创客练手。

1. 硬件架构设计与关键元件选型

1.1 核心控制器:STM32F103C8T6的性价比之选

这块被称为"蓝色药丸"的最小系统板虽然只有64KB Flash和20KB RAM,但72MHz的主频足够处理售货机的控制逻辑。相比Arduino,STM32的优势在于:

  • GPIO资源丰富:37个可用IO口轻松应对矩阵键盘+OLED+继电器的需求
  • 硬件SPI接口:驱动OLED时刷新速率可达8MHz
  • 内置定时器:精确控制按键消抖和继电器动作时序

实际使用中需要注意:

// 时钟配置示例(使用内部8MHz RC振荡器) RCC_DeInit(); RCC_HSEConfig(RCC_HSE_OFF); RCC_HSICmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);

1.2 显示模块:SSD1306 OLED的省电方案

0.96寸128x64分辨率的OLED屏在功耗和显示效果上完胜LCD:

  • 零待机功耗:黑色像素完全关闭
  • 高对比度:即使在阳光下也清晰可见
  • 硬件I2C接口:仅需4根连线

接线时常见的坑:

  • 如果屏幕闪烁,检查I2C上拉电阻(通常需要4.7kΩ)
  • 地址冲突时尝试将屏幕的SA0引脚接高电平(0x3D地址)

1.3 输入输出设备组合

矩阵键盘:4x4布局实现16个按键功能,扫描原理如下表:

扫描方式优点缺点
行扫描代码简单需要较多IO口
中断触发省电电路复杂
ADC分压仅需1个IO精度要求高

最终选择行扫描法,配合10ms定时器消抖:

uint8_t KEY_Scan(void) { static uint8_t key_up = 1; if(key_up && (KEY_ROW1==0 || KEY_ROW2==0 || KEY_ROW3==0 || KEY_ROW4==0)) { delay_ms(10); key_up = 0; // 扫描具体行列... } else if(KEY_ROW1==1 && KEY_ROW2==1 && KEY_ROW3==1 && KEY_ROW4==1) { key_up = 1; } return key_val; }

2. 电路设计与实战接线图

2.1 电源管理设计

整个系统采用USB 5V供电,通过AMS1117-3.3稳压芯片为STM32供电。继电器模块需要单独5V电源防止电流倒灌,实际接线时特别注意:

警告:继电器线圈在断开时会产生反向电动势,必须并联续流二极管

完整的元件清单:

元件型号数量备注
主控STM32F103C8T61需安装Bootloader
显示屏SSD1306 OLED1I2C接口
键盘4x4矩阵1薄膜式最佳
继电器SRD-05VDC1常开触点

2.2 信号线连接方案

为了避免飞线混乱,建议按功能分区连接:

  1. 显示模块

    • SCL -> PB6
    • SDA -> PB7
    • VCC -> 3.3V
    • GND -> GND
  2. 矩阵键盘

    • 行线 -> PA0~PA3
    • 列线 -> PA4~PA7
  3. 继电器控制

    • IN -> PC13
    • VCC -> 5V(独立电源)
    • GND -> 共地

3. 软件架构与核心算法实现

3.1 状态机设计:售货流程的完美建模

将用户操作抽象为五个状态,用枚举变量实现:

typedef enum { STATE_IDLE, // 待机状态 STATE_SELECT_ITEM, // 选择商品 STATE_SELECT_QTY, // 选择数量 STATE_PAYMENT, // 投币支付 STATE_DELIVERY // 出货状态 } VendingState;

状态转换触发条件:

当前状态触发事件下一状态动作
IDLE按下S1/S5SELECT_ITEM显示商品菜单
SELECT_ITEM按下S9/S13SELECT_QTY显示数量选择
SELECT_QTY按下S12PAYMENT计算总价
PAYMENT投币足够DELIVERY驱动继电器

3.2 价格计算与投币逻辑

采用结构体存储交易数据,避免全局变量混乱:

typedef struct { uint8_t current_item; uint8_t quantity; uint16_t unit_price[8]; // 8种商品单价 uint16_t total; uint16_t coin_inserted; uint16_t change; } TransactionData;

投币验证算法示例:

void process_coin(uint16_t amount) { transaction.coin_inserted += amount; if(transaction.coin_inserted >= transaction.total) { transaction.change = transaction.coin_inserted - transaction.total; state = STATE_DELIVERY; OLED_Clear(); OLED_ShowString(0, 16, "Change:", FONT_16); OLED_ShowNumber(56, 16, transaction.change, FONT_16); } else { uint16_t remaining = transaction.total - transaction.coin_inserted; OLED_ShowString(0, 32, "Need more:", FONT_16); OLED_ShowNumber(80, 32, remaining, FONT_16); } }

4. 调试技巧与性能优化

4.1 OLED显示刷新优化

直接刷新全屏会导致肉眼可见的闪烁,采用差异刷新策略:

  1. 定义显示缓存结构
typedef struct { char line1[21]; // 128像素/6像素每字符 ≈ 21字符 char line2[21]; char line3[21]; char line4[21]; } DisplayBuffer;
  1. 比较新旧内容,仅更新变化部分
void smart_refresh(DisplayBuffer *new, DisplayBuffer *old) { if(strcmp(new->line1, old->line1)) { OLED_ShowString(0, 0, new->line1, FONT_16); strcpy(old->line1, new->line1); } // 其他行同理... }

4.2 继电器驱动时序问题

测试中发现继电器有时会误动作,通过示波器捕获到的问题:

  • 线圈驱动信号上升沿太缓(>2ms)
  • MCU复位时GPIO处于浮空状态

改进方案:

// 硬件改进:GPIO增加10k下拉电阻 // 软件改进: void relay_control(uint8_t on) { if(on) { GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); delay_ms(50); // 确保完全吸合 } else { GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); delay_ms(20); // 确保完全释放 } }

4.3 低功耗设计技巧

虽然售货机通常常电运行,但加入休眠模式可延长电池续航:

  1. 配置停机模式:
void enter_stop_mode(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); // 唤醒后需要重新配置系统时钟 SystemInit(); }
  1. 通过按键中断唤醒:
void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { EXTI_ClearITPendingBit(EXTI_Line0); // 唤醒处理逻辑 } }

这个项目最让我惊喜的是,用成本不到50元的元件就实现了一个真实可用的自动售货机核心功能。特别是在调试继电器时序时,用逻辑分析仪捕获到的信号异常最终让我理解了硬件消抖的重要性。如果想让项目更具商业价值,可以考虑增加RFID支付模块或者网络远程库存管理功能——这正好是我下一步的升级计划。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询