Electronics > Projects, Designs, and Technical Stuff
Sigma Delta ADC Design
iMo:
Another experiment - the "network topology" as Lattice calls it. See below the schematics.
With Vref=3.3V / 2 (thus the PWM and the comparator share the same source for Vref=Vccio/2) and R1=R2 the Vinp=0..3.3V maps to 0..FullScale_18bit.
See below the calibration table and formula (the Forth runs inside the UPduino).
--- Code: ---: sdadc 700 io@ 701 io@ ; \ read the raw data from the sdadc 2x16bit
: sdf sdadc d>f ; \ read and convert int32 to float (48bits fp)
: sdvf f# 4.96897511e-3 f# 1.2578181e-5 sdf f* f+ ; \ .. convert to Volts
--- End code ---
The peak in the TL431 measurement with v2 (tl431 @2.5ma wired to the Vinp) comes from my writing this post (see above the shot with my setup) ::)
iMo:
SD ADC v3 with a Second Order SD modulator based on TSP #32 blog.
Below a continual measurement with a stable run for ~3minutes, 1measurement in aprox 2.8secs.
####
PS: this particular kind of SD ADC (see above Lattice whitepaper) works such the 1bit bitstream from the Modulator (an integrator, comparator and a single FFlop) is accumulated in ACC (ie 19bit) while it adds the actual level of the bitstream to ACC on each modulator's clock (ie. 1.5MHz). To count 19bits takes 2^19/1.5M=0.35secs therefore.
After that time the 19bit ADCsize data are passed into an LPF (and the ACC is reset to zero), in case of LPF=3 it takes 2^3 passes, thus a single measurement takes 0.35*8=2.8secs.
There is an option to have ACC>ADCsize, ie 22bit ACC and 19bit ADCsize, then it takes 2^(22-19) times longer to get a measurement (the larger ACC does averaging).
####
The UPduino with the Simple SD as above (19bits ADCsize, ACC=19, LPF=3, sampling clock=1.5MHz ).
Added the inverted signal from the 1bit FF sampler (Q and /Q outputs, 3.3V logic) fed into the second integrator.
SD reference voltage is the Vcc=3.3V of the FPGA.
All put on the solderless breadboard wired with jumping wires, voltages stabilized by 1117 and 7905.
Below is a 3minutes long measurement of an TL431 done under stable conditions (I hold my breath :) ), you may see how the last digits flips.
The data are the raw data coming directly from the SDADC, multiplied by -3.3V/(2^19). Not calibrated.
When the SD ADC data are available an interrupt is asserted and the main loop reads the data.
Forth running in the FPGA:
--- Code: ---0 variable sdflag
: isdadc ( -- ) \ ISR: INT_SD interrupt
$bF intflag! $FF intflag! \ ISR: clear the INT_SD flag
1 sdflag ! \ ISR: set SDADC data ready flag
;
' isdadc 1 rshift $3BFC ! \ place isdadc ISR at INT_6 vector location
: sdadc 700 io@ 701 io@ ; \ read SDADC raw data
: sdf sdadc d>f ; \ convert to float
: sdvf f# 6.2942504882e-6 sdf f* ; \ make Volts, mult by 3.3/2^ADCsize
: testx BEGIN \ wait on a measurement, print result in Volts
sdflag @ 0<> \ is the SDADC flag set? Loop
UNTIL
sdvf f. cr \ print Volts
0 sdflag ! \ reset SDADC flag
;
: test 0 do testx loop ; \ do XXXX measurements
$40 intmask! \ enable isdadc interrupt
eint \ global int enable
7 set-precision \ we will print 7 digits
30000 test \ do make 30000 measurements
--- End code ---
The STDEV is 11.5uV of that measurement.
jaromir:
Your post from late May looks promising.
Any news on this topic?
iMo:
Since then I tried with sinc3 filters but the results are rather poor.
The sinc3 filter code came from AD7402 DS, for example.
PS: One issue I can see with this design is its complexity (when you want something similar to the Multislope) tends to be pretty large. For example the Q and /Q signal levels have to be switched from +Vref=10V to -Vref=-10V, at around 1-2MHz.. And the resistors, capacitors and opamps with same quality as with Multislope.
SiliconWizard:
I've never implemented a sigma-delta ADC, but I have implemented sigma-delta DACs. I got pretty good results using only linear interpolation for the oversampling stage. Sure that's not ideal, but it takes up a lot less area and can run much faster.
Navigation
[0] Message Index
[*] Previous page
Go to full version