Hello,
We're struggling to work out how to use the differential ADC. Firstly the values returned from GP_ADC_RESULT_REG seem to be a factor of 4 higher than what we expected and secondly the differential value reduces in magnitude when the measured voltage difference actually increases:
1)我们对数据表的读取表示在P0_0和P0_1之间配置差分ADC操作时,结果是10位2的补码二进制整数,其将允许在-1.2V的0x200(-512)的全尺度读数和0x1ff(+511)+ 1.2V。这意味着每个ADC计数大致等于测量值的2.3mV(即1.2 / 512 = 2.34E-03)。
我们试图使用DA14580 Devkit基本差分ADC来测量惠斯通电阻桥的2臂之间的电压差(连接到左手侧的P0_ 0,连接到右手侧的P0_1)。使用示波器,我们测量P0_ 0为1.54V,P0_1为1.26V。
1.26 - 1.54 = -0.28V
therefore we'd expect the ADC count returned by adc_get_sample() to be somewhere around 0x388 (-120) but in fact it's coming back at around 0x235 (-459) ~= -1.07v.
Are we misunderstanding the datasheet? configuring the ADC as single-ended appears to work fine.
2) Our Wheatstone bridge is configured to measure an NTC Thermistor. When the value of this Thermistor changes with temperature as we heat it up, the resistance decreases and the voltage measured by P0_1 therefore decreases with respect to that measured at P0_ 0. The differential ADC result should therefore become more negative however it actually becomes less negative for some reason.
我们的桥梁在顶部有一个18k的左手臂(连接到P0_ 0),底部有17.7克电阻,右手臂(连接到P0_1)由顶部和名义上10k的18k组成(@ 25C)底部的热敏电阻。测量时热敏电阻的电阻约为12.5k,当我们轻轻温暖时,减少到11k。
我们的固件呼叫以下功能:
Inside the wakeup from sleep handleradc_calibrate()
在我们的app_easy_timer()回调处理程序内
adc_init(0, GP_ADC_SIGN | GP_ADC_CHOP, 0); // differential ADC, Sign inversion and Chop to cancel offset voltage, Don't switch in the 3.6v attenuator
adc_enable_channel(0); // P0_ 0 and P0_1
int32_t adcCount = adc_get_sample();
... //执行计算等。
adc_disable();
We've discovered that the encoding is probably sign + magnitude as opposed to 2's comp (we'd request that this information were added to the datasheet please). i.e. 0x3ff is the most negative value (theoretically -1.2v) and 0x1ff is the most positive value (theoretically +1.2v).
If we measure -0.3v between P0_ 0 and P0_1 on the scope, then the ADC reports 0x233 (-51). If we switch the leads to P0_ 0 and P0_1 (so that the difference is now +0.3v) then the ADC returns a value of 0x1C4 (452).
但是,如果我们接地P0_ 0和P0_1,则某些原因ADC返回0x0FF。肯定应该返回0x000?
差分ADC结果实际上看起来是标志和幅度的组合,2的补充。将ADC_GET_SAMPLE()结果转换为从-1024到+1023的符号整数的步骤如下:
代码执行来自差异ADC的Get_Adc_sample()结果的上述调节:
/ *条件差异l ADC result to give a 2's comp integer on the same scale as the single ended readings */
static int32_t normaliseDifferentialADCCount(int32_t adcCount) {
// Sign and magnitude
if (adcCount & 0x200) {
Adccount =〜(Adccount&0x1ff);
} else {
// Positive results are for some reason negative
Adccount =(〜Adccount&0x1ff);
}
//双倍以获得ADC计数与单个最终结果相同的比例
返回Adccount * 2;
}
The other thing we discovered is that the datasheet appears to suggest that the difference between the differential ADC pins can be between -1180 and +1180 mV but an additional constraint is that both of those pins individually must at all times be between 0 and 1180mV as well (at least without the attenuator enabled).
Hi scsims,
Sorry for the delayed response, unfortunatelly there are no extra info regarding the ADC regarding the differential mode and no use of it in any reference design, so i had to run some experiments in order to get the following conclusion. In the differential mode, when the voltage difference is zero the output of the ADC should be close to 0x1FF. When the voltage difference is -1.2 volt the output of the ADC should be close to 0x0, and when the voltage difference is +1.2 volt the output of the ADC should be close to 0x3FF. This is the mapping when you are using the differential mode as far as i can tell.
谢谢pm_dialog.
Hi PM_dialog,
Thanks for looking at this, your conclusions make more sense than mine however it's not the behaviour that we observed. As I mentioned in my comment though, we may have been driving the pins outside of the voltage limits. I'll see if I can get some time to reproduce your experiments at some point.
谢谢,
scsims
Hello PM_dialog,
I've now reproduced your results but with one exception, we assumed that P0_ 0 was AIN- and P0_1 was AIN+ however they're the opposite way around i.e.
P0_1 = 0mV, P0_ 0 = +1180mV then get_adc_sample() returns 0x3ff
P0_1 = +1180mV, P0_ 0 = 0mv then get_adc_sample() returns 0x000
We were also clearly using the ADC inputs outside of their range, we assumed that the ADC max voltage was -1180 mV to +1180 mV only across P0_ 0 and P0_1 however in fact P0_ 0 and P0_1 are also only rated to between 0mV to +1180mV individually.
再次感谢你的帮助。
scsims