我想知道用stm32CubeIDE软件来做一辆带有stm32芯片的智能循迹小车的具体代码程序
循迹小车的代码程序有很多种实现方式,根据不同的传感器、控制器和通信模块等硬件组件的不同,代码实现也会有所区别。下面给出一种基于STM32芯片和红外传感器的智能循迹小车的代码程序,供参考:
#include "stm32f1xx_hal.h"
/* 定义红外传感器引脚 */
#define IR_LEFT_Pin GPIO_PIN_0
#define IR_LEFT_GPIO_Port GPIOA
#define IR_CENTER_Pin GPIO_PIN_1
#define IR_CENTER_GPIO_Port GPIOA
#define IR_RIGHT_Pin GPIO_PIN_2
#define IR_RIGHT_GPIO_Port GPIOA
/* 定义电机引脚 */
#define MOTOR_LEFT_PWM_Pin GPIO_PIN_6
#define MOTOR_LEFT_PWM_GPIO_Port GPIOB
#define MOTOR_LEFT_DIR_Pin GPIO_PIN_7
#define MOTOR_LEFT_DIR_GPIO_Port GPIOB
#define MOTOR_RIGHT_PWM_Pin GPIO_PIN_8
#define MOTOR_RIGHT_PWM_GPIO_Port GPIOB
#define MOTOR_RIGHT_DIR_Pin GPIO_PIN_9
#define MOTOR_RIGHT_DIR_GPIO_Port GPIOB
/* 定义红外传感器检测阈值 */
#define IR_THRESHOLD 1000
/* 定义电机控制参数 */
#define MOTOR_PWM_MAX 1000
#define MOTOR_PWM_MIN 300
#define MOTOR_PWM_STEP 50
#define MOTOR_PWM_DELAY 5
/* 定义循迹状态 */
typedef enum {
TRACKING_NONE,
TRACKING_LEFT,
TRACKING_CENTER,
TRACKING_RIGHT
} TrackingState;
/* 定义电机方向 */
typedef enum {
MOTOR_DIR_FORWARD,
MOTOR_DIR_BACKWARD
} MotorDirection;
/* 定义电机 */
typedef struct {
TIM_HandleTypeDef *htim;
uint32_t pwm_channel;
GPIO_TypeDef *dir_port;
uint16_t dir_pin;
uint16_t pwm;
MotorDirection dir;
} Motor;
/* 定义循迹小车 */
typedef struct {
Motor motor_left;
Motor motor_right;
GPIO_TypeDef *ir_left_port;
uint16_t ir_left_pin;
GPIO_TypeDef *ir_center_port;
uint16_t ir_center_pin;
GPIO_TypeDef *ir_right_port;
uint16_t ir_right_pin;
TrackingState tracking_state;
} TrackCar;
/* 初始化电机 */
void motor_init(Motor *motor, TIM_HandleTypeDef *htim, uint32_t pwm_channel, GPIO_TypeDef *dir_port, uint16_t dir_pin) {
motor->htim = htim;
motor->pwm_channel = pwm_channel;
motor->dir_port = dir_port;
motor->dir_pin = dir_pin;
motor->pwm = 0;
motor->dir = MOTOR_DIR_FORWARD;
}
/* 设置电机方向 */
void motor_set_direction(Motor *motor, MotorDirection dir) {
if (motor->dir != dir) {
motor->dir = dir;
if (dir == MOTOR_DIR_FORWARD) {
HAL_GPIO_WritePin(motor->dir_port, motor->dir_pin, GPIO_PIN_RESET);
} else {
HAL_GPIO_WritePin(motor->dir_port, motor->dir_pin, GPIO_PIN_SET);
}
}
}
/* 设置电机PWM */
void motor_set_pwm(Motor *motor, uint16_t pwm) {
if (pwm > MOTOR_PWM_MAX) {
pwm = MOTOR_PWM_MAX;
} else if (pwm < MOTOR_PWM_MIN) {
pwm = MOTOR_PWM_MIN;
}
if (motor->pwm != pwm) {
motor->pwm = pwm;
__HAL_TIM_SET_COMPARE(motor->htim, motor->pwm_channel, pwm);
}
}
/* 初始化循迹小车 */
void track_car_init(TrackCar *car) {
/* 初始化电机 */
motor_init(&(car->motor_left), &htim3, TIM_CHANNEL_1, MOTOR_LEFT_DIR_GPIO_Port, MOTOR_LEFT_DIR_Pin);
motor_init(&(car->motor_right), &htim3, TIM_CHANNEL_2, MOTOR_RIGHT_DIR_GPIO_Port, MOTOR_RIGHT_DIR_Pin);
/* 初始化红外传感器 */
car->ir_left_port = IR_LEFT_GPIO_Port;
car->ir_left_pin = IR_LEFT_Pin;
car->ir_center_port = IR_CENTER_GPIO_Port;
car->ir_center_pin = IR_CENTER_Pin;
car->ir_right_port = IR_RIGHT_GPIO_Port;
car->ir_right_pin = IR_RIGHT_Pin;
/* 初始化循迹状态 */
car->tracking_state = TRACKING_NONE;
}
/* 获取红外传感器检测值 */
uint16_t ir_read(GPIO_TypeDef *port, uint16_t pin) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(port, &GPIO_InitStruct);
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 1000);
uint16_t value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return value;
}
/* 更新循迹状态 */
void track_car_update(TrackCar *car) {
uint16_t ir_left = ir_read(car->ir_left_port, car->ir_left_pin);
uint16_t ir_center = ir_read(car->ir_center_port, car->ir_center_pin);
uint16_t ir_right = ir_read(car->ir_right_port, car->ir_right_pin);
if (ir_left > IR_THRESHOLD && ir_center > IR_THRESHOLD && ir_right > IR_THRESHOLD) {
/* 没有检测到黑线 */
car->tracking_state = TRACKING_NONE;
} else if (ir_left <= IR_THRESHOLD && ir_center > IR_THRESHOLD && ir_right > IR_THRESHOLD) {
/* 检测到左边的黑线 */
car->tracking_state = TRACKING_LEFT;
} else if (ir_left > IR_THRESHOLD && ir_center <= IR_THRESHOLD && ir_right > IR_THRESHOLD) {
/* 检测到中间的黑线 */
car->tracking_state = TRACKING_CENTER;
} else if (ir_left > IR_THRESHOLD && ir_center > IR_THRESHOLD && ir_right <= IR_THRESHOLD) {
/* 检测到右边的黑线 */
car->tracking_state = TRACKING_RIGHT;
}
}
/* 控制循迹小车 */
void track_car_control(TrackCar *car) {
switch (car->tracking_state) {
case TRACKING_NONE:
/* 没有检测到黑线,停止电机 */
motor_set_pwm(&(car->motor_left), 0);
motor_set_pwm(&(car->motor_right), 0);
break;
case TRACKING_LEFT:
/* 检测到左边的黑线,向右转 */
motor_set_direction(&(car->motor_left), MOTOR_DIR_FORWARD);
motor_set_direction(&(car->motor_right), MOTOR_DIR_BACKWARD);
motor_set_pwm(&(car->motor_left), MOTOR_PWM_MAX);
motor_set_pwm(&(car->motor_right), MOTOR_PWM_MIN);
break;
case TRACKING_CENTER:
/* 检测到中间的黑线,直走 */
motor_set_direction(&(car->motor_left), MOTOR_DIR_FORWARD);
motor_set_direction(&(car->motor_right), MOTOR_DIR_FORWARD);
motor_set_pwm(&(car->motor_left), MOTOR_PWM_MAX);
motor_set_pwm(&(car->motor_right), MOTOR_PWM_MAX);
break;
case TRACKING_RIGHT:
/* 检测到右边的黑线,向左转 */
motor_set_direction(&(car->motor_left), MOTOR_DIR_BACKWARD);
motor_set_direction(&(car->motor_right), MOTOR_DIR_FORWARD);
motor_set_pwm(&(car->motor_left), MOTOR_PWM_MIN);
motor_set_pwm(&(car->motor_right), MOTOR_PWM_MAX);
break;
}
}
int main(void) {
/* 初始化循迹小车 */
TrackCar car;
track_car_init(&car);
/* 循环处理 */
while (1) {
/* 更新循迹状态 */
track_car_update(&car);
/* 控制循迹小车 */
track_car_control(&car);
/* 延时一段时间 */
HAL_Delay(MOTOR_PWM_DELAY);
}
}
以上是一份简单的循迹小车代码程序,具体实现还需要根据具体的硬件组件和需求进行修改和优化
原文地址: https://www.cveoy.top/t/topic/dq2b 著作权归作者所有。请勿转载和采集!