🧹 清扫小车 技术文档

STM32F103C8T6 · TB6612 双路驱动 · HC-05 蓝牙遥控 · 双刷盘独立控制

硬件实物照片

硬件模块详解

STM32F103C8T6 主控芯片

核心控制

这是整个清扫系统的大脑。Cortex-M3 内核 @72MHz,负责运行所有控制逻辑:接收蓝牙命令、输出 4 路 PWM 控制双电机+舵机、管理 10ms 系统节拍、处理按键/编码器中断。程序仅占用 8.5KB Flash,资源余量充足(64KB 总量)。板载 PC13 LED 用于心跳指示,无需外接显示屏也能判断工作状态。

TB6612FNG 双路电机驱动

功率驱动

这是系统的肌肉。内含两路独立 H 桥,每路可输出 1.2A 持续电流,同时驱动左右两个 130 直流电机。通过 AIN1/AIN2 + PWM 三线控制每路电机的转速(0-100%)和方向(正/反转)。PWM 频率 20kHz 高于人耳听觉范围,运转安静无啸叫。VM 接 5V 独立供电,STBY 使能引脚接 3.3V 常开。

130 直流电机 ×2

执行机构

两个 3.7V 额定电压的小型直流电机,各自带动一个圆形毛刷盘旋转清扫。通过 TB6612 实现双路独立 PWM 调速,左右刷盘可分别控制转速(命令 A:50 / B:80)。支持正反转——反转用于处理刷盘被异物卡住的异常情况。5V 短期测试可用,长期建议 3.7V 供电。

HC-05 蓝牙模块

无线通信

手机与清扫小车之间的无线桥梁。通过 USART1 串口(PA9/PA10)与 STM32 通信,波特率 9600bps。手机安装任意蓝牙串口助手 APP 即可发送 ASCII 命令遥控。支持的命令包括:ON/OFF(启停)、S0-100(调速)、A:N/B:N(单路控制)、UP/DN(刷臂升降)、REV(反转防卡)、?(状态查询)。

供电模块

电源管理

系统采用双电源架构:ST-Link 通过 SWD 接口提供 3.3V 逻辑电源(给 STM32、TB6612 逻辑侧、HC-05 供电),USB Type-C 提供 5V 电机电源(给 TB6612 VM 引脚和 SG90 舵机供电)。两个电源的 GND 必须共地,确保信号参考电平一致。

小车底板平台

机械结构

两轮差速驱动底盘,搭载所有硬件模块。底板提供统一的安装平面,TB6612、STM32 核心板、蓝牙模块均固定其上。车轮由独立电机驱动(非本清扫系统控制),清扫刷盘通过支架安装于车头/车侧,刷臂角度由 SG90 舵机调节。

驱动车轮

行走机构

小车底盘的两个驱动轮,由独立的行走电机控制(通过另一块 STM32 板或同一主控的其他 GPIO 控制)。通过两轮差速实现前进、后退、原地旋转。清扫作业时小车慢速前进,刷盘旋转清扫路面,刷臂角度根据路面情况由 SG90 动态调整。

芯片支架底座

结构件

用于固定 STM32 核心板和 TB6612 模块的塑料/金属支架,确保电路板在运动过程中不会松动或短路。支架通过螺丝或卡扣安装在底板上,核心板可直接插拔方便调试和更换。

杜邦连接线

电气连接

套件包含母对母、母对公各 20 根杜邦线(21cm),用于连接 STM32 引脚与各模块。面包板跳线和飞线用于原型验证阶段快速搭建电路。正式安装在小车上后建议用扎带整理走线,避免运动时松动。

紧固件螺母

结构件

用于固定电机支架、刷盘连接件、舵机臂等机械部件。配合螺丝使用,确保清扫机构在震动环境下保持稳定连接。

系统控制流程

🔌 系统上电 / STM32 初始化
▼
⚙️ 外设初始化:TIM1/2/3 PWM + USART1 蓝牙 + TIM4 节拍 + GPIO
▼
🧪 开机自检:双电机 50% 正转 3 秒 → 停止 / LED 心跳启动
▼
📡 等待蓝牙命令 (USART1 中断接收)
✅ 收到命令 → 解析执行
⏳ 继续等待 (LED 慢闪)
▼
ON → 启动双电机 OFF → 停止 S:N → 调速 UP/DN → 刷臂
▼
🔄 每 10ms 执行 Sweep_Task + LED 心跳 + 回到等待命令

STM32F103C8T6 主控芯片上电后,依次初始化 TIM2(SG90 舵机 50Hz PWM)、TIM3(Motor A 20kHz PWM)、 TIM1(Motor B 20kHz PWM)、TIM4(10ms 系统节拍定时器)及 USART1(蓝牙串口 9600bps)。 开机执行 3 秒自检确认双电机通路正常后进入主循环。主循环以 TIM4 10ms 中断为节拍驱动清扫状态机, 同时 USART1 中断接收蓝牙串口数据,当检测到换行符(\r 或 \n)时触发命令解析。命令经去空格、转大写、 字符串匹配后执行对应操作。TB6612 双 H 桥以 20kHz PWM 驱动两个 130 直流电机,占空比可 0%~100% 连续可调, 支持正反转。SG90 舵机以 50Hz PWM 控制刷臂角度(5°抬起 ~ 60°强力下压)。

硬件系统架构


          ┌─────────────────────────────────┐
          │        📱 手机蓝牙串口 APP       │
          │        命令: ON / OFF / S50       │
          └─────────────┬───────────────────┘
                        │ HC-05 BLE (9600)
          ┌─────────────┴───────────────────┐
          │       🧠 STM32F103C8T6          │
          │    Cortex-M3 @ 72MHz            │
          │                                │
          │  PA0→SG90 │ PA6→MotorA │ PA8→MotorB │
          │  PA9/10→HC-05 │ PB0/1/13/14→DIR   │
          └──┬──────────┬──────────┬──────────┘
             │          │          │
    ┌────────┴──┐  ┌───┴──────────┴───┐  ┌───┴───┐
    │  SG90 舵机 │  │    TB6612FNG     │  │ HC-05 │
    │ 刷臂 0~60° │  │ Motor A │ Motor B│  │ 蓝牙  │
    │ 50Hz PWM  │  │ 🧹左刷   │ 🧹右刷  │  └───────┘
    └───────────┘  └──────────────────┘

软件基础设置信息

项目名称清扫小车 — 蓝牙遥控双刷盘嵌入式控制系统
适用场景室内路面自动清扫,可安装于智能小车底盘,手机蓝牙遥控
开发语言C (ARMCC V5.06),基于 STM32 标准外设库 V3.5.0
核心依赖STM32F10x_StdPeriph_Driver、CMSIS Core-M3、startup_stm32f10x_md.s
MCU 平台STM32F103C8T6,Cortex-M3 内核,72MHz,64KB Flash,20KB SRAM
编译工具Keil MDK-ARM V5 (ARMCC V5.06),优化 -O1,C99 + --gnu
程序规模Code=6292B RO-data=2368B RW-data=68B ZI-data=1636B,~8.5KB Flash

软件系统设计

多定时器协同架构

  • TIM1 (20kHz): 高级定时器 CH1→PA8,驱动 Motor B,含 BDTR 死区配置
  • TIM2 (50Hz): CH1→PA0,驱动 SG90 舵机,脉宽 0.5~2.5ms
  • TIM3 (20kHz): CH1→PA6,驱动 Motor A PWM
  • TIM4 (10ms): 系统节拍,PSC=71/ARR=9999,驱动状态机+LED
  • SysTick: delay_ms/us 轮询延迟,与 TIM4 独立

蓝牙命令解析引擎

  • USART1 中断逐字节接收,缓冲区 64 字节
  • 检测 \r 或 \n 触发命令就绪标志
  • 主循环去换行符→去空格→转大写→多路分支匹配
  • 支持完整命令 (ON/OFF/ARM:UP) 和短命令 (1/0/S50/A:65)
  • 命令回显 RX:[cmd] + OK/ERR 确认,方便调试

TB6612 双路电机驱动

  • 双 H 桥独立控制,AIN1/AIN2 方向 + PWM 调速
  • 正转:AIN=10 + 占空比;反转:AIN=01 + 占空比
  • 停止:AIN=00;刹车:AIN=11 (短路制动)
  • PWM 20kHz(高于人耳听觉范围,无啸叫)
  • 占空比映射:speed × 36 = CCR (ARR=3599)

SG90 舵机刷臂控制

  • 50Hz PWM 周期 20ms,脉宽 0.5ms(0°) ~ 2.5ms(180°)
  • PSC=71→1MHz,ARR=19999→20ms 周期
  • 线性映射:CCR = 500 + angle × 2000 / 180
  • 刷臂预设:5°抬起 / 30°轻触 / 45°正常 / 60°强力

按键 + 编码器交互

  • 3 路独立按键 (PB8/9/10),内部上拉,接 GND 触发
  • 消抖:3 次扫描 (30ms);短按 <1s,长按 ≥1s
  • 编码器 EXTI11 下降沿中断,B 相判方向
  • 累计计数转 ±20% 转速微调,仅 RUNNING 生效

LED 心跳状态指示

  • IDLE (待机): PC13 500ms 慢闪
  • RUNNING (运行): PC13 100ms 快闪
  • PAUSED (暂停): PC13 常亮
  • 无需 OLED 即可判断系统工作状态

核心代码模块

TB6612 双电机驱动 (tb6612.c)

/* TB6612 双 H 桥电机驱动 - 20kHz PWM,双路独立 */
void TB6612_Init(void) {
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    // Motor A: PB0(AIN1) PB1(AIN2) + PA6(TIM3_CH1 PWM)
    // Motor B: PB13(BIN1) PB14(BIN2) + PA8(TIM1_CH1 PWM)
    // TIM1 需 BDTR 配置(高级定时器必须)
    TIM_BDTRInitTypeDef bdtr; TIM_BDTRStructInit(&bdtr);
    TIM_BDTRConfig(TIM1, &bdtr); TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
void TB6612_MotorA(int16_t speed) {
    if (speed > 100) speed = 100;
    if (speed < -100) speed = -100;
    if (speed > 0)      { AIN1=1;AIN2=0;TIM_SetCompare1(TIM3,speed*36); }
    else if (speed < 0) { AIN1=0;AIN2=1;TIM_SetCompare1(TIM3,(-speed)*36); }
    else                { AIN1=0;AIN2=0;TIM_SetCompare1(TIM3,0); }
}

SG90 舵机 + 蓝牙命令解析 (main.c)

/* SG90 舵机 - 50Hz PWM */
void SG90_SetAngle(uint8_t angle) {
    uint16_t pulse = 500 + (uint16_t)((uint32_t)angle * 2000 / 180);
    TIM_SetCompare1(TIM2, pulse);  // 500(0°)-2500(180°)
}

/* USART1 中断接收(HC-05 蓝牙, 9600bps)*/
void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE)) {
        char ch = USART_ReceiveData(USART1);
        if (ch == '\n' || ch == '\r') {
            if (uart_idx) { uart_buf[uart_idx]=0; uart_cmd_ready=1; }
        } else if (uart_idx < 63) uart_buf[uart_idx++] = ch;
    }
}

/* 命令解析: 去空白→转大写→分支匹配 */
static void UART_ParseCmd(char *cmd) {
    /* strip \r\n + leading spaces */
    while (*cmd == ' ') cmd++; strupr(cmd);
    if (!strcmp(cmd,"ON"))   TB6612_BrushRun(65);
    else if (!strncmp(cmd,"S",1)) { int v=atoi(cmd+1); TB6612_BrushRun(v); }
    else if (!strcmp(cmd,"UP")) SG90_ArmUp();
    else if (!strcmp(cmd,"DN")) SG90_ArmDown();
}

按键消抖 + 编码器中断 (button.c / encoder.c)

/* 按键扫描 - 每10ms调用 */
void Button_Scan(void) {
    for (uint8_t i=0; i<3; i++) {
        uint8_t cur = GPIO_ReadInputDataBit(pins[i]);
        if (cur==0&&last[i]==1) cnt[i]=0;       // 按下沿, 开始计数
        else if (cur==0) cnt[i]++;              // 持续按下, 累加
        else if (cur==1&&last[i]==0&&cnt[i]>=3)  // 松开沿, 判断
            event[i] = (cnt[i]<100) ? KEY_SHORT : KEY_LONG;
        if (cnt[i]==100) event[i]=KEY_LONG;  // 长按1s
        last[i]=cur;
    }
}
/* 编码器 EXTI11 下降沿中断 */
void EXTI15_10_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line11)) {
        if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)) enc_cnt++; else enc_cnt--;
        EXTI_ClearITPendingBit(EXTI_Line11);
    }
}

参数配置

PWM 频率Motor A: TIM3 20kHz / Motor B: TIM1 20kHz / SG90: TIM2 50Hz
默认转速65%(三档:LOW=40 / MID=65 / HIGH=100),编码器 ±20% 微调
反转防卡转速 -80% 持续 3 秒(300×10ms),自动恢复正转
蓝牙波特率9600-8-N-1,USART1 中断接收,缓冲区 64 字节
系统节拍TIM4 10ms 中断(PSC=71, ARR=9999)
按键消抖3 次确认 (30ms),短按 <1s,长按 ≥1s
LED 闪烁IDLE=500ms / RUNNING=100ms / PAUSED=常亮
开机自检双电机 50% 正转 3 秒 → 停止
MCU 资源Flash ~8.5KB/64KB (13%),SRAM ~1.7KB/20KB (8%)

完整接线引脚表

STM32 引脚功能连接设备技术参数
PA0TIM2_CH1SG90 舵机 信号50Hz PWM, 0~180°, 刷臂5°~60°
PA6TIM3_CH1TB6612 PWMA20kHz PWM, Motor A 转速
PA8TIM1_CH1TB6612 PWMB20kHz PWM, Motor B 转速
PA9 / PA10USART1_TX/RXHC-05 RXD/TXD9600-8-N-1, 蓝牙串口
PB0 / PB1GPIO OutTB6612 AIN1/2Motor A 方向 (10=正 01=反)
PB8~PB10GPIO In (IPU)KEY1/2/3内部上拉, 接GND触发
PB11 / PB12EXTI11 / GPIO编码器 CLK / DT下降沿中断 + 方向判断
PB13 / PB14GPIO OutTB6612 BIN1/2Motor B 方向
PC13GPIO Out板载 LED心跳指示 (低点亮)

蓝牙命令参考 (9600bps)

ON / 1启动双电机清扫 (65%)
OFF / 0双电机停止
S30 ~ S100设置双电机转速 %
A:50 / B:50单独控制左/右刷
UP / DN抬起/放下刷臂
R / REV反转 3 秒防卡死
? / STAT查询系统状态
AUTO / MANUAL切换自动/手动模式