2016-08-16 09:31 AM
Hi,
I am trying to read two adc channels number 10 and 11 with cubemx output. I can read the 10th channel with this code:HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1,10);value_adc=HAL_ADC_GetValue(&hadc1);How can i read 11th channel? #adc #hal #no-hablo-hal2016-08-16 01:25 PM
Hi
>How can i read 11th channel?
From my understanding of the reference manual (see the example timing diagrams and example code) I think this code aught to work.uint16_t
adc_10;
uint16_t
adc_11;
HAL_ADC_Start(&hadc1);
//get channel 10
HAL_ADC_PollForConversion(&hadc1,10);
adc_10=HAL_ADC_GetValue(&hadc1);
//get channel 11
HAL_ADC_PollForConversion(&hadc1,10);
adc_11=HAL_ADC_GetValue(&hadc1);
To get more data just repeat the process.
Disclaimer: I usually just mess with the registers directly for ADC conversions.
-Sam Ellicott
2016-08-16 11:20 PM
Hi Nebk
It does not work because you assign the same adc value to different variables, so it always shows the same values. I just want to read different adc channels and Show them with different variables.2016-08-17 05:51 AM
The method preferred by the STM32 design is to configure the ADC to read two channels, using an enumerated list, to scan them in a non-continuous fashion, and be software triggered. Then you have an array holding two 16-bit half-words, describe the array, and length to the DMA unit, in circular mode.
Then, after you trigger the ADC, the DMA fills the two variables (in an array), and signals TC (Transfer Complete) to let you know it is complete.2016-08-17 06:03 AM
Hi rapid84,
For multichannel ADC case, you ought to use DMA. I recommend that you look to the ''ADC_RegularConversion_DMA'' example in the STM32CubeF4 and add the other ADC channel to the code. If you want to make change in your CubeMx project and read channels in continuous mode, follow these recommendations: - Enable scan conversion mode - Enable continuous conversion mode - Add n regular channel configuration to be converted ( n=2 in your case) - Select circular mode with data_width = word. -Hannibal-2016-08-17 06:29 AM
Hi,
I am using the code and definitions for multichannel adc read: ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1; uint16_t value_adc[2]; main() { MX_DMA_Init(); MX_ADC1_Init(); HAL_ADC_Start(&hadc1); HAL_ADC_Start_DMA(&hadc1, value_adc, 2); HAL_ADC_PollForConversion(&hadc1,250); *value_adc = HAL_ADC_GetValue(&hadc1); } void MX_ADC1_Init(void) {ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = ENABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 2; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; HAL_ADC_Init(&hadc1);/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/ sConfig.Channel = ADC_CHANNEL_10; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES; HAL_ADC_ConfigChannel(&hadc1, &sConfig); sConfig.Channel = ADC_CHANNEL_11; sConfig.Rank = 2; //sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES; HAL_ADC_ConfigChannel(&hadc1, &sConfig); } But it does not work clearly, what is my wrongness ?2016-08-17 09:49 AM
If you do not mind using polling (against the superior wisdom of Hanibal and clive1) this code aught to work (it works on my stm32f0 board).
The important thing is to configure the ADC in discontinuous mode.int
main(
void
)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();
uint16_t adc_6, adc_7, adc_9;
while
(1) {
//first ADC in the sequence
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 5);
adc_6 = HAL_ADC_GetValue(&hadc);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 5);
adc_7 = HAL_ADC_GetValue(&hadc);
//last ADC in the sequence
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 5);
adc_9 = HAL_ADC_GetValue(&hadc);
}
}
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_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 = ENABLE;
// this is the important bit
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
HAL_ADC_Init(&hadc);
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_7;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_9;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
}
Sorry that my original code did not work.
-Nebk
2016-08-17 10:14 AM
For using the DMA, you might want to look at
https://tunizem.blogspot.com/2014/09/using-adc-with-dma-on-stm32.html
2016-08-17 11:11 AM
Hi Nebk,
What is the difference between your code and dma technique? Advantages or disadvantages...2016-08-17 12:18 PM
I have just never bothered to use the DMA for ADCs. I don't think there are really any downsides of using the DMA once you get it working. I just have never had a project where setting up the DMA was worth the extra hassle. (I always have problems when I try to use the DMA.)
My code is more or less ''quick and dirty''. It should work but is definitely less efficient. I would not use it if your application depends heavily on having fast access to new ADC values. -Nebk