如何用stm32做循迹小车
时间: 2025-07-05 19:01:02 浏览: 8
### 使用STM32实现循迹小车
#### 硬件连接说明
为了使基于STM32的红外循迹小车正常工作,硬件部分需按照特定的方式进行连接。对于采用四轮式底盘的小车而言,其主要组成部分包括MCU主控电路、车轮电机驱动电路以及用于检测路径的循迹模块等[^2]。
具体的硬件接线方式如下:
- 左侧电机输入端口分别接到PA0, PB1
- 右侧电机输入端口则应连接至PA1, PB10
- **循迹传感器**
- 将左侧循迹模块的数据输出引脚接入PB3
- 同样地,右侧循迹模块的数据输出引脚应当连向PB4
此配置确保了能够有效地接收来自两侧地面反射光强度的信息,并据此调整行驶方向[^4]。
```c
// 定义GPIO引脚分配
#define LEFT_MOTOR_IN1 GPIO_PIN_0 // PA0
#define LEFT_MOTOR_IN2 GPIO_PIN_1 // PB1
#define RIGHT_MOTOR_IN1 GPIO_PIN_1 // PA1
#define RIGHT_MOTOR_IN2 GPIO_PIN_10 // PB10
#define TRACK_LEFT GPIO_PIN_3 // PB3 (左循迹)
#define TRACK_RIGHT GPIO_PIN_4 // PB4 (右循迹)
void setup_gpio(void){
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 配置电机控制引脚为推挽输出模式
GPIO_InitStruct.Pin = LEFT_MOTOR_IN1 | LEFT_MOTOR_IN2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.Pin = RIGHT_MOTOR_IN1|RIGHT_MOTOR_IN2;
HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
// 设置循迹传感器引脚为浮空输入模式
GPIO_InitStruct.Pin=TRACK_LEFT|TRACK_RIGHT;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
}
```
#### 软件逻辑概述
当完成上述硬件搭建之后,在软件层面需要编写相应的程序来处理由循迹模块传回的数据并作出响应动作。通常情况下会利用PID算法来进行轨迹跟踪误差校正,从而提高系统的稳定性和准确性[^3]。
下面给出一段简单的C语言代码片段展示如何读取两个不同位置处黑白边界变化情况下的状态改变事件,并依据这些信息决定前进还是转弯操作:
```c
#include "stm32f4xx_hal.h"
uint8_t read_track_sensors(){
uint8_t state = 0;
if(HAL_GPIO_ReadPin(GPIOB, TRACK_LEFT)==GPIO_PIN_SET && \
HAL_GPIO_ReadPin(GPIOB, TRACK_RIGHT)==GPIO_PIN_RESET){
state |= 0b01; // 黑白交界处位于左边
}else if(HAL_GPIO_ReadPin(GPIOB, TRACK_LEFT)==GPIO_PIN_RESET &&\
HAL_GPIO_ReadPin(GPIOB, TRACK_RIGHT)==GPIO_PIN_SET){
state|=0b10;// 白黑交界处在右边
}
return state;
}
void control_motors(uint8_t direction){
switch(direction){
case 0b01://转向右转
HAL_GPIO_WritePin(GPIOA,LEFT_MOTOR_IN1,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,LEFT_MOTOR_IN2,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,RIGHT_MOTOR_IN1,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,RIGHT_MOTOR_IN2,GPIO_PIN_SET);
break;
case 0b10://向左转
HAL_GPIO_WritePin(GPIOA,LEFT_MOTOR_IN1,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,LEFT_MOTOR_IN2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,RIGHT_MOTOR_IN1,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,RIGHT_MOTOR_IN2,GPIO_PIN_RESET);
break;
default ://直行
HAL_GPIO_WritePin(GPIOA,LEFT_MOTOR_IN1,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,LEFT_MOTOR_IN2,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,RIGHT_MOTOR_IN1,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,RIGHT_MOTOR_IN2,GPIO_PIN_RESET);
break;
}
}
int main(void){
/* 初始化 */
HAL_Init();
SystemClock_Config(); // 系统时钟初始化
setup_gpio();
while(1){
uint8_t track_state=read_track_sensors();
control_motors(track_state);
// 延迟一段时间再继续循环
HAL_Delay(50);
}
return 0;
}
```
这段代码实现了基本的方向决策机制,即根据当前所处环境做出适当反应——如果发现前方有障碍物,则尝试绕过它;如果没有遇到任何阻碍,则保持直线前行。当然这只是一个非常基础的例子,在实际项目开发过程中还需要考虑更多因素比如速度调节、防抖动措施等等。
阅读全文
相关推荐

















