五路灰度我使用的是数字五路灰度,它可以用螺丝刀来调节其灵敏度,使用起来也是非常简单,在白色区域五路灰度上的led亮,在黑线灭,五路灰度灵敏度就调好了。对于代码部分,五路灰度传回值0白色区域,传回1为黑色区域。
首先看一下他的cubmx配置,其他配置就不多说了,还和以前一样,不过我把驱动电机分别放倒了htim2和3的一通道,添加五路灰度配置,所使用io口为gpio_input,分别将其命名为L2,L1,M,R1,R2
其他配置和之前的一样,这里就不多说了,生成keil5文件就好了。
首先是motor.c文件代码
#include "stm32f4xx_hal.h" // Device header
#include "motor.h"
#include "gpio.h"
#include "tim.h"
// 定义电机速度常量
#define DEFAULT_SPEED 65
#define LIFT_PLACE_SPEED_INCREMENT 20
#define MAX_SPEED 1000 // 定义最大速度限制
// 定义延迟时间常量
#define DELAY_TIME 50
/**
* @brief 检查速度是否在有效范围内
* @param speed 要检查的速度值
* @return 如果速度有效返回 1,否则返回 0
*/
int checkSpeedValidity(uint16_t Speed) {
if (Speed >= 0 && Speed <= MAX_SPEED) {
return 1;
}
return 0;
}
/**
* @brief 小车前进
*/
void MoveForward() {
if (checkSpeedValidity(DEFAULT_SPEED)) { // 增加速度有效性检查
motorControlL(1, DEFAULT_SPEED);
motorControlR(1, DEFAULT_SPEED);
}
}
/**
* @brief 小车停止
*/
void StopCar() {
motorControlL(1, 0);
motorControlR(1, 0);
}
/**
* @brief 以左
*/
void LiftAndPlaceWithSpeed() {
if (checkSpeedValidity(DEFAULT_SPEED) && checkSpeedValidity(DEFAULT_SPEED + LIFT_PLACE_SPEED_INCREMENT)) {
motorControlL(1, DEFAULT_SPEED);
motorControlR(1, DEFAULT_SPEED + LIFT_PLACE_SPEED_INCREMENT);
HAL_Delay(DELAY_TIME);
}
}
/**
* @brief 向右转
*/
void RightAndPlaceWithSpeed() {
if (checkSpeedValidity(DEFAULT_SPEED) && checkSpeedValidity(DEFAULT_SPEED + LIFT_PLACE_SPEED_INCREMENT)) {
motorControlL(1, DEFAULT_SPEED + LIFT_PLACE_SPEED_INCREMENT);
motorControlR(1, DEFAULT_SPEED);
HAL_Delay(DELAY_TIME);
}
}
/*
* @brief 控制左侧电机
* @param Dir 方向(1 正转,0 反转)
* @param Speed 速度值(0 - 1000)
*/
void motorControlL(uint8_t Dir, uint16_t Speed)
{
if (checkSpeedValidity(Speed)) { // 增加速度有效性检查
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
/* 根据方向设置 IN1 和 IN2 引脚 */
HAL_GPIO_WritePin(GPIOC, BIN1_Pin, (Dir & 0x01));
HAL_GPIO_WritePin(GPIOC, BIN2_Pin, ((Dir & 0x01) ^ 0x01));
/* 设置 PWM 引脚以控制速度 */
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, Speed);
}
}
/**
* @brief 控制右侧电机
* @param Dir 方向(1 正转,0 反转)
* @param Speed 速度值(0 - 1000)
*/
void motorControlR(uint8_t Dir, uint16_t Speed)
{
if (checkSpeedValidity(Speed)) { // 增加速度有效性检查
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
/* 根据方向设置 IN1 和 IN2 引脚 */
HAL_GPIO_WritePin(GPIOA, AIN2_Pin, (Dir & 0x01));
HAL_GPIO_WritePin(GPIOA, AIN1_Pin, ((Dir & 0x01) ^ 0x01));
/* 设置 PWM 引脚以控制速度 */
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, Speed);
}
}
接下来是motor.h
#ifndef MOTOR_CONTROL_H
#define MOTOR_CONTROL_H
#include "stm32f4xx_hal.h"
// 定义电机速度常量
#define DEFAULT_SPEED 65
#define LIFT_PLACE_SPEED_INCREMENT 20
#define MAX_SPEED 1000 // 定义最大速度限制
// 定义延迟时间常量
#define DELAY_TIME 50
// 函数声明
int checkSpeedValidity(uint16_t speed);
void MoveForward();
void StopCar();
void LiftAndPlaceWithSpeed();
void LiftAndPlaceWithSpeed0();
void LiftAndPlaceWithSpeed1();
void LiftAndPlaceWithSpeed2();
void LiftAndMoveForward();
void RightAndPlaceWithSpeed();
void RightAndPlaceWithSpeed0();
void RightAndPlaceWithSpeed1();
void RightAndPlaceWithSpeed2();
void RightAndMoveForward();
void motorControlR(uint8_t Dir, uint16_t Speed);
void motorControlL(uint8_t Dir, uint16_t Speed);
#endif
然后是五路灰度代码
gray.c
#include "stm32f4xx_hal.h"
#include "gray.h"
#include "motor.h"
#include "stdio.h"
// 定义更具描述性的常量
#define LEFT_SENSOR1_PIN GPIOA, GPIO_PIN_10
#define LEFT_SENSOR2_PIN GPIOA, GPIO_PIN_9
#define MIDDLE_SENSOR_PIN GPIOA, GPIO_PIN_8
#define RIGHT_SENSOR1_PIN GPIOC, GPIO_PIN_8
#define RIGHT_SENSOR2_PIN GPIOC, GPIO_PIN_9
// 定义不同的动作函数
void StopCarAction() {
StopCar();
}
void MoveForwardAction() {
MoveForward();
}
void LiftAndPlaceWithSpeedAction() {
LiftAndPlaceWithSpeed();
}
void RightAndPlaceWithSpeedAction() {
RightAndPlaceWithSpeed();
}
void Track_Adjust(void)
{
int leftSensor1, leftSensor2, middleSensor, rightSensor1, rightSensor2;
leftSensor1 = HAL_GPIO_ReadPin(LEFT_SENSOR1_PIN);
leftSensor2 = HAL_GPIO_ReadPin(LEFT_SENSOR2_PIN);
middleSensor = HAL_GPIO_ReadPin(MIDDLE_SENSOR_PIN);
rightSensor1 = HAL_GPIO_ReadPin(RIGHT_SENSOR1_PIN);
rightSensor2 = HAL_GPIO_ReadPin(RIGHT_SENSOR2_PIN);
// 详细的注释解释每个条件
//0白1黑
if (leftSensor2 == 1 && leftSensor1 == 1 && middleSensor == 1 && rightSensor2 == 1 && rightSensor1 == 1)
{
StopCarAction();
HAL_Delay(500);
MoveForwardAction();
} else if ((leftSensor2 == 0 && leftSensor1 == 0 && middleSensor == 1 && rightSensor1 == 0 && rightSensor2 == 0) ||
(leftSensor2 == 0 && leftSensor1 == 1 && middleSensor == 1 && rightSensor1 == 0 && rightSensor2 == 0) ||
(leftSensor2 == 0 && leftSensor1 == 0 && middleSensor == 0 && rightSensor1 == 0 && rightSensor2 == 0)||
(leftSensor2 == 0 && leftSensor1 == 0 && middleSensor == 1 && rightSensor1 == 1 && rightSensor2 == 0) ||
(leftSensor2 == 0 && leftSensor1 == 1 && middleSensor == 1 && rightSensor1 == 1 && rightSensor2 == 0)) {
MoveForwardAction();
} else if ((leftSensor2 == 0 && leftSensor1 == 1 && middleSensor == 0 && rightSensor1 == 0 && rightSensor2 == 0) ||
(leftSensor2 == 1 && leftSensor1 == 1 && middleSensor == 0 && rightSensor1 == 0 && rightSensor2 == 0) ||
(leftSensor2 == 1 && leftSensor1 == 0 && middleSensor == 0 && rightSensor1 == 0 && rightSensor2 == 0)) {
RightAndPlaceWithSpeedAction();
} else if ((leftSensor2 == 0 && leftSensor1 == 0 && middleSensor == 0 && rightSensor1 == 1 && rightSensor2 == 0) ||
(leftSensor2 == 0 && leftSensor1 == 0 && middleSensor == 0 && rightSensor1 == 1 && rightSensor2 == 1) ||
(leftSensor2 == 0 && leftSensor1 == 0 && middleSensor == 0 && rightSensor1 == 0 && rightSensor2 == 1)) {
LiftAndPlaceWithSpeed();
} else {
MoveForwardAction();
}
}
gray.h
#ifndef GRAY_SCALE_H
#define GRAY_SCALE_H
#include "stm32f4xx_hal.h"
// 定义灰度传感器引脚
#define LEFT_SENSOR1_PIN GPIOA, GPIO_PIN_10
#define LEFT_SENSOR2_PIN GPIOA, GPIO_PIN_9
#define MIDDLE_SENSOR_PIN GPIOA, GPIO_PIN_8
#define RIGHT_SENSOR1_PIN GPIOC, GPIO_PIN_8
#define RIGHT_SENSOR2_PIN GPIOC, GPIO_PIN_9
// 定义不同的动作函数声明
void StopCarAction(void);
void MoveForwardAction(void);
void LiftAndPlaceWithSpeedAction(void);
void RightAndPlaceWithSpeedAction(void);
// 轨迹调整函数声明
void Track_Adjust(void);
#endif
在main.c中引用头文件
/* USER CODE BEGIN Includes */
#include "motor.h"
#include "gray.h"
/* USER CODE END Includes */
在while循环中的代码
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Track_Adjust();
}
/* USER CODE END 3 */
}
while循环中可能会有警告,编译完可以直接烧录使用,不用改。
如果可以买编码器电机,这个可以在行进过程中根据编码器调节速度,(我的这篇文章中没有编码器代码),而且他比较重,影响小车速度,是小车在循迹过程中更稳定,使用tt直流电机我经常冲出跑道。