STM32F407 互补PWM驱动BLDC

/* 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_hall.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 htim5;
TIM_HandleTypeDef htim8;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM8_Init(void);
static void MX_TIM5_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_TIM8_Init();
  MX_TIM5_Init();
  /* USER CODE BEGIN 2 */
	
	delay_init(168);
	
	motor_phase_ctrl(get_hall_phase());
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		
    /* 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 TIM5 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM5_Init(void)
{

  /* USER CODE BEGIN TIM5_Init 0 */

  /* USER CODE END TIM5_Init 0 */

  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};

  /* USER CODE BEGIN TIM5_Init 1 */

  /* USER CODE END TIM5_Init 1 */
  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 0;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 4294967295;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
  sSlaveConfig.InputTrigger = TIM_TS_TI1F_ED;
  sSlaveConfig.TriggerFilter = 0;
  if (HAL_TIM_SlaveConfigSynchro(&htim5, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_TRC;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  if (HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_ConfigTI1Input(&htim5, TIM_TI1SELECTION_XORCOMBINATION) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM5_Init 2 */
	
	HAL_TIM_IC_Start_IT(&htim5, TIM_CHANNEL_1);

  /* USER CODE END TIM5_Init 2 */

}

/**
  * @brief TIM8 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM8_Init(void)
{

  /* USER CODE BEGIN TIM8_Init 0 */

  /* USER CODE END TIM8_Init 0 */

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

  /* USER CODE BEGIN TIM8_Init 1 */

  /* USER CODE END TIM8_Init 1 */
  htim8.Instance = TIM8;
  htim8.Init.Prescaler = 0;
  htim8.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
  htim8.Init.Period = 4200;
  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim8.Init.RepetitionCounter = 0;
  htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim8) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 3000;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 50;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM8_Init 2 */
	
	HAL_TIMEx_ConfigCommutationEvent(&htim8, TIM_TS_NONE, TIM_COMMUTATION_SOFTWARE);

  /* USER CODE END TIM8_Init 2 */
  HAL_TIM_MspPostInit(&htim8);

}

/**
  * @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_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOI_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****/

#include "bsp_motor.h"

void BLDCMOTOR_TIM_CHx_MODE(TIM_HandleTypeDef *htim, uint32_t OCMode, uint32_t CHx);

#define BLDCMOTOR_TIM_CH1_PORT                GPIOI          // TIM8_CH1的引脚
#define BLDCMOTOR_TIM_CH1_PIN                 GPIO_PIN_5
#define BLDCMOTOR_TIM_CH1                     TIM_CHANNEL_1

#define BLDCMOTOR_TIM_CH2_PORT                GPIOI          // TIM8_CH2的引脚
#define BLDCMOTOR_TIM_CH2_PIN                 GPIO_PIN_6
#define BLDCMOTOR_TIM_CH2                     TIM_CHANNEL_2

#define BLDCMOTOR_TIM_CH3_PORT                GPIOI          // TIM8_CH3的引脚
#define BLDCMOTOR_TIM_CH3_PIN                 GPIO_PIN_7
#define BLDCMOTOR_TIM_CH3                     TIM_CHANNEL_3

#define htimx_BLDCM htim8

void set_tim_pwm_mode(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t OCMode, uint32_t ChannelState, uint32_t ChannelNState)
{
	assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
  assert_param(IS_TIM_PWM_MODE(sConfig->OCMode));
	
	uint32_t tmpccmrx;
	uint32_t tmp;
	
	switch (Channel)
	{
		case TIM_CHANNEL_1:
		{
			/* Get the TIMx CCMR1 register value */
			tmpccmrx = htim->Instance->CCMR1;
			/* Reset the Output Compare Mode Bits */
			tmpccmrx &= ~TIM_CCMR1_OC1M;
			tmpccmrx &= ~TIM_CCMR1_CC1S;
			/* Select the Output Compare Mode */
			tmpccmrx |= OCMode;
			htim->Instance->CCMR1 = tmpccmrx;
			
			tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
			/* Reset the CCxE Bit */
			htim->Instance->CCER &= ~tmp;
			/* Set or reset the CCxE Bit */
			htim->Instance->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
			
			tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
			/* Reset the CCxNE Bit */
			htim->Instance->CCER &=  ~tmp;
			/* Set or reset the CCxNE Bit */
			htim->Instance->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
			break;
		}
		
		case TIM_CHANNEL_2:
		{
			/* Get the TIMx CCMR1 register value */
			tmpccmrx = htim->Instance->CCMR1;
			/* Reset the Output Compare mode and Capture/Compare selection Bits */
			tmpccmrx &= ~TIM_CCMR1_OC2M;
			tmpccmrx &= ~TIM_CCMR1_CC2S;
			/* Select the Output Compare Mode */
			tmpccmrx |= (OCMode << 8U);
			htim->Instance->CCMR1 = tmpccmrx;
			
			tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
			/* Reset the CCxE Bit */
			htim->Instance->CCER &= ~tmp;
			/* Set or reset the CCxE Bit */
			htim->Instance->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
			
			tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
			/* Reset the CCxNE Bit */
			htim->Instance->CCER &=  ~tmp;
			/* Set or reset the CCxNE Bit */
			htim->Instance->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
			break;
		}
		
		case TIM_CHANNEL_3:
		{
			/* Get the TIMx CCMR2 register value */
			tmpccmrx = htim->Instance->CCMR2;
			/* Reset the Output Compare mode and Capture/Compare selection Bits */
			tmpccmrx &= ~TIM_CCMR2_OC3M;
			tmpccmrx &= ~TIM_CCMR2_CC3S;
			/* Select the Output Compare Mode */
			tmpccmrx |= OCMode;
			htim->Instance->CCMR2 = tmpccmrx;
			
			tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
			/* Reset the CCxE Bit */
			htim->Instance->CCER &= ~tmp;
			/* Set or reset the CCxE Bit */
			htim->Instance->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
			
			tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
			/* Reset the CCxNE Bit */
			htim->Instance->CCER &=  ~tmp;
			/* Set or reset the CCxNE Bit */
			htim->Instance->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
			break;
		}
		
		default:
      break;
	}
}

/* 相位控制 */
void motor_phase_ctrl(uint8_t num)
{
	if (num > 6)
	{
		return;
	}
	
	
		switch (num)
	{
		case 5: //B+  A-
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM1, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM2, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM2, TIM_CCx_DISABLE, TIM_CCxN_DISABLE);
		break;
		
		case 4:// C+ A-
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM1, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM2, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM2, TIM_CCx_DISABLE, TIM_CCxN_DISABLE);
		break;
		
		case 6://C+ B-
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM1, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM2, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM2, TIM_CCx_DISABLE, TIM_CCxN_DISABLE);
		break;
		
		case 2: // A+ B-
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM1, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM2, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM2, TIM_CCx_DISABLE, TIM_CCxN_DISABLE);
		break;
		
		case 3:// A+ C-
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM1, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM2, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM2, TIM_CCx_DISABLE, TIM_CCxN_DISABLE);
		break;
		
		case 1: // B+ C-
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_2, TIM_OCMODE_PWM1, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_3, TIM_OCMODE_PWM2, TIM_CCx_ENABLE, TIM_CCxN_ENABLE);
			set_tim_pwm_mode(&htim8, TIM_CHANNEL_1, TIM_OCMODE_PWM2, TIM_CCx_DISABLE, TIM_CCxN_DISABLE);
		break;
	}

	__HAL_TIM_MOE_ENABLE(&htim8);
	__HAL_TIM_ENABLE(&htim8);
	HAL_TIM_GenerateEvent(&htim8, TIM_EVENTSOURCE_COM);
}


#include "bsp_hall.h"
#include "bsp_motor.h"

uint8_t get_hall_phase(void)
{
	uint8_t tmp = 0;
	
	tmp |= (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_10));
	tmp <<= 1;
	tmp |= (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_11));
	tmp <<= 1;
	tmp |= (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_12));
	
	return tmp;
}

/**
  * @brief  Input Capture callback in non-blocking mode
  * @param  htim TIM IC handle
  * @retval None
  */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (htim == &htim5)
	{
		motor_phase_ctrl(get_hall_phase());
	}
}



总结:
1、HALL传感器通过TIM5捕获,BLDC由TIM8输出PWM互补信号驱动
2、将HALL传感器信号接入主控板,手动转动BLDC,逻辑分析仪捕获PWM互补输出信号
在这里插入图片描述

在这里插入图片描述
3、
在这里插入图片描述
4、
在这里插入图片描述
5、
在这里插入图片描述
6、
在这里插入图片描述
7、
在这里插入图片描述
8、
在这里插入图片描述
9、
在这里插入图片描述
10、
在这里插入图片描述
11、
在这里插入图片描述
12、
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值