I am currently testing a 16-bit DAC and a 18-bit ADC. In many tests I have found the ADC to get "stuck" at codes, especially at the ends of the input range.
Both the DAC and ADC operate in bipolar mode and are interfaced with analog circuitry that amplifies/attenuate and also provide common mode offset and clipping to ensure that signal fits the differential inputs on the ADC. The data converters are connected to a micro controller with SPI. The data is transferred from the micro controller to a PC with a serial port.
I am using the ADC to sample the output of the DAC in order to test precision and noise etc. The resulting data should be straight line when the DAC is used as x-values and the corresponding ADC samples plotted on the y-axis.
Note that the full scale range is different: The DAC outputs voltages between -20.48 and 20.4794. The ADC reads voltages between -16.384 and 16.3839.
The plot below shows the samples from the ADC when the DAC is set from 0 to 65535 in steps of 1 LSB. The total number of samples is 65536.
Zooming in at the center of the full scale range (x-span: 1000, y-span: 5000), the plot looks like this (a little noisy, but otherwise OK):
However, zooming in at the lower part of the full scale range, stuck codes are clearly visible:
The same can be said about the upper samples:
Note that all three plots are on the same scale but different areas.
Looking at a segment of the data is interesting (keep in mind that the analog interfaces introduces some gain and offset error):
One can clearly see, that the ADC is stuck even though the resolution of the 18-bit ADC is better than the 16-bit DAC.
Even more interesting is that the difference between two stuck codes, like 255648-255712 = -64 and 255712-255808 = -96, seems to be in multiples of 32. That rules out any problems with the analog interface, I think.
To show the problem better, I made a plot of the difference between one sample and the next sample over the entire full scale range:
The plot clearly shows that stuck codes does not occur at the center of the full-scale range. Moving towards the ends of the range, stuck samples become more and more obvious.
In order to solve the problem, I tried to slow the SPI-communication and also sampling at lower speeds. This did not make any difference. I also wonder if the problem could be the conversion of the 18-bit ADC output from Two's Complement to Offset Binary. I use this code to do the conversion, which I believe is correct:
uint32_t y = (131072 ^ Y >> 6) & 0x3FFFF; // Y is 18-bit Two's Complement
So, what could cause this problem? I have also checked the voltage reference, decoupling and other analog issues that might cause the problem. Still the stuck codes are multiples of 32, it looks to me like the problem is digital rather than analog.
Any help or ideas are appreciated! Thanks in advance :-)