2015-08-11 6 views
-1

Я пытаюсь читать значения АЦП (ADS8320), используя связь SPI. Я использую встроенный workbench IAR для контроллера ARM и SM470R1B1. В листе данных говорится, что первые 6 бит являются фиктивными, а следующие 16 бит - это данные actval. Я пытаюсь читать 24 бита и игнорировать первые 6 бит и последние 2 бита. Я получаю неправильные значения, когда я пытаюсь использовать код ниже.Чтение 22 бит через SPI

unsigned int readADC8320(void) 
{     
    value = AD8320_16(0xFFFFFF);    // read registe  
    return value; 
} 

unsigned int AD8320_16(unsigned int value) 
{ 
unsigned int data; 
AD8320_CS_Status(0); 
SW_Delay(DELAY_10US); 
while(GIODOUTA&X2); 
data = spi2(value >> 16);  //read high 8 bits 
data = (data << 6)| spi2(value >> 8); //read next 8 bits but 6+8 =14 
data = (data << 8)| spi2(value >> 2); //add last two bits only 
SW_Delay(DELAY_10US); 
AD8320_CS_Status(1); 
return data; 
} 

unsigned char spi2(unsigned char data) 
{ 
// Write byte to SPI2DAT1 register 
SPI2DAT1 = data;  

while(!(SPI2CTRL3 & 0x01)){}  // Wait for RxFlag to get set 
return (SPI2BUF & 0x000000FF);  // Read SPIBUF 
    } 

Может кто-нибудь предложить мне, где я делаю неправильно. Я довольно беден со сменными операциями.

+2

Начните с описания вашей системы. Мы даже не знаем, что такое процессор/MCU, с которым вы работаете. –

+0

Возможно, вы плохо себя чувствуете при работе смены, но вы очень плохо задаете вопросы и, предположительно, тестируете и отлаживаете. Когда вы перешли через этот код с вашим отладчиком, что было передано как «значение» и как данные обрабатывались в «данные»? –

+0

Я имею в виду, зачем просто сбрасывать такие аппаратные драйверы на нас, как просто свалку кода? Мы не знаем, является ли «ценность» здравомыслящей, перевернутой, правильной бесконечности или чем-то.Насколько нам известно, ваш АЦП даже не включен, и вы обрабатываете мусор. –

ответ

1

Ваш код выглядит неуклюжим. Например, какая цель имеет value?

Техническое описание, которое вы связали, указывает на то, что 22 тактовых цикла достаточны (и что 24 тактовых цикла в порядке), никаких дополнительных задержек не требуется, если часы SPI находятся в пределах (как я полагаю, не более 2,4 МГц). Таким образом, я бы ожидать, что ваш код выглядеть как

void AD8320_setup(void) 
{ 
    /* TODO: 
    * - Set SPI2 clock frequency, if programmable (max. 2.4 MHz) 
    * - Set SPI2 transfer size, if programmable (8 bits per byte) 
    * - Set SPI2 to latch data on the falling edge of clock pulse 
    * - Set SPI2 to pull clock high when inactive 
    * - Set AD8320 chip select pin as an output 
    * - Set AD8320 chip select pin high (it is active low) 
    * - Ensure AD8320 is powered 
    */ 
} 

uint16_t AD8320_16(void) 
{ 
    uint16_t result; 

    /* TODO: Set AD8320 chip select pin 0/LOW (to select it) 
    */ 

    /* TODO: Clear SPI2 FIFO if it has one, 
    *  so that we get actual wire data, 
    *  not old cached data. 
    */ 

    result = ((uint16_t)(spi2_read() & 3U)) << 14; 
    result |= ((uint16_t)spi2_read()) << 6; 
    result |= ((uint16_t)spi2_read()) >> 2; 

    /* TODO: Set AD8320 chip select pin 1/HIGH (to deselect it) 
    */ 

    return result; 
} 

Прототип spi2_read обычно unsigned char spi2_read(void);, но это может быть любого целого типа, которое может представлять все восемь значений битов правильно (от 0 до 255, включительно) , Выше я произвел результат - после маскировки любых нерелевантных битов, если они есть, с двоичной операцией И - до uint16_t, прежде чем перевести его в правильное положение в результате, так что независимо от возвращаемого типа spi2_read() мы можем использовать он должен построить наше 16-битное значение.

Первый spi2_read() считывает первые 8 бит. Я предполагаю, что ваше устройство SPI-шина отправляет и получает самый старший бит; это означает, что 6 фиктивных битов являются наиболее значимыми битами, а 2 младших значащих бита являются наиболее значимыми битами результата. Вот почему мы сохраняем только два младших значащих бита первого байта и переносим их на 14 мест - таким образом мы получаем их в наиболее значительном положении.

Второй spi2_read() читает следующие восемь бит. Это бит 13..6 данных; поэтому мы смещаем этот байт, оставшийся на 6 мест, и OR с существующими данными.

Последние spi2_read() читает следующие восемь бит. Последние два бита должны быть отброшены, потому что только первые (наиболее важные) 6 бит содержат остальную часть интересующих нас данных. Таким образом, мы сдвигаем это на 2 места и OR с существующими данными.

Подготовка spi2 включает в себя такие вещи, как размер слова (8 бит), скорость передачи данных (если программируется) и т. Д.

Выбор микросхемы для AD8320 - это всего лишь общий выходной вывод, он просто активен. Вот почему это описано как CS/SHDN в таблице данных: чип выбран при низком уровне, выключение при высоком уровне.

Чип представляет собой микроэлектроэнергию, поэтому требуется менее 2 мА, поэтому вы можете, возможно, вывести ее из выходного штыря на многих микроконтроллерах. Если бы вы это сделали, вам также пришлось бы помнить, чтобы сделать этот вывод выходным и 1/высокий в _setup() функции.

+0

Пикантное замечание о правильности типа: для придания эффекта какого-либо эффекта '((uint16_t) (spi2_read() & 3U)) << 14;' должно быть '((uint16_t) spi2_read() & 3U) << 14; 'Приведение к' uint16_t' должно быть внутри скобки, прежде чем произойдет какое-либо неявное целочисленное продвижение. – Lundin

+0

@ Lundin: Ой! Собственно, моя формулировка в этом параграфе была жестокой. Я написал, что я * «передал значение результата» * (из 'spi2_read()') в 'uint16_t', но я имел в виду, что перед переносом возвращаю значение после маскировки. Я попытаюсь исправить эту формулировку. Я рад предоставить компилятору лучший способ справиться с маскированием бит здесь, если значение, смещенное битом, составляет от 0 до 3 включительно и типа 'uint16_t'. В конце концов, 'spi2_read()' должен иметь возможность возвращать целые значения без знака или подписи с 0 по 255 включительно, а трансляция необходима только для того, чтобы мы могли построить 16-битный результат. –

Смежные вопросы