从零到一:基于STM32F103的自动循迹小车设计与实现

张开发
2026/4/3 17:18:36 15 分钟阅读
从零到一:基于STM32F103的自动循迹小车设计与实现
从零到一基于STM32F103的自动循迹小车设计与实现在嵌入式系统开发领域自动循迹小车是一个经典而富有挑战性的项目。它不仅融合了硬件设计、传感器应用和软件算法等多方面知识更是检验开发者系统思维和问题解决能力的绝佳实践。对于电子工程、自动化或嵌入式系统初学者而言完成一个完整的自动循迹小车项目意味着从理论到实践的跨越从零散知识点到系统工程的蜕变。本文将带领读者深入探索基于STM32F103单片机的自动循迹小车设计与实现全过程。不同于简单的教程式指导我们将从工程实践角度出发剖析每个环节的技术选型考量、常见陷阱与优化技巧。无论你是希望完成课程设计的学生还是渴望提升实战能力的工程师都能从中获得可直接落地的项目经验。1. 项目规划与硬件选型1.1 系统架构设计一个完整的自动循迹小车系统通常包含以下几个核心模块控制核心STM32F103单片机作为主控制器感知系统多路红外或灰度传感器组成的循迹模块执行机构直流电机驱动模块负责运动舵机控制转向能源系统锂电池组配合电压转换电路调试接口串口、SWD调试接口等辅助开发工具在架构设计阶段需要特别关注各模块间的信号流与电源分配。下图展示了一个典型的系统框图--------------- | 7.2V锂电 | -------┬------- | -------▼------- ----------------- | DC-DC降压模块 | | 电机驱动模块 | | (5V/3.3V输出) | | (BTS7960) | -------┬------- --------┬-------- | | -------▼------- --------▼-------- | STM32F103核心 | | 直流电机 | | 板载系统 | | (带编码器) | -------┬------- ----------------- | -------▼------- | 七路灰度传感器 | | (循迹模块) | -------┬------- | -------▼------- | 舵机 | | (方向控制) | ---------------1.2 关键元器件选型指南单片机选型考量STM32F103C8T6最小系统板性价比高资源丰富至少需要3个定时器2个用于PWM生成1个用于系统时钟ADC通道数量需满足传感器信号采集需求建议选择带SWD调试接口的开发板电机驱动方案对比驱动芯片最大电流工作电压特点适用场景L298N2A5-35V价格低发热大轻负载预算有限TB66121.2A2.5-13.5V效率高体积小小型智能车BTS796043A5.5-27V大电流内置保护中大型智能车提示对于初学者项目TB6612是性价比较高的选择既避免了L298N的高发热问题又比BTS7960更经济。传感器选型建议TCRT5000红外对管成本低但受环境光影响大灰度传感器精度高需配合特定颜色赛道使用七路循迹模块覆盖范围广可检测复杂路径2. 硬件电路设计与实现2.1 电源系统设计稳定的电源是系统可靠运行的基础。典型的电源架构需要提供三种电压等级7.2V直接供给电机驱动模块5V供给舵机和部分传感器3.3V供给STM32单片机推荐使用MP1584EN降压模块作为主要DC-DC转换器其典型电路连接如下// 电源连接示意图 电池正极 → MP1584EN Vin ├─ 输出5V → 舵机 └─ AMS1117 → 3.3V → STM32 电机驱动 ← 直接连接电池关键参数计算总电流需求估算单片机~50mA传感器阵列~100mA舵机峰值500mA电机每台1-2A视型号而定锂电池容量选择所需容量(mAh) 总电流(A) × 预计运行时间(h) × 安全系数(1.2-1.5)例如系统平均电流1A希望运行1小时则至少需要1200mAh电池2.2 传感器阵列布局优化七路灰度传感器的安装位置直接影响循迹效果。经过多次实测验证推荐以下布局参数传感器间距15-20mm适应常见2cm宽赛道安装高度8-12mm距地面排列方式中间一个左右各三个对称分布调试时需要使用电位器调整每个传感器的灵敏度确保在白纸上输出高电平3V在黑线上输出低电平0.5V各传感器阈值一致典型接线方式传感器1 OUT → PA0 传感器2 OUT → PA1 ... 传感器7 OUT → PA6 VCC → 5V GND → 共地3. 软件系统设计与算法实现3.1 主程序架构设计采用前后台系统架构主循环负责调度各功能模块中断处理时间敏感任务int main(void) { hardware_init(); // 硬件初始化 motor_init(); // 电机初始化 sensor_calibrate(); // 传感器校准 while(1) { track_line read_sensors(); // 读取传感器状态 error calculate_error(track_line); // 计算偏离误差 pwm pid_controller(error); // PID计算输出 set_motor_speed(pwm); // 调整电机速度 delay_ms(10); // 控制周期 } }3.2 改进型PID控制算法实现传统PID算法在小车快速运动时容易出现震荡。我们采用以下改进措施增量式PID避免积分饱和typedef struct { float Kp, Ki, Kd; float last_error, prev_error; float output; } PID_Controller; float pid_update(PID_Controller* pid, float error) { float delta pid-Kp * (error - pid-last_error) pid-Ki * error pid-Kd * (error - 2*pid-last_error pid-prev_error); pid-output delta; pid-prev_error pid-last_error; pid-last_error error; return pid-output; }动态参数调整根据误差大小自动调节PID参数void adjust_pid_params(PID_Controller* pid, float abs_error) { if(abs_error 3) { // 大偏差时增强P减弱I pid-Kp 0.8; pid-Ki 0.01; } else { // 小偏差时减弱P增强I pid-Kp 0.3; pid-Ki 0.05; } }抗积分饱和限制输出范围并暂停积分#define MAX_OUTPUT 1000 #define MIN_OUTPUT -1000 if(pid-output MAX_OUTPUT) { pid-output MAX_OUTPUT; // 暂停积分项累积 } else if(pid-output MIN_OUTPUT) { pid-output MIN_OUTPUT; // 暂停积分项累积 }3.3 多传感器数据融合算法七路传感器数据可通过加权算法转换为位置偏差// 传感器位置定义单位mm const float sensor_pos[7] {-30, -20, -10, 0, 10, 20, 30}; float calculate_error(uint8_t sensor_status) { float weighted_sum 0; uint8_t active_count 0; for(int i0; i7; i) { if(sensor_status (1i)) { weighted_sum sensor_pos[i]; active_count; } } if(active_count 0) return last_valid_error; // 保持上次有效值 else return weighted_sum / active_count; }4. 系统调试与性能优化4.1 分阶段调试策略硬件调试步骤电源测试测量各电压输出是否正常检查纹波电压应50mV传感器测试# 通过串口输出传感器状态 printf(Sensor: %d%d%d%d%d%d%d\r\n, s1, s2, s3, s4, s5, s6, s7);电机测试逐步增加PWM占空比观察电机响应测试正反转功能是否正常软件调试技巧使用STM32的硬件调试器设置断点实时监测变量值变化利用串口绘图工具可视化PID调节过程4.2 常见问题解决方案问题1小车在直线上左右摆动可能原因P参数过大导致超调传感器响应延迟解决方案逐步减小Kp值每次调整10%增加传感器采样滤波#define FILTER_DEPTH 3 uint8_t filter_buffer[FILTER_DEPTH]; uint8_t filtered_read(uint8_t pin) { // 移位存储历史数据 for(int iFILTER_DEPTH-1; i0; i--) { filter_buffer[i] filter_buffer[i-1]; } filter_buffer[0] HAL_GPIO_ReadPin(pin); // 多数表决 uint8_t sum 0; for(int i0; iFILTER_DEPTH; i) { sum filter_buffer[i]; } return (sum FILTER_DEPTH/2) ? 1 : 0; }问题2急弯处冲出赛道优化方案增加弯道检测逻辑int is_sharp_turn(uint8_t sensor_status) { // 检测外侧传感器同时触发 return (sensor_status 0x41) 0x41; } void handle_sharp_turn(void) { if(is_sharp_turn(current_sensors)) { reduce_speed(50); // 减速50% increase_kp(30); // 临时增加P参数 } }改进机械结构降低重心增加前轮转向角度使用差速转向代替舵机转向4.3 性能优化记录通过系统优化我们实现了以下性能提升优化项目优化前优化后提升幅度直线跟踪精度(mm)±15±566%弯道通过速度(cm/s)203575%电池续航时间(min)456851%关键优化措施采用动态PID参数调整实现传感器数据滑动平均滤波优化电源管理策略改进机械结构降低摩擦在最终测试中小车能够在复杂赛道上以0.35m/s的速度稳定运行连续工作时间超过1小时。这个项目最让我印象深刻的是PID参数的整定过程——通过系统化的调试方法我们最终找到了适合不同赛道特征的参数组合这比单纯依靠试错法效率高了至少三倍。

更多文章