cancel
Showing results for 
Search instead for 
Did you mean: 

How to get a ADC resolution?

ubaldot
Senior

I have the following code that I call from a freertos task scheduled with a period of 100 ms.

It reads the voltage applied to a pin and return the voltage value as a float.  

 

float pinin_pv(void) {
/* Return the pin voltage in the interval [0, PIN_VOLTAGE] */
extern ADC_HandleTypeDef hadc1;
const uint32_t ADC_RESOLUTION_BITS = 10;
const uint32_t pippo = hadc1.Init.Resolution; // Only for explanation
const float PIN_VOLTAGE = 5000.0F; // [mV]
const float ANALOG_IN_RESOLUTION =
PIN_VOLTAGE / (float)(1 << ADC_RESOLUTION_BITS); // [mV]HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
size_t analog_read = HAL_ADC_GetValue(&hadc1);
float pin_voltage;
pin_voltage = ANALOG_IN_RESOLUTION * (float)analog_read;
return pin_voltage;
}

 



As you see, I have hard-coded const uint32_t ADC_RESOLUTION_BITS = 10; but I would like to pull this information from hadc1.Init.Resolution; (as example, I defined a variable named pippo in the code above). However, the value of pippo is like 1000 times larger that what is supposed to be. How to fix it? Is it possible to avoid hard-coding the variable PIN_VOLTAGE as well?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Look at the definition for hadc1.Init.Resolution to see the various values and do an if statement for each.

 

if (hadc1.Init.Resolution == ADC_RESOLUTION_6B) {
    ...
} else if (hadc1.Init.Resolution == ADC_RESOLUTION_8B) {
    ...
} ...

 

You can also look at how they're defined within the register to make a formula for this.

 

> const float PIN_VOLTAGE = 5000.0F; // [mV]

Not sure what you mean here. Why is this hard-coded to 5V anyway? Shouldn't it be 3.3V? CubeMX allows you to define a value for VREF+ (technically VDD) that you could use if you want.

#define  VDD_VALUE                    (3300UL) /*!< Value of VDD in mv */

 

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

View solution in original post

6 REPLIES 6
Andrew Neil
Evangelist III

Use this button to properly post source code:

AndrewNeil_0-1707764517518.png

 

 

Ok! I wish to edit my post, but I cannot figure out how... :\ 
EDIT: Found! 

TDK
Guru

Look at the definition for hadc1.Init.Resolution to see the various values and do an if statement for each.

 

if (hadc1.Init.Resolution == ADC_RESOLUTION_6B) {
    ...
} else if (hadc1.Init.Resolution == ADC_RESOLUTION_8B) {
    ...
} ...

 

You can also look at how they're defined within the register to make a formula for this.

 

> const float PIN_VOLTAGE = 5000.0F; // [mV]

Not sure what you mean here. Why is this hard-coded to 5V anyway? Shouldn't it be 3.3V? CubeMX allows you to define a value for VREF+ (technically VDD) that you could use if you want.

#define  VDD_VALUE                    (3300UL) /*!< Value of VDD in mv */

 

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

Usch! Right, I could use a switch-case statement for the resolution. I tried to look into the definition but it’s a bit cryptic. 

Regarding the voltage I have 5 volts because the range of the input signal on that pin (PC0 in my case) is 0-5V. 

5V is definitely above the limit for ADC pins. It is limited to VREF+, which is usually VDDA, which is usually VDD.

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

Usch! I reduced it to 3.3V and the readings are actually correct now! (I compared with a multimeter and when I have 5.0V the readings were wrong). Thanks for the heads up! :)