关于制作基于STM32的智能垃圾桶的总结
一、项目概述
本项目基于STM32F103C8T6微控制器,设计并实现了一款具备多种智能功能的垃圾桶。系统通过各类传感器感知环境与用户需求,实现自动开盖、消毒、火灾预警、状态监测及手机交互等功能,体现了嵌入式系统在智能家居领域的应用。
二、硬件模块清单
| 模块名称 | 功能说明 |
|---|---|
| 主控芯片 | STM32F103C8T6(核心控制单元) |
| 电源模块 | 为系统各模块提供稳定电源 |
| 独立按键模块 | 手动控制、功能切换 |
| 继电器 | 控制紫外线消毒灯等高功率设备 |
| UV紫外线消毒灯 | 垃圾桶内部自动杀菌 |
| 红外光电传感器 | 检测人手或物体,触发开盖 |
| SG90舵机模块 | 驱动垃圾桶盖自动开合 |
| 火焰传感器 | 检测火源,实现火灾报警 |
| HC-SR04超声波传感器 | 测量垃圾高度,提醒清理 |
| 蓝牙模块 | 与手机通信,实现远程控制与状态查看 |
| OLED显示屏 | 显示垃圾桶状态(如垃圾量、模式等) |
| LED模块 | 状态指示(如消毒中、已满、报警等) |
| 蜂鸣器模块 | 火灾报警、提醒提示音 |
| 手机(嘿嘿) | 用户终端,通过蓝牙与垃圾桶交互 |
三、涉及的主要通信协议与外设
| 协议/外设类型 | 在项目中的应用场景 |
|---|---|
| GPIO | 控制LED、蜂鸣器、按键输入、继电器开关 |
| UART | 蓝牙模块与STM32间的串口通信 |
| IIC | 驱动OLED显示屏 |
| TIM(定时器) | 1. 产生PWM信号控制舵机角度 2. 为超声波传感器提供时序控制 3. 系统延时与定时任务 |
| 外部中断 | 用于按键紧急触发、火焰传感器报警等即时响应事件 |
四、关键步骤与遇到的问题
1. 蓝牙模块(AT指令配置)
-
关键步骤:
-
将蓝牙模块的
KEY(或EN)引脚拉高(接VCC),使其进入AT指令模式。 -
通过STM32的UART(或USB转TTL)连接蓝牙模块的
TX、RX。 -
使用串口调试助手,以纯英文模式(注意字符编码)发送AT指令(如
AT+NAME=SmartBin)进行名称、配对码、波特率等参数配置。 -
配置完成后,将
KEY引脚拉低,使其退出AT模式进入正常工作(透传)模式。
-
-
遇到的问题与解决:
-
问题1:无法进入AT模式
-
现象:仅给模块断电(VCC),再上电后发送AT指令无回应。
-
原因:模块状态未完全复位。
KEY引脚电平可能未在正确时刻保持高电平。 -
解决:确保VCC和
KEY引脚都完全断电后,先拉高KEY引脚,再给VCC上电。这是进入AT模式的关键时序。
-
-
问题2:AT指令无响应或返回错误
-
现象:发送指令后无
OK返回。 -
原因:串口调试助手输入法为中文,导致指令中包含不可见的中文字符(如空格);或波特率设置错误。
-
解决:在串口工具中切换至英文输入法重新输入;或发送纯英文的
AT(无任何后缀)测试连接,并核对双方波特率。
-
-

2. OLED显示屏显示汉字
-
关键步骤:
-
取模软件:使用PC端OLED取模软件(如
PCtoLCD2002)。 -
设置参数:根据所用OLED驱动芯片(通常是SSD1306),设置正确的取模方式。常见设置为:列行式、逆向、C51格式(十六进制数组)。
-
生成字模:输入所需汉字,生成对应的点阵数据数组(如
const unsigned char Chinese[]={...})。 -
调用显示函数:在程序中调用OLED驱动库的图形显示函数,将字模数组写入显示RAM。
-
-
遇到的问题与解决:
-
问题:直接显示汉字出现乱码或错位。
-
原因:OLED本身不含中文字库,必须使用点阵数据。乱码通常是因为取模格式(逐行/逐列、字节顺序)与驱动程序的显示函数不匹配。
-
解决:核对并统一取模软件设置与驱动程序的数据处理逻辑。通常需要调整取模软件的“取模方式”并进行测试。
-

3. OLED驱动初始化与显示
-
关键步骤:
-
系统上电后,首先进行OLED硬件初始化(通过I2C或SPI发送一系列配置命令)。
-
初始化后清屏,再执行后续的显示操作。
-
-
遇到的问题与解决:
-
问题1:屏幕无任何显示
-
原因:初始化序列未成功执行或时序不对;I2C地址错误;硬件连接(SDA、SCL)不可靠。
-
解决:确保
OLED_Init()函数在任何显示操作前被调用;用逻辑分析仪或示波器检查I2C总线信号;核对模块的I2C地址(通常是0x78或0x7A)。
-
-
问题2:程序烧录后必须手动复位才能显示
-
现象:下载程序后屏幕仍是空白,按下复位键后正常。
-
原因:系统上电后,OLED模块的电源和内部控制器需要一定的准备时间(几毫秒到几十毫秒),而STM32的初始化速度过快,在OLED还未就绪时就发送了初始化命令,导致命令被忽略。
-
解决:在单片机初始化后、OLED初始化前,增加一个足够长的延时(如100ms),确保OLED模块已完全上电就绪。也可以在OLED初始化函数中,在发送软复位命令后增加延时。
-
-

AI给出的加延时的底层原因

4. 舵机控制(SG90)
-
关键步骤:
-
明确舵机类型:确认使用的是180°位置舵机(用于控制开盖角度)还是360°连续旋转舵机(只能控制速度和方向)。
-
PWM信号生成:使用STM32的TIM(定时器)输出PWM信号,周期设置为20ms(50Hz)。
-
对于180°舵机:通过调节占空比(高电平时间)控制角度。通常:
-
0.5ms → 0°
-
1.5ms → 90°
-
2.5ms → 180°
-
-
对于360°舵机:占空比控制旋转速度和方向:
-
1.5ms → 停止
-
1.0ms → 全速正转(具体方向取决于接线)
-
2.0ms → 全速反转
-
-
-
配置

-
代码

-
供电隔离:舵机必须使用独立的5V电源供电(可从Type-C口取电),避免与单片机共用3.3V电源,同时确保两者的GND相连。
-
-
遇到的问题与解决:
-
问题1:舵机不转动或抖动
-
现象:舵机发出“滋滋”声但不转动,或轻微抖动。
-
原因:供电不足。SG90工作电流在150-300mA左右,而STM32的3.3V输出或DAPLink的3.3V引脚无法提供足够电流。
-
解决:使用外部5V电源单独为舵机供电,确保电源能提供至少1A的电流。同时,将外部电源的GND与STM32的GND连接。
-
-
问题2:舵机一直旋转(死循环)
-
现象:180°舵机不停旋转而不停止在指定角度。
-
原因:错误地使用了360°连续旋转舵机,或者PWM信号参数设置错误(如周期不对、占空比超出范围)。
-
解决:首先确认舵机型号。若为180°舵机,则检查PWM周期是否为20ms,并确保占空比在0.5ms-2.5ms之间。若为360°舵机,则只能控制其旋转时间和速度来间接控制“角度”。
-
-
问题3:控制信号电压不足
-
现象:供电正常,但舵机响应不灵敏或角度不准。
-
原因:STM32的IO口输出为3.3V,而舵机控制信号理想电压为5V。
-
解决:添加电平转换电路(如使用三极管或MOS管)将3.3V PWM信号升压至5V。在实际测试中,3.3V信号有时也能驱动,但5V信号更可靠。
-
-
5. 供电问题(DAPLink与USB)
-
关键步骤:
-
区分供电角色:DAPLink主要用于程序下载和调试,其3.3V引脚电流能力有限(通常≤200mA)。
-
系统供电设计:当需要驱动舵机、继电器等大电流设备时,必须使用外部电源(如通过开发板的Type-C/USB口输入5V,或使用独立的5V电源模块)。
-
电源隔离:对电机类负载(如舵机)采用独立供电,并在电源线上并联大电容(如100µF)以吸收电流突变。
-
-
遇到的问题与解决:
-
问题:使用DAPLink供电时系统不稳定
-
现象:连接舵机或继电器后,单片机复位、程序跑飞或DAPLink断开。
-
原因:DAPLink的3.3V输出电流过载,触发其保护机制或导致电压跌落。
-
解决:绝不使用DAPLink的3.3V引脚为整个系统供电。仅将其用于调试接口,系统电源应通过开发板的电源接口(如Type-C)提供。如果开发板无此设计,则需自行搭建5V转3.3V的稳压电路为STM32供电。
-
-
6.HC-SR04超声波传感器应用详解
(一)、HC-SR04基本原理
1. 工作原理
HC-SR04通过超声波测距,包含两个核心部件:
-
发射器:发射超声波脉冲
-
接收器:接收反射回来的超声波
2. 测量时序
Trigger: ___|¯¯ ¯¯ ¯¯ ¯¯ ¯¯|_________________ (碰到物体停止触发)
↑ ↑
触发 停止触发Echo: ________________|¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯|____ (高电平持续时间=往返时间) ↑ ↑
回波开始 回波结束
3. 距离计算公式
距离(cm) = (高电平时间(μs) × 声速(340m/s)) ÷ 2 ÷ 10000
= 高电平时间(μs) ÷ 58
= 高电平时间(μs) × 0.017
关键配置说明:
| 参数 | 通道1 | 通道2 | 说明 |
|---|---|---|---|
| 触发边沿 | 上升沿 | 下降沿 | 分别捕获Echo的起始和结束 |
| 中断使能 | 否 | 是 | 只在下降沿触发中断处理 |
| 滤波器 | 可选 | 可选 | 防干扰,建议4-8个时钟周期 |


(二)、STM32实现详解
1. 初始化配置(TIM输入捕获模式)
void hc_sr04_init(void)
{
HAL_TIM_Base_Start(&htim1);
HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);
}
2. 脉冲触发实现
// 在主循环或超声波任务中计算距离
void hc_sr04_proc(void)
{
static uint32_t last_trigger = 0;
uint32_t now = HAL_GetTick();
/* Trigger at a safe rate (HC-SR04 recommends >=60ms between triggers). */
if ((uint32_t)(now - last_trigger) >= HC_SR04_TRIGGER_PERIOD_MS) {
last_trigger = now;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
delay_us(15);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
__HAL_TIM_SetCounter(&htim1, 0);
}
}
3. 测量计算与中断处理
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim1 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
upEage = (uint16_t)HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_1);
downEage = (uint16_t)HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_2);
// 只记录脉宽,不在中断中计算
if(downEage >= upEage) {
echo_width = downEage - upEage;
} else {
// 处理定时器溢出
echo_width = 65535 - upEage + downEage;
}
new_data_ready = 1;
}
}
// 处理新数据
if(new_data_ready) {
new_data_ready = 0;
// 计算距离
float raw_distance = echo_width * 0.017f; // (0.034/2)
// 距离滤波(指数滑动平均)
static float filtered_distance = TRASH_EMPTY_DISTANCE_CM;
if (raw_distance > 0.0f && raw_distance < 500.0f) {
filtered_distance = filtered_distance * 0.7f + raw_distance * 0.3f;
}
distance = filtered_distance; /* publish filtered distance */
if(distance_flag==1){
UART_Printf_DMA("distance:%.2f\r\n",distance);
distance_flag=0;
}
}
4. 完整使用流程
// 主程序示例
int main(void)
{
// 1. 初始化
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM1_Init();
OLED_Init();
hc_sr04_init();
// 2. 主循环
while (1)
{
// 触发一次测量
hc_sr04_trigger();
// 等待测量完成(最长40ms,对应约7m距离)
uint32_t timeout = HAL_GetTick() + 50; // 50ms超时
while(!new_data_ready && HAL_GetTick() < timeout);
// 显示结果
hc_sr04_display_result();
// 适当延时,避免频繁触发(HC-SR04最小测量周期60ms)
HAL_Delay(100);
}
}
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)