天天看点

STM32F407 直流有刷电机PID位置环控制

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

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

#include "bsp_delay.h"
#include "bsp_key.h"
#include "bsp_motor.h"
#include "bsp_usart.h"
#include "bsp_pid.h"

/* 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 htim1;
TIM_HandleTypeDef htim3;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

uint16_t g_encoder_update_cnt = 0;
int32_t pos_current;							/* 单位:0.001r */

/* USER CODE END PV */

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

/* USER CODE END PFP */

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

/* 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_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
	
	delay_init(168);
	
	usart_init();
	pid_init();
	
	__HAL_TIM_SET_COUNTER(&htim3, 0);
	__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);
	__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
	HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
	
	
	int32_t velocity_current;				/* 单位:0.001r/min */
	
	uint8_t buffer_usart_send[16];
	uint32_t tick;
	uint16_t sum;
	uint8_t i;
	uint8_t run = 0;	
	uint32_t tick_start_run;	/* 开始运行时刻 */
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		usart_task();
		
		if(KEY1_StateRead()==KEY_DOWN)
    {
			__HAL_TIM_SET_COUNTER(&htim1, 0);
			HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
			HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
			
			run = 1;
    }
		
		if (run)
		{
			pid_ctrl(get_pid_pos().target);
		}
		
		if (run)
		{
			pos_current = ((int32_t)(g_encoder_update_cnt * (htim3.Init.Period + 1) + __HAL_TIM_GET_COUNTER(&htim3))) * 1.0 / STEP_ENCODER_CIRCLE * 1000;
			velocity_current = get_velocity_current() * 1000;
			tick = HAL_GetTick();
			
			buffer_usart_send[0] = 0x01;																/* 帧头 */
			buffer_usart_send[1] = 0x67;																/* 帧头 */	
			buffer_usart_send[2] = 0x42;																/* 帧头 */
			buffer_usart_send[3] = 0xc0;																/* 帧头 */
			buffer_usart_send[4] = (tick - tick_start_run) >> 8;				/* 时刻 */
			buffer_usart_send[5] = (tick - tick_start_run) & 0xff;			/* 时刻 */
			buffer_usart_send[6] = pos_current >> 24;										/* 电机位置,0.001r */
			buffer_usart_send[7] = pos_current >> 16;										/* 电机位置,0.001r */
			buffer_usart_send[8] = pos_current >> 8;										/* 电机位置,0.001r */
			buffer_usart_send[9] = pos_current & 0xff;									/* 电机位置,0.001r */
			buffer_usart_send[10] = velocity_current >> 24;							/* 编码器速度,0.001r/min */
			buffer_usart_send[11] = velocity_current >> 16;							/* 编码器速度,0.001r/min */
			buffer_usart_send[12] = velocity_current >> 8;							/* 编码器速度,0.001r/min */
			buffer_usart_send[13] = velocity_current & 0xff;						/* 编码器速度,0.001r/min */
			
			sum = 0;
			for (i = 4; i < 14; i++)
			{
				sum += buffer_usart_send[i];
			}
			buffer_usart_send[14] = sum >> 8;
			buffer_usart_send[15] = sum & 0xff;
			
			HAL_UART_Transmit(&huart1, buffer_usart_send, 16, 1000);
			
			//delay_ms(10);
		}
		else
		{
			tick_start_run = HAL_GetTick();
		}
		
    /* 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};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** 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.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  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_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief TIM1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

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

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 20;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 10000;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 5000;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_LOW;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}

/**
  * @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_Encoder_InitTypeDef sConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 65535;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter = 0;
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC2Filter = 0;
  if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */

}

/**
  * @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 = 115200;
  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_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOF, GPIO_PIN_11, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11|GPIO_PIN_3|GPIO_PIN_7, GPIO_PIN_RESET);

  /*Configure GPIO pins : PE2 PE3 PE4 PE0
                           PE1 */
  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_0
                          |GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pin : PF11 */
  GPIO_InitStruct.Pin = GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /*Configure GPIO pins : PD11 PD3 PD7 */
  GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_3|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOD, &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 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

           
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32f4xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "bsp_motor.h"
#include "bsp_usart_host.h"

/* USER CODE END Includes */

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

/* USER CODE END TD */

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

/* USER CODE END PD */

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

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

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

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim3;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Pre-fetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */

  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f4xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles TIM3 global interrupt.
  */
void TIM3_IRQHandler(void)
{
  /* USER CODE BEGIN TIM3_IRQn 0 */

  /* USER CODE END TIM3_IRQn 0 */
  HAL_TIM_IRQHandler(&htim3);
  /* USER CODE BEGIN TIM3_IRQn 1 */

  /* USER CODE END TIM3_IRQn 1 */
}

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

/* USER CODE BEGIN 1 */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim == &htim3)
	{
		if (__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3))
		{
			g_encoder_update_cnt--;
		}
		else
		{
			g_encoder_update_cnt++;
		}
	}
}

/**
* @brief usart接收中断处理回调函数
* @param huart 指针,指向产生中断的huart
* @note: 
* @retval 无
*/	
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &HUSART_HOST)
	{
		usart_wr_rxfifo_host(&g_usart_host_rx_data, 1);
		HAL_UART_Receive_IT(huart, &g_usart_host_rx_data, 1);
	}
}

/**
* @brief 如果usart产生错误中断,重新初始化usart
* @param huart 指针,指向产生中断的huart
* @note: 
* @retval 无
*/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if(huart == &HUSART_HOST)
	{
		host_usart1_uart_init();
	}
}

/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

           
/**
******************************************************************************
* @file bsp_pid.c
* @author 
* @version V1.0
* @date 
* @brief 
* @others 
* @copyright 
******************************************************************************
* @history
*
* 1.date	
*		author	
*		modification
*
******************************************************************************
*/

#include "bsp_pid.h"
#include "bsp_motor.h"

/*static*/ pid_typedef s_pos_pid;
/*static*/ pid_typedef s_velocity_pid; 

/*static*/ double s_velocity_current;	/* 单位:r/min	 */



/**
* @brief 协议帧校验
* @param data 指针,指向接收到数据的数组
* @param len 数组data长度
* @note: 
* @retval 0:执行成功
*					1:执行失败
*/	
uint8_t pid_init(void)
{
	s_pos_pid.target = 50;	/* 单位:mm */
	s_pos_pid.p = 0.06;	
	s_pos_pid.i = 0;	
	s_pos_pid.d = 0;	
	
	s_velocity_pid.target = 5;	/* 单位:r/min */
	s_velocity_pid.p = 0.11;	
	s_velocity_pid.i = 0.12;	
	s_velocity_pid.d = 0.03;	
	
	return 0;
}

/**
* @brief 增量式PID速度环计算
* @param current_val 当前值
* @param target_val 目标值
* @note: 
* @retval 经过PID运算得到的增量值
*/	
double inc_pid_calc_velocity(double current_val, double target_val)       
{
  double error = 0;                       /* 当前误差 */
	static double inc_pid = 0;
	static double last_error = 0;
	static double prev_error = 0;
	
  error = target_val - current_val;                   /* 增量计算 */
                                        
  inc_pid += (s_velocity_pid.p * (error - last_error))                  /* E[k]项 */
					+ (s_velocity_pid.i * error)       			/* E[k-1]项 */
					+ (s_velocity_pid.d * (error - 2 * last_error + prev_error));    				/* E[k-2]项 */
  
  prev_error = last_error;                      			/* 存储误差,用于下次计算 */
  last_error = error;
	
  return inc_pid;                                    	/* 返回增量值 */
}

/**
* @brief 位置式PID速度环计算
* @param current_val 当前值
* @param target_val 目标值
* @note: 
* @retval 经过PID运算得到的增量值
*/	
double pos_pid_calc_velocity(double current_val, double target_val)       
{
  double error = 0;                       /* 当前误差 */
	static double pos_pid = 0;
	static double last_error = 0;
	static double sum_error = 0;
	
  error = target_val - current_val;                   /* 增量计算 */
	sum_error += error;
                                        
  pos_pid = (s_velocity_pid.p * error)                  /* E[k]项 */
					+ (s_velocity_pid.i * sum_error)       			/* E[k-1]项 */
					+ (s_velocity_pid.d * (error - last_error));    				/* E[k-2]项 */

  last_error = error;
	
  return pos_pid;                                    	/* 返回增量值 */
}

/**
* @brief 增量式PID速度环计算
* @param current_val 当前值
* @param target_val 目标值
* @note: 
* @retval 经过PID运算得到的增量值
*/	
double inc_pid_calc_pos(double current_val, double target_val)       
{
  double error = 0;                       /* 当前误差 */
	static double inc_pid = 0;
	static double last_error = 0;
	static double prev_error = 0;
	
  error = target_val - current_val;                   /* 增量计算 */
                                        
  inc_pid += (s_pos_pid.p * (error - last_error))                  /* E[k]项 */
					+ (s_pos_pid.i * error)       			/* E[k-1]项 */
					+ (s_pos_pid.d * (error - 2 * last_error + prev_error));    				/* E[k-2]项 */
  
  prev_error = last_error;                      			/* 存储误差,用于下次计算 */
  last_error = error;
	
  return inc_pid;                                    	/* 返回增量值 */
}

double velocity_arr_current;
int16_t pwm = 5000;

/**
* @brief PID控制
* @param target_val 目标值,单位:r
* @note: 
* @retval 
*/	
uint8_t pid_ctrl(double target_val)   
{
	static uint32_t tick_old = 0; 
	uint32_t tick_current;
	static int32_t encoder_step_new = 0;
	static int32_t	encoder_step_old = 0;
	double inc_val_step_encoder;	/* 增量值 */
	
	tick_current = HAL_GetTick();
	if (tick_current - tick_old > 200)
	{
		encoder_step_new = g_encoder_update_cnt * (htim3.Init.Period + 1) + __HAL_TIM_GET_COUNTER(&htim3);
		s_velocity_current = (encoder_step_new - encoder_step_old) * 1.0 / STEP_ENCODER_CIRCLE  * 60000 / (tick_current - tick_old);	/* 电机速度,单位r/min */
		inc_val_step_encoder = inc_pid_calc_pos(encoder_step_new * 1.0 / STEP_ENCODER_CIRCLE, target_val);  

		if (inc_val_step_encoder > 10000)
		{
			inc_val_step_encoder = 10000;
		}
		else if (inc_val_step_encoder < -10000)
		{
			inc_val_step_encoder = -10000;
		}
    
		pwm -= inc_val_step_encoder;      /* 下一个周期PWM */
		
		if (pwm > 10000)
		{
			pwm = 10000;
		}
		else if (pwm < 0)
		{
			pwm = 0;
		}
		
		__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pwm);
		
		encoder_step_old = encoder_step_new;
		tick_old = tick_current;
	}
	
	return 0;
}

/**
* @brief 获取位置PID参数
* @note: 
* @retval 
*/	
pid_typedef get_pid_pos(void)
{
	return s_pos_pid;
}

/**
* @brief 设置位置PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_pos_target(float target)
{
	s_pos_pid.target = target;
	
	return 0;
}

/**
* @brief 设置位置PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_pos_p(float p)
{
	s_pos_pid.p = p;
	
	return 0;
}

/**
* @brief 设置位置PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_pos_i(float i)
{
	s_pos_pid.i = i;
	
	return 0;
}

/**
* @brief 设置位置PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_pos_d(float d)
{
	s_pos_pid.d = d;
	
	return 0;
}

/**
* @brief 获取速度PID参数
* @note: 
* @retval 
*/	
pid_typedef get_pid_velocity(void)
{
	return s_velocity_pid;
}

/**
* @brief 获取速度PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_velocity_target(float target)
{
	s_velocity_pid.target = target;
	
	return 0;
}

/**
* @brief 获取速度PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_velocity_p(float p)
{
	s_velocity_pid.p = p;
	
	return 0;
}

/**
* @brief 获取速度PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_velocity_i(float i)
{
	s_velocity_pid.i = i;
	
	return 0;
}

/**
* @brief 获取速度PID参数
* @note: 
* @retval 
*/	
uint8_t set_pid_velocity_d(float d)
{
	s_velocity_pid.d = d;
	
	return 0;
}

/**
* @brief 获取实时速度,单位:r/min
* @note: 
* @retval 
*/	
double get_velocity_current(void)
{
	return s_velocity_current;
}




           

总结:

1、

STM32F407 直流有刷电机PID位置环控制

2、

STM32F407 直流有刷电机PID位置环控制

3、

STM32F407 直流有刷电机PID位置环控制

4、

STM32F407 直流有刷电机PID位置环控制

5、

STM32F407 直流有刷电机PID位置环控制

6、

STM32F407 直流有刷电机PID位置环控制

7、

STM32F407 直流有刷电机PID位置环控制

8、

STM32F407 直流有刷电机PID位置环控制

9、

STM32F407 直流有刷电机PID位置环控制

10、

STM32F407 直流有刷电机PID位置环控制

11、

STM32F407 直流有刷电机PID位置环控制

12、

STM32F407 直流有刷电机PID位置环控制

13、

STM32F407 直流有刷电机PID位置环控制

14、

STM32F407 直流有刷电机PID位置环控制

15、

STM32F407 直流有刷电机PID位置环控制

16、

STM32F407 直流有刷电机PID位置环控制

17、

STM32F407 直流有刷电机PID位置环控制