STM32 ADC & Reference - Page 1
Forum section: electronics / general

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: October 20, 2018, 12:06:10 am
content: I have an STM32F103C8 - TQFP-48The ADC application of this MCU is very important for a task. it means the ADC conversions should be as stable as possible.1) The MCU does not have the Vref pin. It means the VDDA is used as the reference and naturally, it should not be more than a few tenths of mV difference between VDD and VDDA. This makes the selection of a reference voltage provider harder because typically we have no choice than shorting VDD and VDDA to avoid exceeding the difference. if I don't use the reference, the stability suffers. if I use a reference, then I have to power the MCU with this voltage either to avoid any difference between VDD and VDDA. As I see references are not designed to handle high currents. it is confusing.2) The TL431 and similar chips are adjustable references. if I use a multiturn pot to generate the desired output voltage, then this pot does not affect the temperature stability of the voltage reference?

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 20, 2018, 12:33:32 am
content: I usually put a LC filter on the VDDA from VDD (ferrite inductor and capacitor). It's usually enough to get good results as long as your VDD is reasonably stable.

author: iMo
author_rank: Super Contributor
timestamp: October 20, 2018, 07:40:46 am
content: That is the big pain of those 103 parts with less than 144pins. Except the LC filtering a good pcb layout is important. People indicate a 4 layers pcb works best.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: October 20, 2018, 01:14:12 pm
content: if you believe having the external Vref pin, is a better option, I can change the design to STM32f103VXX, although I don't use I/Os and it is significantly more expensive.Still, nobody replied that using two external resistors can affect the quality of the TL431 voltage reference, in face of temperature variance, or not.if it does not, I still can select the STM32F103C (48 pins) and make the 3.3V for the VDDA separately using reference and connect the VDD to a linear 3.3V supply.

author: iMo
author_rank: Super Contributor
timestamp: October 20, 2018, 02:04:30 pm
content: The ADC in stm32F103 is 12bit. 1LSB with 3.3V Vref is 0.8mV. Thus the stability/tempco of the Vref should be (2x) better than that (TL431 is worse afaik). In practice the induced noise you may see is usually +/- 2 LSB or more, however..Here is what STM recommends in order to get most out oftheir MCU ADCs..

author: GeorgeOfTheJungle
author_rank: Super Contributor
timestamp: October 20, 2018, 02:52:18 pm
content: Quote from: VanitarNordic on October 20, 2018, 12:06:10 amQuote from: STM32F103x8.pdf, Electrical characteristics, page117

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: October 20, 2018, 05:08:08 pm
content: Quote from: imo on October 20, 2018, 02:04:30 pmYes, I briefly considered that but for accurate applications, I think a voltage reference is a must. TL431 claims to have 0.4% tolerance. if you know any other easy to find component, please mention it

author: iMo
author_rank: Super Contributor
timestamp: October 21, 2018, 06:13:24 pm
content: ref3133 3.3V 20ppm/Cref5030 3.0V 3-8ppm/C

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 21, 2018, 06:32:12 pm
content: I like the very good MAX6126. Hard to beat at this price point. (Around $3)https://www.maximintegrated.com/en/products/analog/voltage-references/MAX6126.html

author: slugrustle
author_rank: Frequent Contributor
timestamp: October 21, 2018, 07:36:23 pm
content: That MCU also has an internal reference with 100ppm/degC temperature coefficient. See section 5.3.4 in the datasheet. Unfortunately, I cannot find a calibration register for the internal reference anywhere in the STM32F103C8 documentation. I have used other STM32 chips that store the ADC counts recorded from the internal reference when the chip is supplied with 3.0V or 3.3V Vdd during manufacturing. Using this value, a measurement of the Vrefint channel, and some math, one can convert other channels from ADC counts to millivolts.See also section 11.4 in the Reference manual for ADC self-calibration, which compensates for sampling capacitor differences.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: October 21, 2018, 08:12:41 pm
content: Quote from: slugrustle on October 21, 2018, 07:36:23 pmI use STM32Cube and HAL libraries, I also did not see any note for the internal reference but I read somewhere that it is not that much stable, although 100ppm is good enough I think.regarding the self-calibration I can not find any setting inside CubeMx, it might be enabled as default in the code.

author: iMo
author_rank: Super Contributor
timestamp: October 21, 2018, 08:16:26 pm
content: You have to call something like HAL_ADCEx_Calibration_Start()..

author: mikerj
author_rank: Super Contributor
timestamp: October 21, 2018, 08:26:24 pm
content: If you have a spare input channel then use that to read an external reference voltage and adjust the other channels values in software.

author: Totoxa
author_rank: Newbie
timestamp: October 21, 2018, 08:50:38 pm
content: Quote from: slugrustle on October 21, 2018, 07:36:23 pmLooks like that MCU doesn't have a register with a calibration value. The stm32l051 has one an the address is shown in the datasheet.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: October 21, 2018, 09:07:56 pm
content: Quote from: mikerj on October 21, 2018, 08:26:24 pmyes, I have spare ADC pins, but that channel (which reads the Vref) should be calibrated based on what true reference? maybe I did not get what you mean, Could you explain it more? Thanks

author: mikerj
author_rank: Super Contributor
timestamp: October 21, 2018, 09:30:26 pm
content: Quote from: VanitarNordic on October 21, 2018, 09:07:56 pmBy measuring a known, stable voltage on one of the ADC input, you can calculate the reference voltage on VDDA. You can then use this value to calculate the voltage on the other inputs.e.g. if you measured a 2.5v reference and the 12bit ADC returned a value A, the voltage on VDDA would beVDDA= (2.5*4096)/A

author: iMo
author_rank: Super Contributor
timestamp: October 22, 2018, 07:57:51 am
content: The internal on-chip Vref is 1.20V (+/- 0.04V, max 100ppm/C), you may measure it and then use the above calculation. There is an on-chip temperature sensor as well (has to be calibrated for precise ambient temp measurements).This is how I did it in past with famous BluePill (stm32f103C8) under stm32duino:Code:// Reading Vdd and internal Temperature Sensor// Internal Temperature sensor at ADC16, VREFINT at ADC17// BluePill and MapleMini (stm32f103C8)void setup_vdd_tempr_sensor() {adc_reg_map *regs = ADC1->regs;regs->CR2 |= ADC_CR2_TSEREFE; // enable VREFINT and Temperature sensor// sample rate for VREFINT ADC channel and for Temperature sensorregs->SMPR1 |= (0b111 << 18); // sample rate temperatureregs->SMPR1 |= (0b111 << 21); // sample rate vrefintadc_calibrate(ADC1);}void setup() {Serial.begin(115200);setup_vdd_tempr_sensor();delay(100);}void loop() {float tempr, vdd;// reading Vdd by utilising the internal 1.20V VREFvdd = 1.20 * 4096.0 / adc_read(ADC1, 17);// following "1.43 and 0.0043" parameters come from F103 datasheet - ch. 5.9.13// and tempr needs to be calibrated for every chip (large fab parameters variance)tempr = (1.43 - (vdd / 4096.0 * adc_read(ADC1, 16))) / 0.0043 + 25.0;Serial.print("Vdd= ");Serial.print(vdd);Serial.println(" V");Serial.print("Temp= ");Serial.print(tempr);Serial.println(" C");delay(500);}Code:Temp= 38.32 CVdd= 3.31 VTemp= 39.91 CVdd= 3.32 VTemp= 39.67 CVdd= 3.32 VTemp= 38.49 CVdd= 3.32 VWhat could be done is to "calibrate" the internal Vref - do measure its dependency on Vdd and the temperature (at specific MCU's clock and activity), and create a "calibration table". Has to be done for each chip individually, however.An example (-18 and 10 in fridge, 25=ambient, 50=hair dryer):Code:measure ADC16 (temp) and ADC17 (Vref) atTemp=-18degC for Vdd=3.0, 3.1, 3.2, 3.3, 3.4Temp= 10degC for Vdd=3.0, 3.1, 3.2, 3.3, 3.4Temp= 25degC for Vdd=3.0, 3.1, 3.2, 3.3, 3.4Temp= 50degC for Vdd=3.0, 3.1, 3.2, 3.3, 3.4PS: mind the temperature of the chip depends on the MCU's "activity" and MCU's clock frequency