Skip to main content
Associate
April 27, 2025
Question

STM32H743 BLDC use Hallsensor get speed(HAL)

  • April 27, 2025
  • 1 reply
  • 468 views

LED1_TOGGLE();cant run when i start BLDC. can someone solve it? status of HAL_TIMEx_HallSensor_Start_DMA is OK and Mspinit is OK.

void hall_init(void)
{
 __HAL_RCC_DMA1_CLK_ENABLE();
 __HAL_LINKDMA(&g_htimx_handle, hdma[TIM_DMA_ID_CC1], g_hall_dma_handle);
 
 g_hall_dma_handle.Instance = DMA1_Stream5;
 g_hall_dma_handle.Init.Request = DMA_REQUEST_TIM5_CH1;
 g_hall_dma_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
 g_hall_dma_handle.Init.MemInc = DMA_MINC_ENABLE;
 g_hall_dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;
 g_hall_dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 g_hall_dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 g_hall_dma_handle.Init.Priority = DMA_PRIORITY_HIGH;
 g_hall_dma_handle.Init.Mode = DMA_CIRCULAR;
 g_hall_dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 g_hall_dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 g_hall_dma_handle.Init.MemBurst = DMA_MBURST_SINGLE;
 g_hall_dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
 HAL_DMA_Init(&g_hall_dma_handle);

 HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 1, 1);
 HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 __HAL_DMA_ENABLE_IT(&g_hall_dma_handle, DMA_IT_TC);
 
 TIM_HallSensor_InitTypeDef hall_tim_handle = {0};
 
 g_htimx_handle.Instance = TIM5;
 g_htimx_handle.Init.Period = HALL_ARR;
 g_htimx_handle.Init.Prescaler = 200-1;
 g_htimx_handle.Init.RepetitionCounter = 0;
 g_htimx_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
 g_htimx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
 g_htimx_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 hall_tim_handle.Commutation_Delay = 1;
 hall_tim_handle.IC1Prescaler = TIM_ICPSC_DIV1;
 hall_tim_handle.IC1Filter = 15;
 hall_tim_handle.IC1Polarity = TIM_ICPOLARITY_FALLING;
 HAL_TIMEx_HallSensor_Init(&g_htimx_handle, &hall_tim_handle);
 HAL_TIMEx_HallSensor_Start_DMA(&g_htimx_handle, (uint32_t *)g_encoder_data, 1);
}

void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
{
 if(htim->Instance == TIM5)
 {
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_TIM5_CLK_ENABLE();
 
 GPIO_InitTypeDef gpio_init_struct = {0};
 gpio_init_struct.Pin = GPIO_PIN_10;
 gpio_init_struct.Mode = GPIO_MODE_INPUT;
 gpio_init_struct.Pull = GPIO_PULLUP;
 gpio_init_struct.Alternate = GPIO_AF2_TIM5;
 HAL_GPIO_Init(GPIOH, &gpio_init_struct);
 
 gpio_init_struct.Pin = GPIO_PIN_11;
 HAL_GPIO_Init(GPIOH, &gpio_init_struct);
 
 gpio_init_struct.Pin = GPIO_PIN_12;
 HAL_GPIO_Init(GPIOH, &gpio_init_struct);
 }
}

void DMA1_Stream5_IRQHandler(void)
{
 LED1_TOGGLE();
 if(__HAL_DMA_GET_FLAG(&g_hall_dma_handle, DMA_FLAG_TCIF1_5) != RESET)
 {
 HAL_DMA_IRQHandler(&g_hall_dma_handle);
 }
}

 

1 reply

MM..1
Chief III
April 27, 2025

Are you sure breakpoint on line toggle not break ? 

Associate
April 27, 2025

i am sure. no break. but mu ADC code can. they are similar. it  is my  first time use HAL_TIMEx_HallSensor_Start_DMA on H743

#include "./BSP/ADC/adc.h"

ADC_HandleTypeDef g_adc_handle = {0};
DMA_HandleTypeDef g_adc_dma_handler = {0};
volatile uint16_t g_adc_dma_buf[ADC_DMA_BUF_SIZE] = {0};
volatile uint16_t g_adc_val[ADC_CH_NUM] = {0};

void adc_init(void)
{
 __HAL_RCC_DMA1_CLK_ENABLE();

 __HAL_LINKDMA(&g_adc_handle, DMA_Handle, g_adc_dma_handler);

 g_adc_dma_handler.Instance = DMA1_Stream6;
 g_adc_dma_handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
 g_adc_dma_handler.Init.Request = 9;
 g_adc_dma_handler.Init.PeriphInc = DMA_PINC_DISABLE;
 g_adc_dma_handler.Init.MemInc = DMA_MINC_ENABLE;
 g_adc_dma_handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 g_adc_dma_handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 g_adc_dma_handler.Init.Mode = DMA_CIRCULAR;
 g_adc_dma_handler.Init.Priority = DMA_PRIORITY_HIGH;
 HAL_DMA_Init(&g_adc_dma_handler);
 
 HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 2, 1);
 HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
 __HAL_DMA_ENABLE_IT(&g_adc_dma_handler, DMA_IT_TC);
 
 g_adc_handle.Instance = ADC1;
 g_adc_handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
 g_adc_handle.Init.Resolution = ADC_RESOLUTION_16B;
 g_adc_handle.Init.EOCSelection = ADC_EOC_SEQ_CONV;
 g_adc_handle.Init.ScanConvMode = ADC_SCAN_ENABLE;
 g_adc_handle.Init.NbrOfConversion = ADC_CH_NUM;
 g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 g_adc_handle.Init.ContinuousConvMode = ENABLE;
 g_adc_handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
 g_adc_handle.Init.DiscontinuousConvMode = DISABLE;
 g_adc_handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
 g_adc_handle.Init.OversamplingMode = DISABLE;
 g_adc_handle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
 HAL_ADC_Init(&g_adc_handle);
 
 HAL_ADCEx_Calibration_Start(&g_adc_handle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);

 ADC_ChannelConfTypeDef adc_ch_conf;
 adc_ch_conf.Channel = ADC_CHANNEL_14;//PA2电压
 adc_ch_conf.Rank = ADC_REGULAR_RANK_1;
 adc_ch_conf.SingleDiff = ADC_SINGLE_ENDED;
 adc_ch_conf.Offset = 0;
 adc_ch_conf.OffsetNumber = ADC_OFFSET_NONE;
 adc_ch_conf.OffsetRightShift = DISABLE;
 adc_ch_conf.OffsetSignedSaturation = DISABLE;
 adc_ch_conf.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
 HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);
 
 adc_ch_conf.Channel = ADC_CHANNEL_15;//PA3温度
 adc_ch_conf.Rank = ADC_REGULAR_RANK_2;
 HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);
 
 adc_ch_conf.Channel = ADC_CHANNEL_17;//PA1电流u
 adc_ch_conf.Rank = ADC_REGULAR_RANK_3;
 HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);
 
 adc_ch_conf.Channel = ADC_CHANNEL_18;//PA4电流v
 adc_ch_conf.Rank = ADC_REGULAR_RANK_4;
 HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);
 
 adc_ch_conf.Channel = ADC_CHANNEL_19;//PA5电流w
 adc_ch_conf.Rank = ADC_REGULAR_RANK_5;
 HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);
 
 HAL_ADC_Start_DMA(&g_adc_handle, (uint32_t *)g_adc_dma_buf, ADC_DMA_BUF_SIZE);
}

void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
 if(hadc->Instance == ADC1)
 {
 GPIO_InitTypeDef gpio_init_struct;
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_ADC12_CLK_ENABLE();
 
 gpio_init_struct.Pin = GPIO_PIN_1;
 gpio_init_struct.Mode = GPIO_MODE_ANALOG;
 HAL_GPIO_Init(GPIOA, &gpio_init_struct);

 gpio_init_struct.Pin = GPIO_PIN_2;
 HAL_GPIO_Init(GPIOA, &gpio_init_struct);
 
 gpio_init_struct.Pin = GPIO_PIN_3;
 HAL_GPIO_Init(GPIOA, &gpio_init_struct);
 
 gpio_init_struct.Pin = GPIO_PIN_4;
 HAL_GPIO_Init(GPIOA, &gpio_init_struct);
 
 gpio_init_struct.Pin = GPIO_PIN_5;
 HAL_GPIO_Init(GPIOA, &gpio_init_struct);
 
 RCC_PeriphCLKInitTypeDef adc_clk_init = {0};
 adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC;
 adc_clk_init.PLL2.PLL2M = 25;
 adc_clk_init.PLL2.PLL2N = 504;
 adc_clk_init.PLL2.PLL2P = 7;
 adc_clk_init.PLL2.PLL2Q = 7;
 adc_clk_init.PLL2.PLL2R = 7;
 adc_clk_init.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
 adc_clk_init.PLL2.PLL2FRACN = 0;
 adc_clk_init.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
 adc_clk_init.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
 HAL_RCCEx_PeriphCLKConfig(&adc_clk_init);
 }
}

void DMA1_Stream6_IRQHandler(void)
{
 if(__HAL_DMA_GET_FLAG(&g_adc_dma_handler, DMA_FLAG_TCIF2_6) != RESET)
 {
 HAL_DMA_IRQHandler(&g_adc_dma_handler);
 }
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
 if(hadc->Instance == ADC1)
 {
 HAL_ADC_Stop_DMA(&g_adc_handle);
 calc_adc_val((uint16_t *)(volatile void *)g_adc_val);
 HAL_ADC_Start_DMA(&g_adc_handle, (uint32_t *)g_adc_dma_buf, ADC_DMA_BUF_SIZE);
 }
}

void calc_adc_val(uint16_t *p)
{
 uint32_t temp[ADC_CH_NUM] ={0};
 int i,j;
 for(i=0;i<ADC_COLL;i++)
 {
 for(j=0;j<ADC_CH_NUM;j++)
 {
 temp[j] += g_adc_dma_buf[j+i*ADC_CH_NUM];
 }
 }
 for(j=0;j<ADC_CH_NUM;j++)
 {
 temp[j] /= ADC_COLL;
 p[j] = temp[j];
 }
}

 

MM..1
Chief III
April 27, 2025

Check startup files if your 

DMA1_Stream5_IRQHandler

realy exist i mean no. On ADC you use too HAL right cb for ADC and this works, but DMA too maybe no.
Your code you manage in MX ? And too check if TIM5 is connected to Stream5 DMA.

Example for is maybe

void HAL_TIMEx_HallSensor_DMAFullCpltCallback(TIM_HandleTypeDef *htim) {
 // Full buffer processed
}

 and use DMA for buffer with size 1 is ...