STM32F103C8T6 + L298N + 四路红外,手把手教你调出一个能跑圈的寻迹小车(附完整代码)

张开发
2026/6/4 8:24:53 15 分钟阅读
STM32F103C8T6 + L298N + 四路红外,手把手教你调出一个能跑圈的寻迹小车(附完整代码)
STM32F103C8T6 L298N 四路红外从零构建高精度寻迹小车的实战指南当你第一次看到自己组装的智能小车沿着黑线平稳行驶时那种成就感绝对值得所有前期的调试付出。作为STM32入门后的第一个综合性项目寻迹小车完美融合了GPIO控制、PWM调速和传感器数据处理等核心技能。本文将带你从元器件选型开始逐步完成硬件组装、代码编写、参数调试全流程最终实现一个能应对复杂路线的智能巡线机器人。1. 硬件配置与电路搭建1.1 核心元器件选型建议市面上的STM32开发板型号繁多对于寻迹小车项目**STM32F103C8T6蓝桥杯推荐款**是最具性价比的选择。这款Cortex-M3内核的开发板具有64KB Flash 20KB SRAM3个通用定时器TIM2/3/437个高速GPIO口2.0-3.6V工作电压L298N电机驱动模块需要注意版本差异版本特征经典款集成款散热方式金属散热片塑料外壳供电接口分离逻辑/动力电源共用电源尺寸43mm×43mm55mm×45mm推荐场景大电流驱动紧凑型安装红外寻迹模块建议选择四路数字输出型相比模拟输出型号它省去了ADC采样环节直接通过比较器输出高低电平。典型参数如下// 红外模块工作参数 检测距离1-3cm可调 响应时间2ms 输出电平TTL兼容黑线检测为高电平 工作电流20mA1.2 电路连接详解主控与各模块的连接需要特别注意电平匹配和信号隔离电机驱动接线以右侧电机为例L298N IN1 → PA6 (PWM输入) L298N IN2 → PA5 (方向控制) L298N ENA → 跳线帽短接使能常开 电机输出A → 右电机正负极注意L298N的12V供电端务必与STM32的5V输出隔离避免电机噪声干扰MCU运行四路红外传感器连接方案#define TRACK_LEFT PB12 // 最左侧传感器 #define TRACK_MID1 PB14 // 中左传感器 #define TRACK_MID2 PB15 // 中右传感器 #define TRACK_RIGHT PA9 // 最右侧传感器推荐使用面包板搭建测试电路时按功能分区布局电源区12V输入5V稳压信号处理区红外模块上拉电阻驱动区L298N周边配置滤波电容2. 工程架构与核心代码实现2.1 Keil工程模块化设计专业级的代码组织方式应该做到高内聚低耦合建议采用如下文件结构├── Drivers/ │ ├── PWM/ // 电机PWM驱动 │ │ ├── pwm_motor.c │ │ └── pwm_motor.h │ └── IR_Sensor/ // 红外数据处理 │ ├── infrared.c │ └── infrared.h ├── Application/ │ ├── motor_ctrl.c // 运动控制 │ └── track_algo.c // 巡线算法 └── main.c // 主循环调度2.2 关键代码解析PWM初始化代码优化版增加死区保护void PWM_Init(TIM_TypeDef* TIMx, uint16_t arr, uint16_t psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; // 时基配置 TIM_TimeBaseStructure.TIM_Period arr; TIM_TimeBaseStructure.TIM_Prescaler psc; TIM_TimeBaseStructure.TIM_ClockDivision 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIMx, TIM_TimeBaseStructure); // PWM通道配置 TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse 0; // 初始占空比0% TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC2Init(TIMx, TIM_OCInitStructure); // 死区时间配置防止H桥直通 TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_BDTRInitStructure.TIM_DeadTime 0x18; // 约1us死区 TIM_BDTRInitStructure.TIM_LOCKLevel TIM_LOCKLevel_1; TIM_BDTRConfig(TIM3, TIM_BDTRInitStructure); TIM_Cmd(TIMx, ENABLE); TIM_CtrlPWMOutputs(TIMx, ENABLE); }改进型巡线算法增加动态调速void Track_Adjust(void) { uint8_t sensor_state (Track_Left()3) | (Track_Mid1()2) | (Track_Mid2()1) | Track_Right(); switch(sensor_state) { case 0b0110: // 两中传感器在黑线上 Motor_SetSpeed(SPEED_NORMAL, SPEED_NORMAL); break; case 0b0100: // 偏右 Motor_SetSpeed(SPEED_HIGH, SPEED_LOW); break; case 0b0010: // 偏左 Motor_SetSpeed(SPEED_LOW, SPEED_HIGH); break; case 0b1000: // 急左转 Motor_SetSpeed(-SPEED_TURN, SPEED_TURN*1.2); break; case 0b0001: // 急右转 Motor_SetSpeed(SPEED_TURN*1.2, -SPEED_TURN); break; default: Motor_Stop(); // 异常状态处理 } }3. 调试技巧与性能优化3.1 系统校准流程红外传感器阈值校准使用白色背景和2cm宽黑胶带搭建测试环境通过串口输出各通道ADC原始值调整模块上的电位器确保白区读数 800 黑线读数 300电机平衡校准# 伪代码测试电机转速一致性 left_speed right_speed 50 while True: if 左轮实际转速 右轮: right_speed 1 else: left_speed 1 time.sleep(1)3.2 动态参数调整策略开发过程中可以构建一个实时参数调节系统PID参数整定步骤先调P比例项直到出现小幅振荡加入D微分项抑制振荡最后加入I积分项消除静差典型参数范围参数类型起步值调节步长影响效果KP5.0±0.5响应速度KI0.1±0.02稳态精度KD1.5±0.3系统阻尼4. 进阶功能扩展4.1 多模式切换实现通过按键增加工作模式选择功能typedef enum { MODE_LINE_TRACKING 0, MODE_SPEED_TEST, MODE_CALIBRATION, MODE_MANUAL } WorkMode; void Mode_Select(void) { static WorkMode mode MODE_LINE_TRACKING; if(KEY_Pressed()) { mode (mode 1) % 4; OLED_ShowMode(mode); } }4.2 蓝牙遥控功能集成添加HC-05模块实现手机控制接线方案HC05_TX → PA10 (USART1_RX) HC05_RX → PA9 (USART1_TX) HC05_KEY → PC13 (配置引脚)通信协议设计{ cmd: speed_ctrl, left: 80, right: 75, timeout: 1000 }在项目开发过程中最让我印象深刻的是电机响应延迟问题的排查——起初以为是PWM频率问题最后发现是L298N的使能端接触不良。这个教训让我养成了在关键信号线加装消抖电路的习惯。

更多文章