cancel
Showing results for 
Search instead for 
Did you mean: 

ADC sampling with TIM1 and saving to DMA

thannara123
Senior

Hello ,

I am generating PWM wave of 16khz ,by using TIM1 ,the Duty cycle updating from the DMA array in circular mode .

(to generate sinewave ).

And worked as expected . The TIM1 is configured the Trigger (TRGO) to update event.

Now i want to sample ADC with a 124 micro second (as per the PWM frequency)

The TIM1 update event  should trigger the ADC ,to sample  and need to save the data via DMA.

how to configure it 

I triedout some of configuration dosent working correctly 

please help me 

uint32_t ADC_RES[200];

HAL_ADC_Start_DMA(&hadc, (uint32_t*)&ADC_RES,200);

HAL_ADC_Start_DMA(&hadc, (uint32_t*)&ADC_RES,200);

 

I have configured as follows , But i didnt get 124 micro second sample why ?

 

 

static void MX_ADC_Init(void)

{

 

/* USER CODE BEGIN ADC_Init 0 */

 

/* USER CODE END ADC_Init 0 */

 

ADC_ChannelConfTypeDef sConfig = {0};

 

/* USER CODE BEGIN ADC_Init 1 */

 

/* USER CODE END ADC_Init 1 */

 

/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

*/

hadc.Instance = ADC1;

hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

hadc.Init.Resolution = ADC_RESOLUTION_12B;

hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

hadc.Init.LowPowerAutoWait = DISABLE;

hadc.Init.LowPowerAutoPowerOff = DISABLE;

hadc.Init.ContinuousConvMode = ENABLE;

hadc.Init.DiscontinuousConvMode = DISABLE;

hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO;

hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;

hadc.Init.DMAContinuousRequests = ENABLE;

hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

if (HAL_ADC_Init(&hadc) != HAL_OK)

{

Error_Handler();

}

 

/** Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;

if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN ADC_Init 2 */

 

/* USER CODE END ADC_Init 2 */

 

}

Screenshot 2024-05-04 at 9.13.21 PM.png

 

 

Thanking you 

 

 

@AScha.3   

@waclawek.jan 

 

 

 

 

13 REPLIES 13
AScha.3
Chief II

- don't set ADC continuous...

- don't start DMA 2x

- set DMA circular mode 

So it will run all the time.

If you feel a post has answered your question, please click "Accept as Solution".
thannara123
Senior

What does " mean don't start DMA 2x "?

I turned of all you said but not sampling ADC 

I have configured as follows

Screenshot 2024-05-05 at 7.56.58 AM.png

Screenshot 2024-05-05 at 7.58.08 AM.png

In DMA data width i tried Half word also 

thannara123
Senior

Hello ,

Here is i think my ADC is not getting triger from Time how to check it ?

>What does " mean don't start DMA 2x "?

This :

 

uint32_t ADC_RES[200];

HAL_ADC_Start_DMA(&hadc, (uint32_t*)&ADC_RES,200);

HAL_ADC_Start_DMA(&hadc, (uint32_t*)&ADC_RES,200);

..looks  like : 2x starting DMA.

+

>Here is i think my ADC is not getting triger from Time how to check it ?

You start ADC with trigger - so if it converts you see it - right ? otherwise no result/output.

If you feel a post has answered your question, please click "Accept as Solution".
thannara123
Senior

I am not started DMA twice 

Am not gettinng output 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);

 

}

what will be the problem ?

 

hadc.Instance = ADC1;

hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

hadc.Init.Resolution = ADC_RESOLUTION_12B;

hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

hadc.Init.LowPowerAutoWait = DISABLE;

hadc.Init.LowPowerAutoPowerOff = DISABLE;

hadc.Init.ContinuousConvMode = DISABLE;

hadc.Init.DiscontinuousConvMode = DISABLE;

hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_TRGO;

hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;

hadc.Init.DMAContinuousRequests = DISABLE;

hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

 

 

When I enable DMA contnious request the ADC is sample some of frquency as follows  12.506 ms second sample

Screenshot 2024-05-07 at 1.24.26 PM.png

when i use conntinus DMA request + continous Conversion the following sampling getting 

Screenshot 2024-05-07 at 1.22.52 PM.png

Please help me correct it ?

Hmm - on circular DMA mode, you should check the dma HAL_xxxHalfCpltCallback or 

HAL_xxxCpltCallback, for full buffer received.

If you feel a post has answered your question, please click "Accept as Solution".
thannara123
Senior

Hi 

I am a beginer i dont know how to exactly work DMA transfer complete callback funtion 

i tried the following 

void HAL_TIM_DMA_CpltCallback(TIM_HandleTypeDef *htim) {

if (htim->Instance == TIM1) {

// Handle DMA transfer completion for TIM1

// Your code here: add actions to be performed when the DMA transfer completes

HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8); // Toggle GPIO pin C8

}

}

 

Nothing happening

is it correct way to check DMA transfer ?

As you working with the ADC ,

HAL_ADC_Start_DMA(&hadc, (uint32_t*)&ADC_RES,200);

then wait for -> HAL_ADC_ConvHalfCpltCallback

+

just look in debug , what you get in ADC_RES..

If you feel a post has answered your question, please click "Accept as Solution".
thannara123
Senior

__HAL_RCC_ADC1_CLK_ENABLE();

__HAL_RCC_TIM6_CLK_ENABLE():

These two function where i can find is it in main.c file or any other ?

i am not seeing it in main.c