2021-07-12 11:13 PM
Sorry for my bad English. I am using NUCLEO STM32H743ZI2 with ADC multi-channel. I am using 3ADC: ADC 1, 2, and 3 independent mode triggered by TIM1CH1
The CPU clock is 400MHz using an external HSE
STM32H7-> The TIM PWM works well, and it can trigger the ADC measurement. ADC can read the value properly, However, the ADC sampling and conversion took a lot of time than expected with around 10us !!! - too long a time. (I selected 1.5cycle)
Compared to TI TMS320F 28379D - with around 1us, the STM32H7 is much slower :(
COULD YOU PLEASE TELL ME WHAT IS MY ISSUE related to the ADC sampling and converting time ??? . I have tried to read many threads on the internet but no hope, disable ADC2 and ADC3 do not improve the performance :(
I have attached the project so you can import the project and see the delay.
TIM1CH1 (the one trigger ADC) : PE9
GPIO used to check the computation time PG12
https://1drv.ms/u/s!AuUAN7PWAxFS8l3wJ1uhJ_1y7zx8?e=jOM8Gd
========================CODE =================
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //
{
if(hadc->Instance == ADC1)
{
if(SW_CASE1==50 )
{TIM1->CCR1 = 0; SW_CASE1=0; } // TESTING
/* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */
if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
{
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12,1); // //GPIO TEST COMPUTATION BURDEN
for (int i =0; i<4; i++) // 4_ADC-> 0,1,2,3
{
adc1_value[i] = ADC_DATA[i];
}
for (int i =0; i<4; i++) // 4_ADC-> 0,1,2,3
{
adc2_value[i] = ADC_DATA_2[i];
}
for (int i =0; i<4; i++) // 4_ADC-> 0,1,2,3
{
adc3_value[i] = ADC_DATA_3[i];
}
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12,0); // //GPIO TEST COMPUTATION BURDEN
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,0); // //GPIO TEST COMPUTATION BURDEN
} // END __HAL_ADC_GET_FLAG
}//END hadc->Instance
} // END HAL_ADC_ConvCpltCallback
void HAL_TIM_PeriodElapsedCallback ( TIM_HandleTypeDef * htim)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,1); // //GPIO TEST COMPUTATION BURDEN
}
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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_ADC3_Init();
MX_SPI1_Init();
MX_SPI3_Init();
MX_SPI4_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM4_Init();
MX_TIM8_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
//=============================================================
//TIM1_CH1
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1); // turn on complementary channel
//TIM1_CH2
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2); // turn on complementary channel
//TIM1_CH3
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3); // turn on complementary channel
//=============================================================
//TIM8_CH1
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_1); // turn on complementary channel
//TIM8_CH2
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_2); // turn on complementary channel
//TIM8_CH3
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim8, TIM_CHANNEL_3); // turn on complementary channel
//initial PWM Setup
TIM1->CCR1 = 32767;
TIM1->CCR2 = 32767;
TIM1->CCR3 = 32767;
TIM8->CCR1 = 32767;
TIM8->CCR2 = 32767;
TIM8->CCR3 = 32767;
// ADC_DMA Startup
// HAL_ADC_Start_DMA(&hadc1, buffer, 4); // handle ADC1 -> Save to BUFFER value
// TIM1->CCR1= 32767; // for ADC_TRIGGER TIM1-CCR1 NO OUTPUT |OR| TIM1_CCR1 USE AS PWM
HAL_TIM_Base_Start_IT(&htim1) ;
// IMPORTANT -> void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) for the update event
//HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1); // Activate the TIM peripheral
// IMPORTANT -> void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) for the compare event
// ADC calib
// not corect ?? while(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK);
// ================ ADC_DMA ===============================================
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_DATA, ADC_CONVERTED_DATA_BUFFER_SIZE) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *)ADC_DATA_2, ADC_CONVERTED_DATA_BUFFER_SIZE) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start_DMA(&hadc3, (uint32_t *)ADC_DATA_3, ADC_CONVERTED_DATA_BUFFER_SIZE) != HAL_OK)
{
Error_Handler();
}
// ================ ADC_DMA ===============================================
TIM1->ARR = 39999/2;
TIM1->CCR1= 0.5* 39999/2;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
while_function();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
2021-07-14 09:07 PM
I opened your project in CubeMX, issues:
2021-07-18 02:30 AM
Dear Master T
Thank you for your kind reply,
After checking your kind comments, I have fixed some function
P/S: actually it does not affect the ADC trigger
2.) Timer-1 (to be able to activate ADC conversion) has to be configured /routed PWM channel-1 as external events
-> I may not understand fully your meaning? in my testing if TIM1. CCR1 =0 -> ADC is not triggered
when TIM1. CCR1 =500 for example, TIM1 PWM have duty >0 then it triggers ADC
-> configured /routed PWM channel-1 as external events would you please show me which parameter that I have to config
3.ADC is running at 75 /4 = ~18.75 MHz, far away from max speed.
-> Thank for your guidance
After reducing the ADC clock divider, it does improve the ADC performance, but it is not much
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //
{
if(hadc->Instance == ADC3) // ADC 3 is the lastest one that trigger the HAL_ADC_ConvCpltCallback
{
.......................................
}
}
With the config last time 75 /4 = ~18.75 MHz, -> we have the ADC GPIO trigger at 20us
With your suggestion , 75 /2 = ~18.75 *2 MHz, -> we have the ADC GPIO trigger at 15us
However, it is not much high as I expected, Could you please tell me which thing that I should modify?
Here is the modified project one https://1drv.ms/u/s!AuUAN7PWAxFS8l7QfX5_LVRjLFHI?e=Nj7q6Y
2021-07-18 02:38 AM
Thank you for your kind reply,
I am a new guy in this field so I may not fully understand your meaning?
Here's the thing I found:
because I config ADC 1,2 and 3, there are three DMA-ADC callbacks -> when the ADC data is finished transferred to DMA
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //
{
if(hadc->Instance == ADC3) // ADC 3 is the lastest one that trigger the HAL_ADC_ConvCpltCallback
{
.......................................
}
}
I mean (hadc->Instance =ADC1) will be call first , then (hadc->Instance =ADC2), and finally , (hadc->Instance =ADC3)
because I used the DEBUG function, it seem like (I guess) each " HAL_ADC_ConvCpltCallback" equivalent to (hadc->Instance =ADC1), (hadc->Instance =ADC2), and (hadc->Instance =ADC3) have a delay like 5us - Just I feel when I tried to modify the code to see the the difference.
Would you please explain your idea more detail ??
2021-07-18 06:17 AM
2). Check this out:
Advanced-control timers (TIM1/TIM8) RM0433 (page 1588/3289 RM0433 Rev 6)
37.3.27 ADC synchronization
The timer can generate an ADC triggering event with various internal signals, such as reset,
enable or compare events. It is also possible to generate a pulse issued by internal edge
detectors, such as:
– Rising and falling edges of OC4ref
– Rising edge on OC5ref or falling edge on OC6ref
The triggers are issued on the TRGO2 internal line which is redirected to the ADC. There is
a total of 16 possible events, which can be selected using the MMS2[3:0] bits in the
TIMx_CR2 register.
2021-07-18 10:01 AM
Thank you for your fast reply,
As a dummy in STM32, I will need more time to read by myself and understand your kind comment,
I will read RM0433 Rev 6
sincerely,