2023-02-16 08:45 PM
I using STM32CubeIDE and STM32L03.
I don't understand how to make a simple sample of a ADC channel (in blocking mode). I had config the Cube to generate a ADC_Init() that contains my 6 Analog In channels.
I want to have a function that goes like this: uint16_t AD_Read(unit32_t channel) { ... }
I make a ADC_Start and then HAL_Polling() and then get the ADC value. Doing that for 20 samples. But where do I set what ADC channel I want to read? Is it the rank member I set before I calling HAL_ADC_Start() or what? The first channel in ADC_Init has this "rank" member set.
The config I tried to keep as simple as I could. No group scanning or continuous scanning and no interrupt.
The ADC_Init
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_10B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
plus six ADC-channel where the first has sConfig.rank = ADC_RANK_CHANNEL_NUMBER
Solved! Go to Solution.
2023-02-20 03:33 AM
Now it works. I saw the array of configurations per channel. I modified them so it suited my processor.
Then I called ad_read () with Hadc and channel selection as parameters. The error was in the fact that the AD got the wrong configuration. Now it got correct.
Thanks again.
2023-02-16 10:40 PM
if you don't want to use the automatics, configure only the first channel in CubeMX and use that config as a blueprint for your user written config_i for each channel i. Then your code is
while(1) {
config_1
start
poll
v[1] = get_value
config_2
...
}
You may of course use an inner for-loop etc..
If it doesn't work, show your code snippets
hth
KnarfB
2023-02-16 10:52 PM
The thing is to configure each channel as the first one.
Example:
AD_Read(channel)
{
config_[channel] (see below)
for n=0; n < 20; n++
{start
poll
x = x + get_value}
x= x / 20
return x
}
FYI:
First ch look like this in the ADC_Ini
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
Am I thinking right?
2023-02-16 11:11 PM
You init sConfig once and then change only the Channel field, not the rank, they are all rank 1, and call HAL_ADC_ConfigChannel right before the start.
You can conveniently keep the channels in an array like
const uint32_t adc_channels[] = {
ADC_CHANNEL_VREFINT, // internal measurement channel
ADC_CHANNEL_TEMPSENSOR, // internal measurement channel
ADC_CHANNEL_8,
ADC_CHANNEL_9,
ADC_CHANNEL_10,
ADC_CHANNEL_11
};
and say
sConfig.Channel = adc_channels[i];
in the inner for-loop.
hth
KnarfB
2023-02-16 11:20 PM
I got it. I must say, I did that test before (I think). I thought the HAL_ADC_ConfigChannel() made some switching around the ADC and after that I could make a START(); poll..., Read. But it didn't work out. Some of the sampled values was very huge like I needed to use a MASK to get the correct value.
However, your answer show that I'm on the right track.
Thanx
2023-02-18 08:26 PM
Tried again and it does NOT work. I don't understand. It's like the ADC is not turned on. There must be some ADC_enable() somewhere?
Maybe I have problems with definitions/declarations of variables? To change channel in ADC_Read() the sConfig needs to be reachable also here.
My ADC_Init() is in main.c. CubeIDE takes care of that. Then I have a file called adc.c/adc.h. adc_read() is defined here.
sConfig is defined in ADC_Init(). I move the definition of sConfig outside of ADC_Init() and then declare it as external in ADC_Read(). Also included the xxxxx_adc.h file from the Driver folder.
Is it here the error is committed?
2023-02-18 10:13 PM
This code works on STM32C0 and does repetitively blocking single channel read... for all of them, including the internal ones.
The ADC generation might be newer, the most difficult to grasp was how to configure it for the -unanticipated- simple operating mode...
2023-02-18 10:31 PM
Thank you. it's all about configuration and this will help me. I think I miss something obvious.
2023-02-20 03:33 AM
Now it works. I saw the array of configurations per channel. I modified them so it suited my processor.
Then I called ad_read () with Hadc and channel selection as parameters. The error was in the fact that the AD got the wrong configuration. Now it got correct.
Thanks again.