How to have a good precision of ADC on STM32F103C8?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-22 8:58 PM
Hi.
Now I'm trying to implement the ADC on the STM32F103C8.
but I came across some problem when I voltage leveling test.
The code is here
x = getPot()*3.3/4095; //get analog value and convert to volts, 12bit ADC if(x < 2.2) { GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_SetBits(GPIOA, GPIO_Pin_5); GPIO_ResetBits(GPIOA, GPIO_Pin_6); GPIO_SetBits(GPIOA, GPIO_Pin_7); alram = 1; } else { GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_SetBits(GPIOA, GPIO_Pin_5); GPIO_SetBits(GPIOA, GPIO_Pin_6); GPIO_SetBits(GPIOA, GPIO_Pin_7); alram = 0; }the below is what I got the outputs from ports.
As you can see that above image, when I set 2.2v to the ADC then the output is such a mess.
Is there any good way to get a clean operation?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-22 9:23 PM
x = getPot()*3.3/4095; //get analog value and convert to volts, 12bit ADC
if(x < 2.2)
==> For precise calculation, don't use float with 24 bit mantissa. Try to use integer or something like Q31 format.
Anything analog has noise, this noise level will have at least one LSB amplitude.
Where comes from the noise? Well, mostly from the application itself, the HW, the wires (acting as antenna), etc...
Typically, for a good analog performance, the analog supply should be separated (MCU package dependent). Then, the wires should be at least a twisted pair with ground. Ideally for some STM32, the ADC has differential mode, then the twisted pair becomes like the USB differential pair, which rejects common mode noise (if the signal is disturbed, so is its 'ground' hence it is cancelled out). After this, characterizing the noise will enable proper digital filtering (oversampling is the generic brute force way to reduce noise)...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-23 12:01 AM
Thanks, Would you mind giving me some snippet code of that?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-23 1:19 AM
This is an old SW (Std lib for STM32F437), so to be considered as pseudo code.
________________ Attachments : Adc.c.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hy9n&d=%2Fa%2F0X0000000b6S%2FuUM482hqY39pDlu0Gk0bUg59EpHkMoFVR7EZ5a5boeo&asPdf=falseAdc.h.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyCX&d=%2Fa%2F0X0000000b6R%2F.zmaGMlYUpaGF5CvDWLLVkhc8Kix9HAOO2p0_PD.hz4&asPdf=false- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-23 1:41 AM
==> For precise calculation, don't use float with 24 bit mantissa. Try to use integer or something like Q31 format.
The problem of shown calculation is IMHO more a (massive) waste of performance then a loss of precision.
The F1 parts have no FPU, and you gain nothing compared to integer calculations.
if(x < 2.2)
{...
} else ...Apart from that, I suggest a filtering instead of hard decision on just one value ( x ).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-23 3:09 AM
Another thing to consider when precisely converting ADC value to volts: You should use the actual Vdda value instead of 3.3 V in your equation. See the 'Converting a supply-relative ADC measurement to an absolute voltage value' paragraph on page 375 of the link below (this is the RM for STM32F303, but the principle is the same):
For precise conversion you should know what is the Vdda value and for that, you should do another ADC conversion of Vref_int channel.
Best regards.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-10-23 6:27 AM
Digging in the sample code will enable the possibiity to compensate for the MCU VDDA and Temperature (if linear interpolation points are available)
