用STM32F103C8T6和TB6612驱动模块,从零搭建一辆能自动避障的小车(附完整代码)
用STM32F103C8T6和TB6612驱动模块从零搭建自动避障小车第一次接触嵌入式开发时最令人兴奋的莫过于让冰冷的硬件活起来。本文将带你用最常见的STM32蓝色小板F103C8T6和TB6612电机驱动模块从焊接电路到编写代码完整实现一个能自主避开障碍物的智能小车。不同于市面上复杂的多功能方案我们聚焦最核心的避障功能确保每个步骤都能被初学者理解并复现。1. 硬件准备与电路连接1.1 核心元件清单确保备齐以下基础组件总成本控制在200元内主控STM32F103C8T6最小系统板带USB转串口电机驱动TB6612FNG模块比L298N更高效测距传感器HC-SR04超声波模块动力系统TT马达车轮套件配3.7V锂电池结构件亚克力小车底盘、万向轮连接件杜邦线建议用20cm公对公公对母组合提示TB6612的VM引脚需接5V电源但逻辑控制端(VCC)接3.3V即可避免与STM32电平不匹配。1.2 关键电路连接图示用表格梳理必须的接线关系STM32引脚连接目标功能说明PA6TB6612 PWMA左侧电机PWM信号PA7TB6612 PWMB右侧电机PWM信号PB0TB6612 AIN1左侧电机方向控制1PB1TB6612 AIN2左侧电机方向控制2PB10TB6612 BIN1右侧电机方向控制1PB11TB6612 BIN2右侧电机方向控制2PC8HC-SR04 Trig超声波触发信号PC9HC-SR04 Echo超声波回波信号// 示例GPIO初始化代码片段 void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); // 配置PB0/PB1为推挽输出电机方向控制 GPIO_InitStruct.GPIO_Pin GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStruct.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStruct); }2. 电机驱动与PWM配置2.1 TB6612双路控制原理TB6612相比传统L298N有三个显著优势效率提升MOSFET驱动架构使功耗降低70%体积缩小模块面积仅硬币大小保护完善内置过热关断和低压检测电机转向真值表AIN1AIN2电机动作00刹车01正转10反转11停止2.2 STM32的PWM生成实战使用TIM3的通道1/2生成两路PWMvoid PWM_Init(uint16_t arr, uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 时基配置72MHz/(7191)/(9991) 100Hz TIM_TimeBaseStruct.TIM_Prescaler psc; TIM_TimeBaseStruct.TIM_Period arr; TIM_TimeBaseInit(TIM3, TIM_TimeBaseStruct); // PWM模式配置 TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse 0; // 初始占空比0% TIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM3, TIM_OCInitStruct); // 通道1(PA6) TIM_OC2Init(TIM3, TIM_OCInitStruct); // 通道2(PA7) TIM_Cmd(TIM3, ENABLE); TIM_CtrlPWMOutputs(TIM3, ENABLE); }注意实际调试时先用TIM_SetCompare1(TIM3, 500)设置50%占空比观察电机是否匀速转动。3. 超声波测距模块驱动3.1 HC-SR04时序解析完整测距流程分为三步触发给Trig引脚10μs以上高电平回波检测Echo引脚高电平持续时间即声波往返时间距离计算距离(cm) 高电平时间(μs)/58float Get_Distance(void) { GPIO_SetBits(GPIOC, GPIO_Pin_8); delay_us(15); GPIO_ResetBits(GPIOC, GPIO_Pin_8); while(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_9)); // 等待Echo变高 uint32_t start micros(); while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_9)); // 等待Echo变低 uint32_t duration micros() - start; return (float)duration / 58.0f; }3.2 滤波算法优化原始数据易受干扰建议采用移动平均滤波#define SAMPLE_SIZE 5 float distance_buffer[SAMPLE_SIZE]; float Filtered_Distance(void) { // 滑动窗口更新数据 for(int iSAMPLE_SIZE-1; i0; i--) { distance_buffer[i] distance_buffer[i-1]; } distance_buffer[0] Get_Distance(); // 计算平均值 float sum 0; for(int i0; iSAMPLE_SIZE; i) { sum distance_buffer[i]; } return sum / SAMPLE_SIZE; }4. 避障算法设计与实现4.1 三阶段避障策略根据距离采取不同动作距离范围(cm)执行动作PWM占空比30全速前进80%15-30减速前进50%15后退→右转90°→继续检测30%4.2 状态机实现代码typedef enum { STATE_FORWARD, STATE_BACKWARD, STATE_TURN_RIGHT, STATE_CHECK } ObstacleState; void Avoidance_Logic(void) { static ObstacleState state STATE_FORWARD; float dist Filtered_Distance(); switch(state) { case STATE_FORWARD: if(dist 15) { state STATE_BACKWARD; Set_Motor(-30, -30); // 后退 delay_ms(500); } else if(dist 30) { Set_Motor(50, 50); // 慢速前进 } else { Set_Motor(80, 80); // 全速前进 } break; case STATE_BACKWARD: state STATE_TURN_RIGHT; Set_Motor(30, -30); // 原地右转 delay_ms(300); // 调整延时可改变转向角度 break; case STATE_TURN_RIGHT: state STATE_CHECK; Set_Motor(0, 0); // 停止 delay_ms(200); break; case STATE_CHECK: if(Filtered_Distance() 25) { state STATE_FORWARD; } else { state STATE_TURN_RIGHT; } break; } }4.3 性能优化技巧中断优化将超声波Echo检测改为外部中断定时器捕获能耗控制无障碍时进入低速模式检测到障碍再全速运行异常处理增加超时判断防止Echo信号卡死// 改进的Echo检测使用输入捕获 void TIM4_IRQHandler(void) { if(TIM_GetITStatus(TIM4, TIM_IT_CC1) ! RESET) { if(echo_state 0) { // 上升沿 capture_start TIM_GetCapture1(TIM4); echo_state 1; } else { // 下降沿 capture_end TIM_GetCapture1(TIM4); echo_state 0; new_data_ready 1; } TIM_ClearITPendingBit(TIM4, TIM_IT_CC1); } }5. 系统整合与调试5.1 主循环设计要点int main(void) { SystemInit(); GPIO_Config(); PWM_Init(999, 719); // 100Hz PWM Ultrasonic_Init(); while(1) { Avoidance_Logic(); delay_ms(100); // 控制检测频率 } }5.2 常见问题排查电机不转检查TB6612的VM电压是否≥5V测量STM32输出引脚是否有信号确认STBY引脚已接高电平距离测量不准确保超声波模块与障碍物表面平行避免测量柔软材质如窗帘检查电源纹波建议并联100μF电容小车跑偏对两个电机分别校准PWM占空比检查车轮是否安装牢固在光滑地面测试减少摩擦力差异