对于2024电赛h题,我没有学会角度传感器,只做出了前两问,接下来我对前两问的配置做一下分享,写的不是很好。
首先介绍一下我的配置
对于第一问,要从A点到B点停车,我的思路是将小车放到A,按下按钮,进行前进指令,五路灰度接触到黑线进行停车操作
以下是我模式1的代码mode1.c
#include "stm32f4xx_hal.h"
#include "BSP_BEEP.h"
#include "gray.h"
#include "motor.h"
#include "BSP_KEY.h"
#include "mode1.h"
#include "BSP_LED.h"
void KEY11(void)
{
if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == 0) { // 检测按键按下(低电平)
HAL_Delay(100);
if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == 0) {
BLACK1(); // 按键按下时执行巡线检测
}
while (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == 0); // 等待按键释放
}
}
// 检测是否全部检测到黑线
void BLACK1()
{
while (1){ // 持续巡线,直到检测到黑线停止
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);
if (leftSensor1 == 1 || leftSensor2 == 1 || middleSensor==1||rightSensor1==1||rightSensor2==1) {
// 任意一个传感器检测到黑线
StopCarAction();
Beeper_On ();
break; // 退出巡线循环
} else {
MoveForwardAction(); // 没有检测到黑线,继续前进
}
HAL_Delay(10); // 适当的延迟,可根据实际情况调整
}
}
以下是mode.h
#ifndef __CAR_CONTROL_H
#define __CAR_CONTROL_H
#include "stm32f4xx_hal.h"
// 函数声明
void KEY11(void);
void BLACK1(void);
#endif
第二问的话,难点在于从黑线出去后怎么才能到达对面黑线,用角度传感器的话是可以做到的,我不会使用,后面因为一次失误给了我灵感,因为顺时针转,我们可以在直行代码中让左侧车轮走的快一点,正好可以到达对面黑线进行循迹。
mode2.c
#include "stm32f4xx_hal.h"
#include "BSP_BEEP.h"
#include "gray.h"
#include "motor.h"
#include "BSP_KEY.h"
#include "mode2.h"
#include "tim.h"
// 全局变量记录开始时间
uint32_t startTime = 0;
void KEY22(void)
{
if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0) { // 检测按键按下(低电平)
HAL_Delay(100);
if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0) {
startTime = HAL_GetTick(); // 记录开始时间
StartLineFollowing(); // 调用单独的巡线函数
}
}
while (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0); // 等待按键释放
}
void StartLineFollowing()
{
while (1)
{
Track_Adjust();
if (HAL_GetTick() - startTime > 13000)
{
StopCarAction();
Beeper_On();
break;
}
}
}
void Track_Adjust(void);
mode2.h
#ifndef YOUR_PROJECT_H
#define YOUR_PROJECT_H
#include "stm32f4xx_hal.h"
extern uint32_t startTime;
void KEY22(void);
void StartLineFollowing();
void BeepE(void) ;
#endif
以上是两个模式的代码,接下来是驱动电机代码
motor.c
#include "stm32f4xx_hal.h" // Device header
#include "motor.h"
#include "gpio.h"
#include "tim.h"
/**
* @brief 停止小车
*/
void StopCar()
{
motorControlL(1,0);
motorControlR(1,0);
}
/**
* @brief 小车前进
* @param Speed 速度值(0 - 1000)
*/
void MoveForward(uint16_t Speed)
{
if (Speed > 1000) {
Speed = 1000;
}
motorControlL(1, Speed);
motorControlR(1,Speed+13.9);
}
/**
* @brief 小车后退
* @param Speed 速度值(0 - 1000)
*/
void Car_Backward(uint16_t Speed)
{
if (Speed > 1000) {
Speed = 1000;
}
motorControlL(0, Speed);
motorControlR(0,Speed);
}
/**
* @brief 小车左转
* @param Speed 速度值(0 - 1000)
*/
void LiftAndPlaceWithSpeed(uint16_t Speed)
{
if (Speed > 1000) {
Speed = 1000;
}
motorControlL(1, Speed);
motorControlR(1, Speed+DEFAULT_SPEED);
}
/**
* @brief 小车左转
* @param Speed 速度值(0 - 1000)
*/
void LiftSpeed(uint16_t Speed)
{
if (Speed > 1000) {
Speed = 1000;
}
motorControlL(1, Speed);
motorControlR(1, Speed+100);
}
/**
* @brief 小车右转
* @param Speed 速度值(0 - 1000)
*/
void RightAndPlaceWithSpeed(uint16_t Speed)
{
if (Speed > 1000) {
Speed = 1000;
}
motorControlL(1, Speed+DEFAULT_SPEED);
motorControlR(1, Speed);
}
/**
* @brief 小车右转
* @param Speed 速度值(0 - 1000)
*/
void RightSpeed(uint16_t Speed)
{
if (Speed > 1000) {
Speed = 1000;
}
motorControlL(1, Speed+100);
motorControlR(1, Speed);
}
/**
* @brief 控制左侧电机
* @param Dir 方向(1 正转,0 反转)
* @param Speed 速度值(0 - 1000)
*/
void motorControlL(uint8_t Dir, uint16_t 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)
{
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
/* 根据方向设置 IN1 咿 IN2 引脚 */
HAL_GPIO_WritePin(GPIOA, AIN1_Pin, (Dir & 0x01));
HAL_GPIO_WritePin(GPIOA, AIN2_Pin, ((Dir & 0x01) ^ 0x01));
/* 设置 PWM 引脚以控制?度 */
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, Speed);
// 检查速度是否超出范围
}
motor.h
#ifndef CAR_CONTROL_H
#define CAR_CONTROL_H
#include "stm32f4xx_hal.h" // Device header
// 定义电机速度常量
#define DEFAULT_SPEED 100
void LiftSpeed(uint16_t Speed);
void RightSpeed(uint16_t Speed);
// 停止小车
void StopCar(void);
// 小车前进
void MoveForward(uint16_t Speed);
// 小车后退
void Car_Backward(uint16_t Speed);
// 小车左转
void LiftAndPlaceWithSpeed(uint16_t Speed);
// 小车右转
void RightAndPlaceWithSpeed(uint16_t Speed);
// 控制左侧电机
void motorControlL(uint8_t Dir, uint16_t Speed);
// 控制右侧电机
void motorControlR(uint8_t Dir, uint16_t Speed);
#endif
灰度也是重要的一部分
gray.c
#include "stm32f4xx_hal.h"
#include "gray.h"
#include "motor.h"
#include "stdio.h"
#include "main.h"
#include "BSP_BEEP.h"
// 定义更具描述性的常量
#define LEFT_SENSOR1_PIN GPIOB, GPIO_PIN_14
#define LEFT_SENSOR2_PIN GPIOA, GPIO_PIN_9
#define MIDDLE_SENSOR_PIN GPIOA, GPIO_PIN_12
#define RIGHT_SENSOR1_PIN GPIOC, GPIO_PIN_8
#define RIGHT_SENSOR2_PIN GPIOC, GPIO_PIN_9
// 定义不同的动作函数
void StopCarAction() {
StopCar();
}
void MoveForwardAction() {
MoveForward(300);
}
void LiftAndPlaceWithSpeedAction() {
LiftAndPlaceWithSpeed(150);
}
void RightAndPlaceWithSpeedAction() {
RightAndPlaceWithSpeed(150);
}
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)) {
LiftAndPlaceWithSpeedAction();
} else {
MoveForwardAction();
}
}
gray.h
#ifndef GRAY_SCALE_H
#define GRAY_SCALE_H
#include "stm32f4xx_hal.h"
// 定义灰度传感器引脚
#define LEFT_SENSOR1_PIN GPIOB, GPIO_PIN_14
#define LEFT_SENSOR2_PIN GPIOA, GPIO_PIN_9
#define MIDDLE_SENSOR_PIN GPIOA, GPIO_PIN_12
#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
以上是我对前两问完成的代码,对放置角度有一定要求,属于强行调参数调出来的,不过这已经是我能凭自己完成任务的方法,之后我还会继续学习,将其他任务完成。