STM32F103C8T6 四驱智能小车寻迹软件源代码
项目结构
SmartCar/
├── Core/
│ ├── Src/
│ │ ├── main.c
│ │ ├── stm32f1xx_hal_msp.c
│ │ └── stm32f1xx_it.c
│ ├── Inc/
│ │ ├── main.h
│ │ └── config.h
├── Drivers/
│ ├── STM32F1xx_HAL_Driver/
│ └── CMSIS/
├── BSP/
│ ├── Src/
│ │ ├── motor.c
│ │ ├── sensor.c
│ │ ├── pwm.c
│ │ ├── uart.c
│ │ ├── pid.c
│ │ └── control.c
│ ├── Inc/
│ ├── motor.h
│ ├── sensor.h
│ ├── pwm.h
│ ├── uart.h
│ ├── pid.h
│ └── control.h
└── README.md
源代码实现
1. 配置文件 (config.h)
/**
* 智能小车配置头文件
* MCU: STM32F103C8T6
* 晶振: 8MHz
* 系统时钟: 72MHz
*/
#ifndef __CONFIG_H
#define __CONFIG_H
// 系统时钟配置
#define SYS_CLK_FREQ 72000000
#define HSE_VALUE 8000000
// 调试配置
#define DEBUG_ENABLE 1
#define DEBUG_UART USART1
#define DEBUG_BAUDRATE 115200
// 传感器配置
#define SENSOR_COUNT 5 // 5路循迹传感器
#define SENSOR_THRESHOLD 500 // 黑白区分阈值(0-4095)
#define SENSOR_INTERVAL 10 // 传感器采样间隔(ms)
// 电机配置
#define MOTOR_COUNT 4 // 4个电机
#define MOTOR_BASE_SPEED 1000 // 基础速度(0-2000)
#define MOTOR_MAX_SPEED 2000 // 最大速度
#define MOTOR_MIN_SPEED 500 // 最小速度
// PID参数配置
#define PID_KP 2.0f // 比例系数
#define PID_KI 0.1f // 积分系数
#define PID_KD 1.5f // 微分系数
#define PID_MAX_OUTPUT 1000 // PID最大输出
// 循迹模式配置
#define TRACE_MODE_NORMAL 0 // 普通循迹模式
#define TRACE_MODE_PID 1 // PID循迹模式
#define TRACE_MODE_ADVANCED 2 // 高级循迹模式
// 速度配置
#define SPEED_SLOW 800 // 慢速
#define SPEED_NORMAL 1200 // 正常速度
#define SPEED_FAST 1600 // 快速
#define SPEED_TURN 1000 // 转弯速度
// 引脚定义
// 电机引脚
#define MOTOR1_A_PORT GPIOB
#define MOTOR1_A_PIN GPIO_PIN_6
#define MOTOR1_B_PORT GPIOB
#define MOTOR1_B_PIN GPIO_PIN_7
#define MOTOR1_PWM_TIM TIM4
#define MOTOR1_PWM_CH TIM_CHANNEL_1
#define MOTOR2_A_PORT GPIOB
#define MOTOR2_A_PIN GPIO_PIN_8
#define MOTOR2_B_PORT GPIOB
#define MOTOR2_B_PIN GPIO_PIN_9
#define MOTOR2_PWM_TIM TIM4
#define MOTOR2_PWM_CH TIM_CHANNEL_2
#define MOTOR3_A_PORT GPIOB
#define MOTOR3_A_PIN GPIO_PIN_10
#define MOTOR3_B_PORT GPIOB
#define MOTOR3_B_PIN GPIO_PIN_11
#define MOTOR3_PWM_TIM TIM4
#define MOTOR3_PWM_CH TIM_CHANNEL_3
#define MOTOR4_A_PORT GPIOB
#define MOTOR4_A_PIN GPIO_PIN_12
#define MOTOR4_B_PORT GPIOB
#define MOTOR4_B_PIN GPIO_PIN_13
#define MOTOR4_PWM_TIM TIM4
#define MOTOR4_PWM_CH TIM_CHANNEL_4
// 传感器引脚(ADC)
#define SENSOR1_PIN GPIO_PIN_0
#define SENSOR1_CH ADC_CHANNEL_0
#define SENSOR2_PIN GPIO_PIN_1
#define SENSOR2_CH ADC_CHANNEL_1
#define SENSOR3_PIN GPIO_PIN_2
#define SENSOR3_CH ADC_CHANNEL_2
#define SENSOR4_PIN GPIO_PIN_3
#define SENSOR4_CH ADC_CHANNEL_3
#define SENSOR5_PIN GPIO_PIN_4
#define SENSOR5_CH ADC_CHANNEL_4
// 按键引脚
#define KEY_START_PIN GPIO_PIN_5
#define KEY_START_PORT GPIOA
#define KEY_MODE_PIN GPIO_PIN_6
#define KEY_MODE_PORT GPIOA
// LED指示灯
#define LED_RUN_PIN GPIO_PIN_13
#define LED_RUN_PORT GPIOC
#define LED_ERR_PIN GPIO_PIN_14
#define LED_ERR_PORT GPIOC
#define LED_TRACE_PIN GPIO_PIN_15
#define LED_TRACE_PORT GPIOC
// 蜂鸣器
#define BUZZER_PIN GPIO_PIN_8
#define BUZZER_PORT GPIOA
// 超声波模块(可选)
#define US_TRIG_PIN GPIO_PIN_9
#define US_TRIG_PORT GPIOA
#define US_ECHO_PIN GPIO_PIN_10
#define US_ECHO_PORT GPIOA
// 枚举定义
typedef enum {
CAR_STATE_IDLE = 0, // 空闲状态
CAR_STATE_READY, // 准备就绪
CAR_STATE_RUNNING, // 运行中
CAR_STATE_PAUSED, // 暂停
CAR_STATE_ERROR // 错误
} CarState;
typedef enum {
DIR_FORWARD = 0, // 前进
DIR_BACKWARD, // 后退
DIR_LEFT, // 左转
DIR_RIGHT, // 右转
DIR_STOP // 停止
} Direction;
typedef enum {
TRACE_LOST = 0, // 丢失轨迹
TRACE_ON_LINE, // 在轨迹上
TRACE_CROSSROAD, // 十字路口
TRACE_TURN_LEFT, // 左转弯
TRACE_TURN_RIGHT, // 右转弯
TRACE_TURN_AROUND // 掉头
} TraceState;
// 结构体定义
typedef struct {
uint16_t speed_left_front; // 左前轮速度
uint16_t speed_right_front; // 右前轮速度
uint16_t speed_left_rear; // 左后轮速度
uint16_t speed_right_rear; // 右后轮速度
Direction direction; // 行驶方向
uint8_t enable; // 使能标志
} MotorControl;
typedef struct {
uint16_t sensor_values[5]; // 传感器原始值
uint8_t sensor_states[5]; // 传感器状态(0:白线, 1:黑线)
int8_t line_position; // 轨迹位置(-2,-1,0,1,2)
TraceState trace_state; // 循迹状态
uint32_t lost_count; // 丢失轨迹计数
} SensorData;
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float error; // 当前误差
float integral; // 积分项
float derivative; // 微分项
float last_error; // 上次误差
float output; // 输出值
float max_output; // 最大输出
} PIDController;
typedef struct {
CarState state; // 小车状态
uint8_t trace_mode; // 循迹模式
uint16_t base_speed; // 基础速度
uint16_t max_speed; // 最大速度
uint32_t run_time; // 运行时间
uint32_t distance; // 行驶距离
uint8_t obstacle_detected; // 检测到障碍物
} CarInfo;
// 全局变量声明
extern CarInfo g_car_info;
extern SensorData g_sensor_data;
extern MotorControl g_motor_control;
extern PIDController g_pid_controller;
#endif /* __CONFIG_H */
2. 主程序 (main.c)
/**
* 主程序文件
* 四驱智能小车寻迹系统
*/
#include "main.h"
#include "config.h"
#include "motor.h"
#include "sensor.h"
#include "control.h"
#include "uart.h"
#include "pid.h"
#include <stdio.h>
#include <string.h>
// 全局变量定义
CarInfo g_car_info = {0};
SensorData g_sensor_data = {0};
MotorControl g_motor_control = {0};
PIDController g_pid_controller = {0};
// 系统滴答定时器
volatile uint32_t g_sys_tick = 0;
// 函数声明
static void SystemClock_Config(void);
static void GPIO_Init(void);
static void TIM_Init(void);
static void ADC_Init(void);
static void NVIC_Init(void);
static void System_Init(void);
static void Car_Init(void);
static void Error_Handler(void);
static void SysTick_Handler(void);
static void Car_State_Machine(void);
static void Trace_Task(void);
static void Control_Task(void);
static void Debug_Task(void);
static void Beep(uint8_t count, uint16_t interval);
static void LED_Blink(uint8_t led, uint8_t count, uint16_t interval);
int main(void) {
// 复位所有外设,初始化Flash接口和系统滴答定时器
HAL_Init();
// 配置系统时钟
SystemClock_Config();
// 初始化外设
System_Init();
// 初始化小车
Car_Init();
// 启动提示音
Beep(3, 100);
LED_Blink(LED_RUN_PIN, 3, 200);
// 主循环
while (1) {
// 状态机处理
Car_State_Machine();
// 根据状态执行不同任务
switch (g_car_info.state) {
case CAR_STATE_READY:
// 等待启动信号
if (HAL_GPIO_ReadPin(KEY_START_PORT, KEY_START_PIN) == GPIO_PIN_RESET) {
g_car_info.state = CAR_STATE_RUNNING;
Beep(1, 200);
HAL_GPIO_WritePin(LED_TRACE_PORT, LED_TRACE_PIN, GPIO_PIN_SET);
}
break;
case CAR_STATE_RUNNING:
// 执行循迹任务
Trace_Task();
// 执行控制任务
Control_Task();
// 调试信息输出
#if DEBUG_ENABLE
Debug_Task();
#endif
break;
case CAR_STATE_PAUSED:
// 停止电机
Motor_Stop();
break;
case CAR_STATE_ERROR:
// 错误处理
Motor_Stop();
HAL_GPIO_WritePin(LED_ERR_PORT, LED_ERR_PIN, GPIO_PIN_SET);
break;
default:
break;
}
// 系统延时
HAL_Delay(1);
}
}
/**
* 系统时钟配置
* 配置为72MHz
*/
static void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化HSE
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
// 初始化CPU, AHB, APB总线时钟
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
}
/**
* GPIO初始化
*/
static void GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIO时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
// 电机控制引脚配置
// 电机方向控制引脚
GPIO_InitStruct.Pin = MOTOR1_A_PIN | MOTOR1_B_PIN | MOTOR2_A_PIN | MOTOR2_B_PIN |
MOTOR3_A_PIN | MOTOR3_B_PIN | MOTOR4_A_PIN | MOTOR4_B_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 传感器引脚配置(ADC输入)
GPIO_InitStruct.Pin = SENSOR1_PIN | SENSOR2_PIN | SENSOR3_PIN |
SENSOR4_PIN | SENSOR5_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 按键引脚配置
GPIO_InitStruct.Pin = KEY_START_PIN | KEY_MODE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// LED引脚配置
GPIO_InitStruct.Pin = LED_RUN_PIN | LED_ERR_PIN | LED_TRACE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// 蜂鸣器引脚
GPIO_InitStruct.Pin = BUZZER_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 初始状态
HAL_GPIO_WritePin(LED_RUN_PORT, LED_RUN_PIN, GPIO_PIN_SET); // 运行灯常亮
HAL_GPIO_WritePin(LED_ERR_PORT, LED_ERR_PIN, GPIO_PIN_RESET); // 错误灯灭
HAL_GPIO_WritePin(LED_TRACE_PORT, LED_TRACE_PIN, GPIO_PIN_RESET); // 循迹灯灭
HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_RESET); // 蜂鸣器关
}
/**
* 定时器初始化
*/
static void TIM_Init(void) {
TIM_HandleTypeDef htim4 = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
// 使能TIM4时钟
__HAL_RCC_TIM4_CLK_ENABLE();
// 配置TIM4产生PWM
htim4.Instance = TIM4;
htim4.Init.Prescaler = 72 - 1; // 72MHz/72 = 1MHz
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 2000 - 1; // PWM频率 = 1MHz/2000 = 500Hz
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK) {
Error_Handler();
}
// 配置PWM通道
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0; // 初始占空比为0
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
// 配置4个PWM通道
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK ||
HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK ||
HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK ||
HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) {
Error_Handler();
}
// 启动PWM
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
}
/**
* ADC初始化
*/
static void ADC_Init(void) {
ADC_HandleTypeDef hadc1 = {0};
ADC_ChannelConfTypeDef sConfig = {0};
// 使能ADC1时钟
__HAL_RCC_ADC1_CLK_ENABLE();
// 配置ADC
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 5;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler();
}
// 配置ADC通道
// 传感器1
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 传感器2
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 传感器3
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_3;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 传感器4
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_4;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 传感器5
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 启动ADC
HAL_ADC_Start(&hadc1);
}
/**
* NVIC初始化
*/
static void NVIC_Init(void) {
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/**
* 系统初始化
*/
static void System_Init(void) {
// 初始化GPIO
GPIO_Init();
// 初始化定时器
TIM_Init();
// 初始化ADC
ADC_Init();
// 初始化串口(调试用)
#if DEBUG_ENABLE
UART_Init(DEBUG_BAUDRATE);
printf("System Initialized\r\n");
#endif
// 初始化NVIC
NVIC_Init();
}
/**
* 小车初始化
*/
static void Car_Init(void) {
// 初始化小车状态
g_car_info.state = CAR_STATE_READY;
g_car_info.trace_mode = TRACE_MODE_PID;
g_car_info.base_speed = MOTOR_BASE_SPEED;
g_car_info.max_speed = MOTOR_MAX_SPEED;
g_car_info.run_time = 0;
g_car_info.distance = 0;
g_car_info.obstacle_detected = 0;
// 初始化传感器数据
memset(&g_sensor_data, 0, sizeof(SensorData));
g_sensor_data.line_position = 0;
g_sensor_data.trace_state = TRACE_LOST;
g_sensor_data.lost_count = 0;
// 初始化电机控制
memset(&g_motor_control, 0, sizeof(MotorControl));
g_motor_control.enable = 1;
g_motor_control.direction = DIR_STOP;
// 初始化PID控制器
PID_Init(&g_pid_controller, PID_KP, PID_KI, PID_KD, PID_MAX_OUTPUT);
// 初始化电机
Motor_Init();
#if DEBUG_ENABLE
printf("Car Initialized\r\n");
printf("Mode: %s\r\n", g_car_info.trace_mode == TRACE_MODE_PID ? "PID" : "Normal");
printf("Base Speed: %d\r\n", g_car_info.base_speed);
#endif
}
/**
* 错误处理函数
*/
static void Error_Handler(void) {
// 错误处理
HAL_GPIO_WritePin(LED_ERR_PORT, LED_ERR_PIN, GPIO_PIN_SET);
while (1) {
// 错误闪烁
HAL_GPIO_TogglePin(LED_ERR_PORT, LED_ERR_PIN);
HAL_Delay(200);
}
}
/**
* 系统滴答定时器中断
*/
void SysTick_Handler(void) {
HAL_IncTick();
g_sys_tick++;
}
/**
* 小车状态机
*/
static void Car_State_Machine(void) {
static uint32_t last_led_toggle = 0;
static uint8_t mode_button_pressed = 0;
// LED运行指示
if (HAL_GetTick() - last_led_toggle > 500) {
HAL_GPIO_TogglePin(LED_RUN_PORT, LED_RUN_PIN);
last_led_toggle = HAL_GetTick();
}
// 模式切换按键检测
if (HAL_GPIO_ReadPin(KEY_MODE_PORT, KEY_MODE_PIN) == GPIO_PIN_RESET) {
if (!mode_button_pressed) {
mode_button_pressed = 1;
g_car_info.trace_mode = (g_car_info.trace_mode + 1) % 3;
#if DEBUG_ENABLE
printf("Mode Changed: ");
switch (g_car_info.trace_mode) {
case TRACE_MODE_NORMAL:
printf("Normal\r\n");
break;
case TRACE_MODE_PID:
printf("PID\r\n");
break;
case TRACE_MODE_ADVANCED:
printf("Advanced\r\n");
break;
}
#endif
Beep(1, 100);
}
} else {
mode_button_pressed = 0;
}
}
/**
* 循迹任务
*/
static void Trace_Task(void) {
static uint32_t last_sensor_time = 0;
// 定期采样传感器
if (HAL_GetTick() - last_sensor_time > SENSOR_INTERVAL) {
Sensor_ReadAll();
Sensor_Process();
last_sensor_time = HAL_GetTick();
}
}
/**
* 控制任务
*/
static void Control_Task(void) {
int16_t pid_output = 0;
int16_t left_speed = 0, right_speed = 0;
// 根据循迹模式选择控制算法
switch (g_car_info.trace_mode) {
case TRACE_MODE_NORMAL:
// 普通循迹模式
Control_Normal();
break;
case TRACE_MODE_PID:
// PID循迹模式
pid_output = Control_PID();
// 计算左右轮速度
left_speed = g_car_info.base_speed + pid_output;
right_speed = g_car_info.base_speed - pid_output;
// 限制速度范围
left_speed = (left_speed < MOTOR_MIN_SPEED) ? MOTOR_MIN_SPEED :
(left_speed > MOTOR_MAX_SPEED) ? MOTOR_MAX_SPEED : left_speed;
right_speed = (right_speed < MOTOR_MIN_SPEED) ? MOTOR_MIN_SPEED :
(right_speed > MOTOR_MAX_SPEED) ? MOTOR_MAX_SPEED : right_speed;
// 设置电机速度
Motor_SetSpeed(MOTOR_LEFT_FRONT, left_speed);
Motor_SetSpeed(MOTOR_LEFT_REAR, left_speed);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, right_speed);
Motor_SetSpeed(MOTOR_RIGHT_REAR, right_speed);
// 前进
Motor_Forward();
break;
case TRACE_MODE_ADVANCED:
// 高级循迹模式(包含避障)
Control_Advanced();
break;
}
// 更新运行时间
g_car_info.run_time = HAL_GetTick() / 1000; // 转换为秒
}
/**
* 调试任务
*/
static void Debug_Task(void) {
static uint32_t last_debug_time = 0;
if (HAL_GetTick() - last_debug_time > 1000) { // 每秒输出一次
printf("=== Debug Info ===\r\n");
printf("State: %d, Mode: %d\r\n", g_car_info.state, g_car_info.trace_mode);
printf("Run Time: %lus, Distance: %lum\r\n",
g_car_info.run_time, g_car_info.distance);
printf("Line Pos: %d, Trace State: %d\r\n",
g_sensor_data.line_position, g_sensor_data.trace_state);
printf("Motor: LF=%d, RF=%d, LR=%d, RR=%d\r\n",
g_motor_control.speed_left_front,
g_motor_control.speed_right_front,
g_motor_control.speed_left_rear,
g_motor_control.speed_right_rear);
printf("PID Output: %.2f\r\n", g_pid_controller.output);
printf("==================\r\n");
last_debug_time = HAL_GetTick();
}
}
/**
* 蜂鸣器控制
*/
static void Beep(uint8_t count, uint16_t interval) {
for (uint8_t i = 0; i < count; i++) {
HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_SET);
HAL_Delay(interval);
HAL_GPIO_WritePin(BUZZER_PORT, BUZZER_PIN, GPIO_PIN_RESET);
if (i < count - 1) {
HAL_Delay(interval);
}
}
}
/**
* LED闪烁控制
*/
static void LED_Blink(uint8_t led, uint8_t count, uint16_t interval) {
GPIO_TypeDef* port = NULL;
uint16_t pin = 0;
// 确定LED端口和引脚
if (led == LED_RUN_PIN) {
port = LED_RUN_PORT;
pin = LED_RUN_PIN;
} else if (led == LED_ERR_PIN) {
port = LED_ERR_PORT;
pin = LED_ERR_PIN;
} else if (led == LED_TRACE_PIN) {
port = LED_TRACE_PORT;
pin = LED_TRACE_PIN;
} else {
return;
}
for (uint8_t i = 0; i < count; i++) {
HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET);
HAL_Delay(interval);
HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET);
if (i < count - 1) {
HAL_Delay(interval);
}
}
}
3. 电机驱动 (motor.c)
/**
* 电机驱动模块
*/
#include "motor.h"
#include "config.h"
// 电机控制结构体
typedef struct {
GPIO_TypeDef* port_a;
uint16_t pin_a;
GPIO_TypeDef* port_b;
uint16_t pin_b;
TIM_HandleTypeDef* tim;
uint32_t channel;
uint16_t speed;
uint8_t direction;
} Motor;
static Motor motors[4];
/**
* 电机初始化
*/
void Motor_Init(void) {
// 初始化左前电机(M1)
motors[MOTOR_LEFT_FRONT].port_a = MOTOR1_A_PORT;
motors[MOTOR_LEFT_FRONT].pin_a = MOTOR1_A_PIN;
motors[MOTOR_LEFT_FRONT].port_b = MOTOR1_B_PORT;
motors[MOTOR_LEFT_FRONT].pin_b = MOTOR1_B_PIN;
motors[MOTOR_LEFT_FRONT].tim = &MOTOR1_PWM_TIM;
motors[MOTOR_LEFT_FRONT].channel = MOTOR1_PWM_CH;
// 初始化右前电机(M2)
motors[MOTOR_RIGHT_FRONT].port_a = MOTOR2_A_PORT;
motors[MOTOR_RIGHT_FRONT].pin_a = MOTOR2_A_PIN;
motors[MOTOR_RIGHT_FRONT].port_b = MOTOR2_B_PORT;
motors[MOTOR_RIGHT_FRONT].pin_b = MOTOR2_B_PIN;
motors[MOTOR_RIGHT_FRONT].tim = &MOTOR2_PWM_TIM;
motors[MOTOR_RIGHT_FRONT].channel = MOTOR2_PWM_CH;
// 初始化左后电机(M3)
motors[MOTOR_LEFT_REAR].port_a = MOTOR3_A_PORT;
motors[MOTOR_LEFT_REAR].pin_a = MOTOR3_A_PIN;
motors[MOTOR_LEFT_REAR].port_b = MOTOR3_B_PORT;
motors[MOTOR_LEFT_REAR].pin_b = MOTOR3_B_PIN;
motors[MOTOR_LEFT_REAR].tim = &MOTOR3_PWM_TIM;
motors[MOTOR_LEFT_REAR].channel = MOTOR3_PWM_CH;
// 初始化右后电机(M4)
motors[MOTOR_RIGHT_REAR].port_a = MOTOR4_A_PORT;
motors[MOTOR_RIGHT_REAR].pin_a = MOTOR4_A_PIN;
motors[MOTOR_RIGHT_REAR].port_b = MOTOR4_B_PORT;
motors[MOTOR_RIGHT_REAR].pin_b = MOTOR4_B_PIN;
motors[MOTOR_RIGHT_REAR].tim = &MOTOR4_PWM_TIM;
motors[MOTOR_RIGHT_REAR].channel = MOTOR4_PWM_CH;
// 初始化所有电机
for (int i = 0; i < 4; i++) {
motors[i].speed = 0;
motors[i].direction = 0;
// 设置方向引脚为停止状态
HAL_GPIO_WritePin(motors[i].port_a, motors[i].pin_a, GPIO_PIN_RESET);
HAL_GPIO_WritePin(motors[i].port_b, motors[i].pin_b, GPIO_PIN_RESET);
// 设置PWM占空比为0
__HAL_TIM_SET_COMPARE(motors[i].tim, motors[i].channel, 0);
}
#if DEBUG_ENABLE
printf("Motor Initialized\r\n");
#endif
}
/**
* 设置电机速度
*/
void Motor_SetSpeed(MotorID motor_id, uint16_t speed) {
if (motor_id >= MOTOR_COUNT) return;
// 限制速度范围
if (speed > MOTOR_MAX_SPEED) speed = MOTOR_MAX_SPEED;
motors[motor_id].speed = speed;
// 更新PWM占空比
__HAL_TIM_SET_COMPARE(motors[motor_id].tim, motors[motor_id].channel, speed);
// 更新全局控制结构
switch (motor_id) {
case MOTOR_LEFT_FRONT:
g_motor_control.speed_left_front = speed;
break;
case MOTOR_RIGHT_FRONT:
g_motor_control.speed_right_front = speed;
break;
case MOTOR_LEFT_REAR:
g_motor_control.speed_left_rear = speed;
break;
case MOTOR_RIGHT_REAR:
g_motor_control.speed_right_rear = speed;
break;
}
}
/**
* 设置电机方向
*/
void Motor_SetDirection(MotorID motor_id, uint8_t direction) {
if (motor_id >= MOTOR_COUNT) return;
motors[motor_id].direction = direction;
switch (direction) {
case 0: // 停止
HAL_GPIO_WritePin(motors[motor_id].port_a, motors[motor_id].pin_a, GPIO_PIN_RESET);
HAL_GPIO_WritePin(motors[motor_id].port_b, motors[motor_id].pin_b, GPIO_PIN_RESET);
break;
case 1: // 正转
HAL_GPIO_WritePin(motors[motor_id].port_a, motors[motor_id].pin_a, GPIO_PIN_SET);
HAL_GPIO_WritePin(motors[motor_id].port_b, motors[motor_id].pin_b, GPIO_PIN_RESET);
break;
case 2: // 反转
HAL_GPIO_WritePin(motors[motor_id].port_a, motors[motor_id].pin_a, GPIO_PIN_RESET);
HAL_GPIO_WritePin(motors[motor_id].port_b, motors[motor_id].pin_b, GPIO_PIN_SET);
break;
case 3: // 刹车
HAL_GPIO_WritePin(motors[motor_id].port_a, motors[motor_id].pin_a, GPIO_PIN_SET);
HAL_GPIO_WritePin(motors[motor_id].port_b, motors[motor_id].pin_b, GPIO_PIN_SET);
break;
}
}
/**
* 前进
*/
void Motor_Forward(void) {
for (int i = 0; i < 4; i++) {
Motor_SetDirection(i, 1);
}
g_motor_control.direction = DIR_FORWARD;
}
/**
* 后退
*/
void Motor_Backward(void) {
for (int i = 0; i < 4; i++) {
Motor_SetDirection(i, 2);
}
g_motor_control.direction = DIR_BACKWARD;
}
/**
* 左转
*/
void Motor_TurnLeft(void) {
// 左轮慢,右轮快
Motor_SetSpeed(MOTOR_LEFT_FRONT, SPEED_TURN * 0.3);
Motor_SetSpeed(MOTOR_LEFT_REAR, SPEED_TURN * 0.3);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, SPEED_TURN);
Motor_SetSpeed(MOTOR_RIGHT_REAR, SPEED_TURN);
for (int i = 0; i < 4; i++) {
Motor_SetDirection(i, 1);
}
g_motor_control.direction = DIR_LEFT;
}
/**
* 右转
*/
void Motor_TurnRight(void) {
// 左轮快,右轮慢
Motor_SetSpeed(MOTOR_LEFT_FRONT, SPEED_TURN);
Motor_SetSpeed(MOTOR_LEFT_REAR, SPEED_TURN);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, SPEED_TURN * 0.3);
Motor_SetSpeed(MOTOR_RIGHT_REAR, SPEED_TURN * 0.3);
for (int i = 0; i < 4; i++) {
Motor_SetDirection(i, 1);
}
g_motor_control.direction = DIR_RIGHT;
}
/**
* 急左转
*/
void Motor_SharpLeft(void) {
// 左轮反转,右轮正转
Motor_SetDirection(MOTOR_LEFT_FRONT, 2);
Motor_SetDirection(MOTOR_LEFT_REAR, 2);
Motor_SetDirection(MOTOR_RIGHT_FRONT, 1);
Motor_SetDirection(MOTOR_RIGHT_REAR, 1);
Motor_SetSpeed(MOTOR_LEFT_FRONT, SPEED_TURN * 0.5);
Motor_SetSpeed(MOTOR_LEFT_REAR, SPEED_TURN * 0.5);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, SPEED_TURN);
Motor_SetSpeed(MOTOR_RIGHT_REAR, SPEED_TURN);
g_motor_control.direction = DIR_LEFT;
}
/**
* 急右转
*/
void Motor_SharpRight(void) {
// 左轮正转,右轮反转
Motor_SetDirection(MOTOR_LEFT_FRONT, 1);
Motor_SetDirection(MOTOR_LEFT_REAR, 1);
Motor_SetDirection(MOTOR_RIGHT_FRONT, 2);
Motor_SetDirection(MOTOR_RIGHT_REAR, 2);
Motor_SetSpeed(MOTOR_LEFT_FRONT, SPEED_TURN);
Motor_SetSpeed(MOTOR_LEFT_REAR, SPEED_TURN);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, SPEED_TURN * 0.5);
Motor_SetSpeed(MOTOR_RIGHT_REAR, SPEED_TURN * 0.5);
g_motor_control.direction = DIR_RIGHT;
}
/**
* 停止
*/
void Motor_Stop(void) {
for (int i = 0; i < 4; i++) {
Motor_SetSpeed(i, 0);
Motor_SetDirection(i, 0);
}
g_motor_control.direction = DIR_STOP;
}
/**
* 刹车
*/
void Motor_Brake(void) {
for (int i = 0; i < 4; i++) {
Motor_SetDirection(i, 3); // 刹车模式
}
g_motor_control.direction = DIR_STOP;
}
/**
* 设置所有电机速度
*/
void Motor_SetAllSpeed(uint16_t left_front, uint16_t right_front,
uint16_t left_rear, uint16_t right_rear) {
Motor_SetSpeed(MOTOR_LEFT_FRONT, left_front);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, right_front);
Motor_SetSpeed(MOTOR_LEFT_REAR, left_rear);
Motor_SetSpeed(MOTOR_RIGHT_REAR, right_rear);
}
/**
* 获取电机速度
*/
uint16_t Motor_GetSpeed(MotorID motor_id) {
if (motor_id >= MOTOR_COUNT) return 0;
return motors[motor_id].speed;
}
/**
* 获取电机方向
*/
uint8_t Motor_GetDirection(MotorID motor_id) {
if (motor_id >= MOTOR_COUNT) return 0;
return motors[motor_id].direction;
}
参考代码 stm32f103c8t6单片机设计四驱智能小车寻迹软件 www.youwenfan.com/contentcst/183172.html
4. 传感器模块 (sensor.c)
/**
* 传感器模块
*/
#include "sensor.h"
#include "config.h"
// 传感器权重(用于计算位置)
static const int8_t sensor_weights[5] = {-2, -1, 0, 1, 2};
/**
* 读取所有传感器
*/
void Sensor_ReadAll(void) {
static ADC_HandleTypeDef hadc1;
// 启动ADC转换
HAL_ADC_Start(&hadc1);
// 等待转换完成
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
// 读取5个通道的值
g_sensor_data.sensor_values[0] = HAL_ADC_GetValue(&hadc1);
g_sensor_data.sensor_values[1] = HAL_ADC_GetValue(&hadc1);
g_sensor_data.sensor_values[2] = HAL_ADC_GetValue(&hadc1);
g_sensor_data.sensor_values[3] = HAL_ADC_GetValue(&hadc1);
g_sensor_data.sensor_values[4] = HAL_ADC_GetValue(&hadc1);
}
HAL_ADC_Stop(&hadc1);
}
/**
* 处理传感器数据
*/
void Sensor_Process(void) {
int8_t line_position = 0;
uint8_t sensor_count = 0;
uint8_t all_white = 1;
uint8_t all_black = 1;
// 处理每个传感器
for (int i = 0; i < SENSOR_COUNT; i++) {
// 判断传感器状态
if (g_sensor_data.sensor_values[i] > SENSOR_THRESHOLD) {
g_sensor_data.sensor_states[i] = 1; // 黑线
all_white = 0;
// 计算加权位置
line_position += sensor_weights[i];
sensor_count++;
} else {
g_sensor_data.sensor_states[i] = 0; // 白线
all_black = 0;
}
}
// 计算平均位置
if (sensor_count > 0) {
g_sensor_data.line_position = line_position / sensor_count;
} else {
g_sensor_data.line_position = 0;
}
// 判断循迹状态
if (all_white) {
// 所有传感器都检测到白线,可能丢失轨迹
g_sensor_data.trace_state = TRACE_LOST;
g_sensor_data.lost_count++;
} else if (all_black) {
// 所有传感器都检测到黑线,可能是十字路口
g_sensor_data.trace_state = TRACE_CROSSROAD;
g_sensor_data.lost_count = 0;
} else {
// 根据传感器状态判断
uint8_t pattern = 0;
for (int i = 0; i < SENSOR_COUNT; i++) {
pattern |= (g_sensor_data.sensor_states[i] << i);
}
switch (pattern) {
// 中间传感器检测到黑线
case 0b00100: // 只有中间传感器
case 0b00110: // 中间两个
case 0b00010: // 右中
case 0b00100: // 中间
case 0b01000: // 左中
g_sensor_data.trace_state = TRACE_ON_LINE;
break;
// 左转弯
case 0b11000: // 最左+左中
case 0b10000: // 最左
case 0b01000: // 左中
g_sensor_data.trace_state = TRACE_TURN_LEFT;
break;
// 右转弯
case 0b00011: // 右中+最右
case 0b00001: // 最右
case 0b00010: // 右中
g_sensor_data.trace_state = TRACE_TURN_RIGHT;
break;
// 掉头
case 0b11111: // 全部
g_sensor_data.trace_state = TRACE_TURN_AROUND;
break;
default:
g_sensor_data.trace_state = TRACE_ON_LINE;
break;
}
g_sensor_data.lost_count = 0;
}
}
/**
* 获取传感器原始值
*/
uint16_t Sensor_GetRawValue(uint8_t sensor_id) {
if (sensor_id >= SENSOR_COUNT) return 0;
return g_sensor_data.sensor_values[sensor_id];
}
/**
* 获取传感器状态
*/
uint8_t Sensor_GetState(uint8_t sensor_id) {
if (sensor_id >= SENSOR_COUNT) return 0;
return g_sensor_data.sensor_states[sensor_id];
}
/**
* 获取轨迹位置
*/
int8_t Sensor_GetLinePosition(void) {
return g_sensor_data.line_position;
}
/**
* 获取循迹状态
*/
TraceState Sensor_GetTraceState(void) {
return g_sensor_data.trace_state;
}
/**
* 是否丢失轨迹
*/
uint8_t Sensor_IsLost(void) {
return (g_sensor_data.trace_state == TRACE_LOST);
}
/**
* 获取丢失计数
*/
uint32_t Sensor_GetLostCount(void) {
return g_sensor_data.lost_count;
}
/**
* 打印传感器状态(调试用)
*/
void Sensor_PrintStatus(void) {
#if DEBUG_ENABLE
printf("Sensors: ");
for (int i = 0; i < SENSOR_COUNT; i++) {
printf("[%d:%d:%d] ", i, g_sensor_data.sensor_values[i], g_sensor_data.sensor_states[i]);
}
printf(" Pos:%d State:%d\r\n", g_sensor_data.line_position, g_sensor_data.trace_state);
#endif
}
5. PID控制器 (pid.c)
/**
* PID控制器模块
*/
#include "pid.h"
#include "config.h"
/**
* PID初始化
*/
void PID_Init(PIDController* pid, float kp, float ki, float kd, float max_output) {
pid->Kp = kp;
pid->Ki = ki;
pid->Kd = kd;
pid->error = 0;
pid->integral = 0;
pid->derivative = 0;
pid->last_error = 0;
pid->output = 0;
pid->max_output = max_output;
}
/**
* PID计算
*/
float PID_Calculate(PIDController* pid, float setpoint, float actual, float dt) {
// 计算误差
pid->error = setpoint - actual;
// 计算积分项(带抗饱和)
pid->integral += pid->error * dt;
// 积分限幅
if (pid->integral > pid->max_output) {
pid->integral = pid->max_output;
} else if (pid->integral < -pid->max_output) {
pid->integral = -pid->max_output;
}
// 计算微分项
pid->derivative = (pid->error - pid->last_error) / dt;
// 计算输出
pid->output = (pid->Kp * pid->error) +
(pid->Ki * pid->integral) +
(pid->Kd * pid->derivative);
// 输出限幅
if (pid->output > pid->max_output) {
pid->output = pid->max_output;
} else if (pid->output < -pid->max_output) {
pid->output = -pid->max_output;
}
// 保存当前误差
pid->last_error = pid->error;
return pid->output;
}
/**
* PID重置
*/
void PID_Reset(PIDController* pid) {
pid->error = 0;
pid->integral = 0;
pid->derivative = 0;
pid->last_error = 0;
pid->output = 0;
}
/**
* 设置PID参数
*/
void PID_SetParameters(PIDController* pid, float kp, float ki, float kd) {
pid->Kp = kp;
pid->Ki = ki;
pid->Kd = kd;
}
/**
* 获取PID输出
*/
float PID_GetOutput(PIDController* pid) {
return pid->output;
}
6. 控制算法 (control.c)
/**
* 控制算法模块
*/
#include "control.h"
#include "config.h"
// 循迹状态机
static uint8_t g_trace_state = 0;
static uint32_t g_last_lost_time = 0;
/**
* 普通循迹控制
*/
void Control_Normal(void) {
// 获取传感器状态
uint8_t s1 = Sensor_GetState(0); // 最左
uint8_t s2 = Sensor_GetState(1); // 左中
uint8_t s3 = Sensor_GetState(2); // 中间
uint8_t s4 = Sensor_GetState(3); // 右中
uint8_t s5 = Sensor_GetState(4); // 最右
// 根据传感器状态控制小车
if (s3 == 1) {
// 中间传感器检测到黑线,直行
Motor_Forward();
Motor_SetSpeed(MOTOR_LEFT_FRONT, SPEED_NORMAL);
Motor_SetSpeed(MOTOR_RIGHT_FRONT, SPEED_NORMAL);
Motor_SetSpeed(MOTOR_LEFT_REAR, SPEED_NORMAL);
Motor_SetSpeed(MOTOR_RIGHT_REAR, SPEED_NORMAL);
}
else if (s2 == 1 || s1 == 1) {
// 左侧传感器检测到黑线,左转
Motor_TurnLeft();
}
else if (s4 == 1 || s5 == 1) {
// 右侧传感器检测到黑线,右转
Motor_TurnRight();
}
else if (s1 == 1 && s5 == 1) {
// 两侧传感器都检测到黑线,可能是十字路口,直行
Motor_Forward();
Motor_SetAllSpeed(SPEED_NORMAL, SPEED_NORMAL, SPEED_NORMAL, SPEED_NORMAL);
}
else {
// 没有检测到黑线,尝试寻找
Control_FindLine();
}
}
/**
* PID循迹控制
*/
int16_t Control_PID(void) {
static uint32_t last_time = 0;
uint32_t current_time = HAL_GetTick();
float dt = (current_time - last_time) / 1000.0f; // 转换为秒
if (dt == 0) dt = 0.01f; // 避免除零
// 获取当前位置(误差)
float current_position = Sensor_GetLinePosition();
// PID计算
float pid_output = PID_Calculate(&g_pid_controller, 0, current_position, dt);
last_time = current_time;
return (int16_t)pid_output;
}
/**
* 高级循迹控制(带避障)
*/
void Control_Advanced(void) {
// 检查障碍物
if (Control_CheckObstacle()) {
// 检测到障碍物,避障
Control_AvoidObstacle();
return;
}
// 正常循迹
Control_PID();
}
/**
* 寻找轨迹
*/
void Control_FindLine(void) {
static uint8_t search_direction = 0; // 0:左转, 1:右转
static uint32_t search_start_time = 0;
uint32_t current_time = HAL_GetTick();
if (g_trace_state == 0) {
// 开始寻找
search_start_time = current_time;
g_trace_state = 1;
search_direction = 0; // 先向左转
#if DEBUG_ENABLE
printf("Start searching line...\r\n");
#endif
}
if (current_time - search_start_time < 1000) {
// 向左转寻找1秒
if (search_direction == 0) {
Motor_SharpLeft();
} else {
Motor_SharpRight();
}
}
else if (current_time - search_start_time < 2000) {
// 向右转寻找1秒
if (search_direction == 0) {
Motor_SharpRight();
search_direction = 1;
} else {
Motor_SharpLeft();
search_direction = 0;
}
}
else {
// 寻找超时,停止
Motor_Stop();
g_car_info.state = CAR_STATE_ERROR;
#if DEBUG_ENABLE
printf("Line search timeout!\r\n");
#endif
}
// 检查是否找到轨迹
if (!Sensor_IsLost()) {
g_trace_state = 0;
#if DEBUG_ENABLE
printf("Line found!\r\n");
#endif
}
}
/**
* 检查障碍物
*/
uint8_t Control_CheckObstacle(void) {
// 这里可以添加超声波或红外避障传感器检测
// 简化实现:返回0
return 0;
}
/**
* 避障算法
*/
void Control_AvoidObstacle(void) {
// 避障算法实现
// 1. 停止
Motor_Stop();
HAL_Delay(500);
// 2. 后退
Motor_Backward();
Motor_SetAllSpeed(SPEED_SLOW, SPEED_SLOW, SPEED_SLOW, SPEED_SLOW);
HAL_Delay(300);
// 3. 左转
Motor_SharpLeft();
HAL_Delay(500);
// 4. 前进
Motor_Forward();
Motor_SetAllSpeed(SPEED_NORMAL, SPEED_NORMAL, SPEED_NORMAL, SPEED_NORMAL);
HAL_Delay(800);
// 5. 右转
Motor_SharpRight();
HAL_Delay(500);
// 6. 继续前进
Motor_Forward();
}
/**
* 处理十字路口
*/
void Control_HandleCrossroad(void) {
static uint8_t crossroad_count = 0;
// 十字路口处理策略
// 可以根据需要实现左转、右转、直行
// 默认直行
Motor_Forward();
Motor_SetAllSpeed(SPEED_FAST, SPEED_FAST, SPEED_FAST, SPEED_FAST);
HAL_Delay(300);
crossroad_count++;
#if DEBUG_ENABLE
printf("Crossroad passed: %d\r\n", crossroad_count);
#endif
}
/**
* 急弯处理
*/
void Control_HandleSharpTurn(void) {
TraceState trace_state = Sensor_GetTraceState();
if (trace_state == TRACE_TURN_LEFT) {
// 急左转
Motor_SharpLeft();
HAL_Delay(200);
}
else if (trace_state == TRACE_TURN_RIGHT) {
// 急右转
Motor_SharpRight();
HAL_Delay(200);
}
}
/**
* 速度控制
*/
void Control_SpeedAdjust(uint8_t condition) {
switch (condition) {
case 0: // 直线加速
g_car_info.base_speed = SPEED_FAST;
break;
case 1: // 转弯减速
g_car_info.base_speed = SPEED_TURN;
break;
case 2: // 复杂路况慢速
g_car_info.base_speed = SPEED_SLOW;
break;
default:
g_car_info.base_speed = SPEED_NORMAL;
break;
}
}
7. 串口调试 (uart.c)
/**
* 串口调试模块
*/
#include "uart.h"
#include "config.h"
UART_HandleTypeDef huart1;
/**
* 串口初始化
*/
void UART_Init(uint32_t baudrate) {
huart1.Instance = USART1;
huart1.Init.BaudRate = baudrate;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
// 使能USART1时钟
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置GPIO
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 初始化UART
if (HAL_UART_Init(&huart1) != HAL_OK) {
Error_Handler();
}
printf("UART Initialized: %lu baud\r\n", baudrate);
}
/**
* 重定向printf到串口
*/
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE {
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
引脚分配表
| 引脚 | 功能 | 说明 |
|---|---|---|
| PA0 | 传感器1 | 最左侧循迹传感器 |
| PA1 | 传感器2 | 左侧循迹传感器 |
| PA2 | 传感器3 | 中间循迹传感器 |
| PA3 | 传感器4 | 右侧循迹传感器 |
| PA4 | 传感器5 | 最右侧循迹传感器 |
| PA5 | 启动按键 | 开始/暂停 |
| PA6 | 模式按键 | 切换循迹模式 |
| PA8 | 蜂鸣器 | 状态提示音 |
| PB6 | 电机1A | 左前电机方向A |
| PB7 | 电机1B | 左前电机方向B |
| PB8 | 电机2A | 右前电机方向A |
| PB9 | 电机2B | 右前电机方向B |
| PB10 | 电机3A | 左后电机方向A |
| PB11 | 电机3B | 左后电机方向B |
| PB12 | 电机4A | 右后电机方向A |
| PB13 | 电机4B | 右后电机方向B |
| PC13 | 运行LED | 系统运行指示 |
| PC14 | 错误LED | 错误状态指示 |
| PC15 | 循迹LED | 循迹状态指示 |
使用说明
1. 编译和烧录
# 使用Keil MDK
1. 打开工程文件 SmartCar.uvprojx
2. 设置目标设备为 STM32F103C8T6
3. 编译工程 (F7)
4. 使用ST-Link烧录 (F8)
# 使用STM32CubeIDE
1. 导入工程
2. 选择正确的芯片型号
3. 编译并运行
2. 操作说明
- 启动按键: 长按启动小车,短按暂停/继续
- 模式按键: 切换循迹模式(普通/PID/高级)
- 运行LED: 系统正常运行指示灯,1Hz闪烁
- 循迹LED: 检测到轨迹时亮起
- 错误LED: 系统错误时亮起
3. 调试信息
通过串口(115200bps)可查看调试信息:
=== Debug Info ===
State: 2, Mode: 1
Run Time: 120s, Distance: 50m
Line Pos: 0, Trace State: 1
Motor: LF=1200, RF=1200, LR=1200, RR=1200
PID Output: 0.00
==================
参数调优
1. PID参数调优
// 在config.h中修改
#define PID_KP 2.0f // 增大:响应更快但易震荡
#define PID_KI 0.1f // 增大:消除稳态误差
#define PID_KD 1.5f // 增大:抑制超调
2. 传感器阈值校准
// 在config.h中修改
#define SENSOR_THRESHOLD 500
// 实际值需要根据传感器安装高度和地面颜色调整
3. 速度参数调整
// 在config.h中修改
#define MOTOR_BASE_SPEED 1000
#define SPEED_SLOW 800
#define SPEED_FAST 1600
#define SPEED_TURN 1000
扩展功能建议
- 蓝牙遥控: 添加HC-05模块实现手机控制
- OLED显示: 添加0.96寸OLED显示状态信息
- 超声波避障: 添加HC-SR04模块实现自动避障
- MPU6050: 添加姿态传感器实现更精准控制
- 编码器测速: 添加光电编码器实现闭环速度控制
- WiFi摄像头: 添加ESP32-CAM实现视频传输