1. 项目概述
这个基于STM32单片机的智能感应垃圾桶项目,是我最近完成的一个嵌入式系统综合应用案例。它通过红外人体感应自动控制垃圾桶盖的开合,同时具备手动操作、状态显示和满溢检测功能。作为一个典型的物联网边缘设备原型,这个项目涵盖了传感器采集、电机控制、人机交互等嵌入式开发的核心技术点。
在实际应用中,这种智能垃圾桶可以显著提升公共卫生场景的使用体验。当检测到有人靠近时(约0.5-1米范围内),系统会自动开启桶盖;当人离开后(约3-5秒延迟),桶盖自动关闭。这种非接触式操作不仅卫生便捷,还能有效防止异味扩散。通过Proteus仿真环境,我们可以完整模拟整个系统的运行逻辑,这对初学者理解嵌入式系统的工作机制非常有帮助。
2. 硬件设计解析
2.1 核心控制器选型
选择STM32F103C8T6作为主控芯片主要基于三点考虑:
- 充足的GPIO资源(37个I/O口)满足外设连接需求
- 72MHz主频提供足够的处理能力
- 内置硬件PWM模块方便电机控制
提示:初学者常犯的错误是直接使用开发板而忽略最小系统设计。在实际PCB设计中,务必注意为STM32添加:
- 8MHz晶振电路
- 复位电路(10kΩ上拉电阻+0.1μF电容)
- 3.3V稳压电路
2.2 电机驱动方案
采用ULN2003达林顿阵列驱动28BYJ-48步进电机,这种组合的优势在于:
- ULN2003的500mA驱动能力完美匹配电机的300mA工作电流
- 内置续流二极管简化电路设计
- 成本低廉(整套驱动方案不到5元)
电机接线示意图:
code复制ULN2003 | 28BYJ-48
IN1 → 红
IN2 → 黄
IN3 → 蓝
IN4 → 橙
2.3 传感器接口设计
项目中使用两个数字输入模拟传感器信号:
- PA15:人体检测(低电平有效)
- PA14:满溢检测(低电平有效)
实际应用中推荐使用:
- 人体检测:HC-SR501红外模块(检测距离可调)
- 满溢检测:超声波模块(如HC-SR04)或光电对管
3. 软件实现详解
3.1 系统初始化流程
c复制void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置电机控制引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置传感器输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
3.2 步进电机控制算法
28BYJ-48是四相八拍步进电机,每步转角5.625°,需要64步完成一圈转动。控制时序如下:
| 步序 | IN1 | IN2 | IN3 | IN4 | 相位 |
|---|---|---|---|---|---|
| 1 | 1 | 0 | 0 | 0 | A |
| 2 | 1 | 1 | 0 | 0 | AB |
| 3 | 0 | 1 | 0 | 0 | B |
| ... | ... | ... | ... | ... | ... |
实现代码示例:
c复制void MotoRccw(void) // 正转
{
for(int i=0; i<64; i++) {
ULN2003_SetOutput(step_seq[i%8]);
delay_ms(10); // 调整延时改变转速
}
}
void MotoRcw(void) // 反转
{
for(int i=7; i>=0; i--) {
ULN2003_SetOutput(step_seq[i%8]);
delay_ms(10);
}
}
3.3 状态机设计
系统采用事件驱动型状态机,主要状态包括:
- 待机状态(盖子关闭)
- 开启状态(检测到人体)
- 告警状态(垃圾满溢)
状态转换逻辑:
code复制待机状态 →[人体检测]→ 开启状态
开启状态 →[超时/手动关闭]→ 待机状态
任何状态 →[满溢检测]→ 告警状态
4. Proteus仿真要点
4.1 元件清单
| 元件名称 | Proteus关键字 | 备注 |
|---|---|---|
| STM32F103C8 | STM32F103C8 | 需加载HEX文件 |
| LCD1602 | LM016L | 需配置数据线 |
| ULN2003 | ULN2003A | 注意输入输出方向 |
| 步进电机 | MOTOR-STEPPER | 设置步距角为5.625° |
| 开关 | SW-SPST | 模拟传感器信号 |
4.2 常见仿真问题排查
-
电机不转动
- 检查ULN2003输入输出接线
- 确认步进脉冲序列正确
- 调整电机驱动电压(通常5V)
-
LCD显示乱码
- 检查4/8位数据模式设置
- 确认初始化时序满足说明书要求
- 调整对比度电位器(仿真中可忽略)
-
传感器无响应
- 确认GPIO模式设置为上拉输入
- 检查按键去抖处理(仿真中可简化)
5. 进阶优化建议
5.1 功耗优化技巧
- 采用中断唤醒机制:
c复制void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// PA15连接到EXTI15
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource15);
EXTI_InitStructure.EXTI_Line = EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 配置NVIC
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
- 动态时钟调整:
- 检测到人体时切换到72MHz
- 待机时降频到8MHz
5.2 机械结构改进
-
采用蜗轮蜗杆减速机构:
- 提升扭矩(原电机仅0.1N·m)
- 实现自锁功能(避免盖子意外下落)
-
增加限位开关:
- 硬件限位保护电机
- 精确校准开合角度
6. 项目移植与扩展
6.1 硬件兼容性调整
不同型号STM32的移植要点:
| 功能 | F103配置 | F407调整 |
|---|---|---|
| GPIO时钟 | RCC_APB2Periph | RCC_AHB1Periph |
| 延时函数 | SysTick_Config | 使用TIM更精确 |
| PWM输出 | TIM2_CH1 | 需重映射到对应定时器 |
6.2 物联网功能扩展
-
添加ESP8266模块实现:
- 开盖次数统计
- 满溢状态远程通知
- OTA固件升级
-
典型MQTT通信格式:
json复制{
"deviceID": "bin_001",
"status": "open",
"fillLevel": 30,
"battery": 85
}
我在实际调试中发现,步进电机在低温环境下容易出现失步现象。解决方法是在电机驱动代码中加入温度补偿算法,根据环境温度调整步进脉冲的间隔时间。具体实现可以通过NTC热敏电阻采集温度数据,然后使用以下公式计算补偿值:
c复制int get_step_delay(int temp)
{
// 基准延时10ms在25℃时
int base_delay = 10;
// 温度系数:每降低1℃增加0.1ms
if(temp < 25) {
return base_delay + (25 - temp) * 0.1;
}
return base_delay;
}
