硬件课程设计(下):引脚定义及功能实现
本文最后更新于 879 天前,其中的信息可能已经有所发展或是发生改变。

前言

本课设主要完成小车的蓝牙控制、避障行驶与自动循迹,该智能小车以 STM32 单片机为主控芯片,采用红外对管和超声波传感器作为检测元件,使小车能正确避障行驶与自动循迹。

前文所述,我们成功配置了 STM32 的开发环境 – Keli μVision 和 STM32CubeMX,并进行了最基础的引脚设置。

在本文中我们将继续讲述如何参照电路图对可用的引脚进行相应定义,及实现课设所需的功能。

实验内容及原理

主要内容:实现小车变速、遥控控制行驶、自动避障行驶、循迹行驶等功能。

1.基础控制/遥控原理

即编程控制 STM32 引脚去沟通电机驱动芯片再来实现小车电机的控制,实现小车的基本前进后退左转右转操作。

由芯片的PB6,7,8,9的高低电平来控制小车的移动,关系如下:

6,7控制左轮:1,0为前进,0,1为后退,电平相同则停止;

8,9控制左轮:1,0为前进,0,1为后退,电平相同则停止。

驱动蓝牙模块:实现小车的动作控制信号由手机发出,完成遥控功能。

PA9—STM32-U1_TX ——————–>蓝牙的RX

PA10-STM32_U1_RX———————>蓝牙的TX

至此,完成了:手机—->蓝牙—>STM32芯片—->电机驱动芯片—->4个电机 的操作方式

2.舵机控制原理

①PWM舵机

②PWM—-脉冲宽度调制

③PWM舵机控制原理

需要提供舵机的控制信号线一个20ms周期的PWM波,再在每个20ms周期内调整高电平时长为0.5ms~2.5ms就可以调整对应角度。

即编程控制 STM32 引脚去沟通电机驱动芯片再来实现小车电机的控制,实现小车的基本前进后退左转右转操作。


由此,本程序的执行逻辑如下:

主函数逻辑:

本程序由三个独立的模式组成

小车避障逻辑:

自动避障的流程会多次重复执行

STM32 引脚定义

实验代码

以下是在 STM32CubeMX 生成工程后,在 Keli μVision 中打开工程编写的代码。

请注意,自行编辑的代码需要写在生成的工程的“USER CODE BEGIN xxx”和”USER CODE END xxx“ 之间。

否则在 STM32CubeMX 重新生成工程后,相应不在区间的代码会被抹除。

//main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
 TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM4_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* Delay function */
void delay_us(uint32_t delay_us)
{    
  volatile unsigned int num;
  volatile unsigned int t;
  for (num = 0; num < delay_us; num++)
  {
    t = 11;
    while (t != 0)
    {
      t--;
    }
  }
}
void delay_ms(uint16_t delay_ms)
{    
  volatile unsigned int num;
  for (num = 0; num < delay_ms; num++)
  {
    delay_us(1000);
  }
}

/* Direction Control */
void carMoveForward(int speed)
{
  TIM4->CCR1 = speed-260;
  TIM4->CCR2 = 0;
  TIM4->CCR3 = speed;
  TIM4->CCR4 = 0;
}
void carMoveBackward(int speed)
{
  TIM4->CCR1 = 0;
  TIM4->CCR2 = speed-260;
  TIM4->CCR3 = 0;
  TIM4->CCR4 = speed;
}
void carMoveLeft(int speed) //Difference speed steering 
{
  TIM4->CCR1 = speed/3;
  TIM4->CCR2 = 0;
  TIM4->CCR3 = speed;
  TIM4->CCR4 = 0;
}
void carMoveLeft2(int speed)  //Difference speed steering 
{
  TIM4->CCR1 = 0;
  TIM4->CCR2 = speed;
  TIM4->CCR3 = speed;
  TIM4->CCR4 = 0;
}
void carMoveRight(int speed)
{
  TIM4->CCR1 = speed;
  TIM4->CCR2 = 0;
  TIM4->CCR3 = speed/4;
  TIM4->CCR4 = 0;
}
void carMoveRight2(int speed)
{
  TIM4->CCR1 = speed;
  TIM4->CCR2 = 0;
  TIM4->CCR3 = 0;
  TIM4->CCR4 = speed;
}
void carMoveStop()
{
  TIM4->CCR1 = 0;
  TIM4->CCR2 = 0;
  TIM4->CCR3 = 0;
  TIM4->CCR4 = 0;
}

/* Sonar detection */
float obstDist(void)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11  ,GPIO_PIN_SET); //Trigger
  
  TIM2->CR1 &= ~0x01;
  TIM2->CNT = 0;
  TIM2->CR1 |= 0x01;
  while(TIM2->CNT < 20);  //Wait
  
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11  ,GPIO_PIN_RESET); //DISABLE Trigger
  
  while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == 0);  //Wait for echo
  
  TIM2->CR1 &= ~0x01;
  TIM2->CNT = 0;  
  TIM2->CR1 |= 0x01;  //Reset counter
  
  while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == 1);  //Wait for the end of echo
  
  TIM2->CR1 &= ~0x01; //Stop counter
  
  return (TIM2->CNT) *0.017; //Return distance in milimeter
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  
  /* Initialize PWM */
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
  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);
  
  /* Initialize variables */
  unsigned char carCommand=NULL;  //Command from bluetooth SPP
  unsigned char carMode='A';  //"C" control,"A" autopilot,"T" tracking
  int speed=500;  //Car speed from 0 to 999, low speed (500) for initialization
  TIM3->CCR4=1600;  //Init sonar position
  
  /* Initialize movements */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5 ,GPIO_PIN_SET); //High level for motor controller
  carMoveStop();  //Stop the car for the beginning
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_UART_Receive(&huart1,&carCommand,1,4);  //Receive command from SPP
    
    switch(carCommand)  //Mode selector
    {
      case 'J':
        carMode='C';
        carMoveStop();  //Control Mode init stop
        break;
      case 'K':
        carMode='A';
        break;
      case 'L':
        carMode='T';
      carMoveStop();  //Tracker Mode init stop
        break;
    }
    
    switch(carCommand)  //Speed selector
    {
      case 'Z':
        speed=500;
        break;
      case 'X':
        speed=999;
        break;
    }
    
    if(carMode=='C')  //Control mode
    {
      switch(carCommand)
      {
        case 'W':
          carMoveForward(999);
          delay_ms(100);
          carMoveForward(speed);
          break;
        case 'S':
          carMoveBackward(999);
          delay_ms(100);
          carMoveBackward(speed);
          break;
        case 'A':
          carMoveForward(999);
          delay_ms(100);
          carMoveLeft(speed);
          break;
        case 'D':
          carMoveForward(999);
          delay_ms(100);
          carMoveRight(speed);
          break;
        case 'F':
          carMoveStop();
          break;
      }
    }
    
    if(carMode=='A')  //Autopilot mode
    {
      carMoveForward(999);  //Init forward, los los los!
      
      
      /* Corner Scan */
      if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11))
      {
        carMoveBackward(999);
        delay_ms(300);
        carMoveLeft(999);
        delay_ms(450);
      }
      if(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_10))
      {
        carMoveBackward(999);
        delay_ms(300);
        carMoveRight(999);
        delay_ms(450);
      }
      
      
      /* Sector Scan */
      for(int i=1600;i<=2350;i+=50) //Scan from front to left
      {
        if(obstDist()<=20)  break;
        delay_ms(5);
        TIM3->CCR4=i;
      }
      for(int i=2350;i>=850;i-=50)  //Scan from left to right
      {
        if(obstDist()<=20)  break;
        delay_ms(5);
        TIM3->CCR4=i;
      }
      for(int i=850;i<=1600;i+=50)  //Scan from right to front
      {
        if(obstDist()<=20)  break;
        delay_ms(5);
        TIM3->CCR4=i;
      }
      
      /* If Sector Scan Detected Obstacle */
      if(obstDist()<=20)
      {
        carMoveBackward(999);
        delay_ms(200);
        carMoveStop();
        delay_ms(100);
        
        float l,r; //check left 50 and right 50 angle obstacle
        TIM3->CCR4=1900; //left 50
        delay_ms(50);
        l=obstDist();
        delay_ms(50);
        TIM3->CCR4=1300; //right 50
        delay_ms(50);
        r=obstDist();
        delay_ms(50);
        TIM3->CCR4=1600;
        
        if(l<r) //If left obstacle nearer than right
        {
          carMoveBackward(999);
          delay_ms(300);
          carMoveRight(999);
          delay_ms(600);
        }
        else if(l>r)  //right > left
        {
          carMoveBackward(999);
          delay_ms(300);
          carMoveLeft(999);
          delay_ms(600);
        }
        else  //Same distance, default turn left
        {
          carMoveBackward(999);
          delay_ms(300);
          carMoveLeft(999);
          delay_ms(600);
        }
      }
    }
    
    if(carMode=='T')  //Tracker mode
    {
      if((!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15))&&(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14))&&(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13))&&(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)))
      {
        carMoveForward(999);
      }
      if((!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14))&&(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13)))
      {
        carMoveLeft2(999);
      }
      if((!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15))&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)))
      {
        carMoveLeft2(999);
      }
      if((HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13)))
      {
        carMoveRight2(999);
      }
      if((HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15))&&(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)))
      {
        carMoveRight2(999);
      }
      if((!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13))&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)))
      {
        carMoveLeft2(999);
        delay_ms(20);
        carMoveForward(999);
        delay_ms(50);
      }
      if((HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13))&&(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)))
      {
        carMoveRight2(999);
        delay_ms(20);
        carMoveForward(999);
        delay_ms(50);
      }
      if((!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14))&&(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13))&&(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12)))
      {
        carMoveBackward(999);
        delay_ms(100);
      }   
    }
    
    carCommand=NULL;  //Reset command
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  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();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  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();
  }
}

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 71;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 65535;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 71;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 1999;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 500;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);

}

/**
  * @brief TIM4 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM4_Init(void)
{

  /* USER CODE BEGIN TIM4_Init 0 */

  /* USER CODE END TIM4_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM4_Init 1 */

  /* USER CODE END TIM4_Init 1 */
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 71;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 999;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM4_Init 2 */

  /* USER CODE END TIM4_Init 2 */
  HAL_TIM_MspPostInit(&htim4);

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  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;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, SONAR_TRIG_Pin|MOTOR_SW_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : LH_Pin SONAR_ECHO_Pin X3_Pin X2_Pin
                           X1_Pin */
  GPIO_InitStruct.Pin = LH_Pin|SONAR_ECHO_Pin|X3_Pin|X2_Pin
                          |X1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : SONAR_TRIG_Pin MOTOR_SW_Pin */
  GPIO_InitStruct.Pin = SONAR_TRIG_Pin|MOTOR_SW_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);

  /*Configure GPIO pins : RH_Pin X4_Pin */
  GPIO_InitStruct.Pin = RH_Pin|X4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

实践问题及解决方式

问题:小车无法直接低速启动。

解决方法:

先在对应的方向上将马达PWM控制拉到满速,持续很短一段时间(足以让小车起动)后再转入低速。经过实操,这个满速过程可以在20-50ms内完成。


问题:在不同模式间切换时,出现了切换过程中车子失控的问题。

解决方法:

在模式切换进行时,立即对马达控制的四个引脚全部输出低电平,使小车停下。


问题:在小车前进过程中,因车轮一致性不足导致的行进轨迹按固定方向偏移。

解决方法:

编写carMoveForward函数时,对左右两侧控制的PWM进行微调,使其路线趋向平直。


问题:小车循迹遇到极端路段容易冲出线路。

解决方法:

1.可以尝试降低巡航时的车速。

2.可以将差速转向改为原地转向。

3.在检测冲出时进行短时间后退重新进入轨道。

体会及收获

通过此次课程设计,本人在实践中学习了嵌入式开发的相关知识,较在校学习的其他必修课程中扩展学习了更多方向的实践知识,并与之前的理论知识灵活结合。

在此过程中,不仅巩固了以往既有的一些硬件知识和编程技能,更是联系实际开发环境、学习知识之余,培养了自己的动手能力。

本站作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

评论

  1. Macintosh Chrome
    2 年前
    2022-8-08 15:45:57

    围观硬件大佬

    • Dana
      博主
      大雄
      Windows Firefox
      已编辑
      2 年前
      2022-8-08 17:37:09

      只是跟着学校要求做的而已∠( ᐛ 」∠)_完成了要求的内容
      (顺便一提,互换友链整一个不

      • Dana
        Macintosh Chrome
        2 年前
        2022-8-09 10:14:48

        你这么靓仔可以的,来加上吧

        • Dana
          博主
          大雄
          Windows Firefox
          2 年前
          2022-8-09 16:06:03

          链接已经加上了,友链页面可见
          说是大佬真不敢当,我这边网站的描述按照说明改一下就可以啦∠( ᐛ 」∠)_

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇