Передаточная функция АЦП

Я взял на себя этот проект от человека, который ушел давным-давно.

Сейчас я смотрю на модули АЦП, но не понимаю, что означают коды.

MCU: LM3S9B96
ADC: AD7609 ( 18bit/8 channel)
Instrumentation Amp : INA114

Process: Reading volts(0 ~ +10v) --> Amplifier(INA114) --> AD7609.

Вот коды для этого:

  1. После полной конвертации 8 каналов, сохраненных в data[9]
  2. Преобразовать данные в микровольты ??

    //convert to microvolts and store the readings // unsigned long temp[], data[] temp[0] = ((data[0]<<2)& 0x3FFFC) + ((data[1]>>14)& 0x0003); temp[1] = ((data[1]<<4)& 0x3FFF0) + ((data[2]>>12)& 0x000F); temp[2] = ((data[2]<<6)& 0x3FFC0) + ((data[3]>>10)& 0x003F); temp[3] = ((data[3]<<8)& 0x3FF00) + ((data[4]>>8)& 0x00FF); temp[4] = ((data[4]<<10)& 0x3FC00) + ((data[5]>>6)& 0x03FF); temp[5] = ((data[5]<<12) & 0x3F000) + ((data[6]>>4)& 0x0FFF); temp[6] = ((data[6]<<14)& 0x3FFF0) + ((data[7]>>2)& 0x3FFF); temp[7] = ((data[7]<<16)& 0x3FFFC) + (data[8]& 0xFFFF);

Я не понимаю, что делают эти коды ...? Я знаю, что это меняется, но как они становятся форматом микроданных?

  1. функция передачи

//store the final value in the raw data array adstor[] adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);

131072 = 2^(18-1) но Я не знаю, откуда берутся другие значения

В таблице данных AD7609 указано The FSR for the AD7609 is 40 V for the ±10 V range and 20 V for the ±5 V range, поэтому я предположил, что он выбрал 20v, описанный выше, и каким-то образом оказалось 2000???

У кого-нибудь есть какие-нибудь подсказки ??

Спасибо

------------------- Обновленный вопрос отсюда ---------------------

Я не понимаю, как 18-битное объединенное значение данных [0] + 16-битное объединенное значение данных [1] превращается в микровольт после передаточной функции АЦП.

данные [9] +---+---+--- +---+---+---+---+---+---++---+---+---++---+---+---++
analog volts | 1.902v | 1.921v | 1.887v | 1.934v | +-----------++-----------+------------+------------+------------+
digital value| 12,464 | 12,589 | 12,366 | 12,674 | +---+---+---++---+---+---++---+---+---++---+---+---++---+---+---+

Я просто привожу пример из data[3:0] 1 resolution = 20v/2^17-1 = 152.59 uV/bit и 1.902v/152.59uv = 12,464

Теперь приступим к конкатенации:

temp[0] = ((data[0]<<2)& 0x3FFFC) + ((data[1]>>14)& 0x0003) = C2C0

temp[1] = ((data[1]<<4)& 0x3FFF0) + ((data[2]>>12)& 0x000F) = 312D3

temp[2] = ((data[1]<<6)& 0x3FFC0) + ((data[3]>>10)& 0x003F) = 138C

Затем включите передаточную функцию и получите микровольт

adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);

adstor[0]= 7,607,421 with temp[0] !=1.902*e6

adstor[1]= 30,735,321 with temp[1] != 1.921*e6

adstor[2]= 763,549 with temp[2]

Как вы заметили, они сильно отличаются от аналогового значения в таблице.

Я не понимаю, почему данные нужно сдвигать по битам и _21 _, _ 22_ и складывать с двумя данными [] ??

Спасибо,


person Jin    schedule 02.10.2014    source источник


Ответы (1)


Обратите внимание, что максимальное 18-битное значение составляет 2 ^ 18-1 = $ 3FFFF = 262143.

Для [2] оказывается, что он / она разбивает конкатенированные значения 18-битных слов на длинные для облегчения манипуляции на шаге [3].

[3]: Что касается adstor [i] = (signed long) (((temp [i] * 2000) / 131072) * 10000);

Чтобы преобразовать необработанное значение A / D в вольты, он / она умножается на ожидаемое значение вольт и делится на максимально возможное значение A / D (в данном случае $ 3FFFF), так что, похоже, в коде есть ошибка, так как он / она делится на 2 ^ 17-1, а не на 2 ^ 18-1. Другая возможность состоит в том, что он / она использует половину диапазона A / D и компенсирует это таким образом.

Если вы хотите, чтобы 20 В превратились в микровольт, вам нужно умножить его на 1e6. Но чтобы избежать переполнения длинных, он разбивает умножение на две части (* 2000 и * 10000). Из-за промежуточного деления число становится достаточно маленьким, чтобы его можно было в конце умножить на 10000 без переполнения за счет возможной потери некоторых наименее значимых битов результата.

P.S. (Я использую $ как эквивалент 0x из-за многолетней привычки к некоторым языкам ассемблера)

person tonypdmtr    schedule 03.10.2014
comment
Теперь я понимаю, что он пытался сделать. Думаю, я почти понял! Как вы упомянули выше, он использовал половину диапазона АЦП, поскольку диапазон аналогового входа кажется 0 ~ 10V, а не +-10. Я не впервые понял значение 2000 * 10000, но похоже, что это половина микровольт от FSR (Full Scale Range) AD7609 (Полная шкала - 40V). Тем не менее, я не совсем понимаю [2], который представляет собой конкатенированные значения. Мне может потребоваться набрать определенные числа, чтобы увидеть, что произойдет после шагов [2] и [3]. Я действительно благодарю вас за помощь! Я вижу, ты любишь деньги ^^. Я хочу, чтобы $ 3FFFF были моей зарплатой. - person Jin; 03.10.2014
comment
Что касается [2], я имел в виду, что восемь 18-битных значений изначально упакованы в девять 16-битных регистров. Первое 18-битное значение сохраняется как 16 бит в регистре 0, а оставшиеся 2 бита в регистре 1 вместе с 14 битами следующего регистра и так далее. Код предназначен для распаковки всего этого в отдельные переменные (достаточно длинные, чтобы вместить 18 бит). - person tonypdmtr; 04.10.2014
comment
А-ха !. Я понял!! Я очень ценю. Хороших выходных. - person Jin; 04.10.2014