cancel
Showing results for 
Search instead for 
Did you mean: 

ADC DMA Continues Mode and enable/disable VBAT channel

suresh
Associate II
Posted on December 06, 2016 at 22:05

Hello, We are using STM32F072 series MCU with 8 physical ADC input channels and VBAT internal by configuring DMA with continues conversion mode:

/* ADC init function */ void MX_ADC_Init(void) { ADC_ChannelConfTypeDef sConfig; /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc.Instance = ADC1; hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC; hadc.Init.Resolution = ADC_RESOLUTION10b; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; hadc.Init.EOCSelection = EOC_SINGLE_CONV; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; hadc.Init.ContinuousConvMode = ENABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.DMAContinuousRequests = ENABLE; hadc.Init.Overrun = OVR_DATA_PRESERVED; HAL_ADC_Init(&hadc); //Configure for the selected ADC regular channel to be converted. //Vehicle BATT_VOLT_MON sConfig.Channel = ADC_CHANNEL_4; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_5; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_6; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_7; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_8; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_9; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_14; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_15; HAL_ADC_ConfigChannel(&hadc, &sConfig); sConfig.Channel = ADC_CHANNEL_VBAT; //ADC_CHANNEL_18; HAL_ADC_ConfigChannel(&hadc, &sConfig); }

By enabling : 

HAL_ADC_Start_DMA(&hadc, (uint32_t*)&ADCRawReadValues,TOTAL_DMA_CONFIG_ADC_CHANNELS);

With this configuration, we are able to read all the configured channels without any issues and unit works perfectly.

As we learned, to save battery life at Internal VBAT ADC channels VABTE bit needs to control. In our case, reading VABT ADC not required continues scan mode. Planning to read this particular channel whenever user requested on demand and all other channels we would like to read DMA continues mode.

Is there a code example to enable and disable VBATE control line? Tried to enable and disable this particular channel through following code sample when user requested. But not suceeded:

  ADC->CCR &= (uint32_t)(~ADC_CCR_VBATEN);

Please help us on this.

Thanks,

#adc
6 REPLIES 6
suresh
Associate II
Posted on December 06, 2016 at 22:07

Here is the Initialization code after better editing:

ADC_ChannelConfTypeDef sConfig;

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

*/

hadc.Instance = ADC1;

hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC;

hadc.Init.Resolution = ADC_RESOLUTION10b;

hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

hadc.Init.EOCSelection = EOC_SINGLE_CONV;

hadc.Init.LowPowerAutoWait = DISABLE;

hadc.Init.LowPowerAutoPowerOff = DISABLE;

hadc.Init.ContinuousConvMode = ENABLE;

hadc.Init.DiscontinuousConvMode = DISABLE;

hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc.Init.DMAContinuousRequests = ENABLE;

hadc.Init.Overrun = OVR_DATA_PRESERVED;

HAL_ADC_Init(&hadc);

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

//Vehicle BATT_VOLT_MON

sConfig.Channel = ADC_CHANNEL_4;

sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_5;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_6;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_7;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_8;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_9;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_14;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_15;

HAL_ADC_ConfigChannel(&hadc, &sConfig);

sConfig.Channel = ADC_CHANNEL_VBAT; //ADC_CHANNEL_18;

HAL_ADC_ConfigChannel(&hadc, &sConfig);
Walid FTITI_O
Senior II
Posted on December 07, 2016 at 15:39

Hi

Kavula.Suresh

,

I think in your case , you shoudConfigure the ADC injected group and the selected channel to be linked to the injected group. This is done through the functionHAL_ADCEx_InjectedConfigChannel()

In case of usage of internal measurement channels (Vbat/VrefInt/TempSensor), The internal paths can be disabled using function HAL_ADC_DeInit(). To reset injected sequencer, function HAL_ADCEx_InjectedStop() can be used.

The ijected mode is not avaialable in the STM32F072, other device does as STM32F3 or STM32F4.

-Walid F-

suresh
Associate II
Posted on December 07, 2016 at 16:51

We reviewed reference manual and googled, not able to find any solution as on now. Appreciate any help on this.

Thanks,

Jim

Posted on December 07, 2016 at 16:01

Thanks for the reply. As you said it's not available in STM32F072 devices. Is there a way we can Inject and Deinject internal channels while using DMA in continues mode?

Thanks,

Posted on December 07, 2016 at 16:39

I think no. You have to check each time the relavant reference manuals for further infomation.

If a response is useful, you would mention that by clicking the correct bottom. Thank you for the contribution

Jeroen3
Senior
Posted on December 08, 2016 at 08:08

I think you can use an trigger instead of continuous mode and some IRQ's to get somewhere.

If you use, for example, TIM1 Update as trigger source for a sample sequence. You can then use DMA and ADC IRQ as timing points to start a single Vbat conversion. Like this:

1. TIM1 Update -> ADC start DMA sampling sequence.

2. DMA IRQ -> once every n samples:

   - disable DMAEN,

   - enable EOCIE,

   - enable VBAT channel, (maybe TSEN and VREFEN as well?)

   - change CHSELR and start seqeunce.

3. ADC IRQ -> restore ADC to regular DMA mode before next TIM1

Update

.

I think. Good luck.