Отправка 8-байтового массива в SPI

Я пытаюсь настроить связь SPI с PIC18F452 от Microchip, чтобы отправить 8-байтовый массив на шину (= передача всех байтов сразу). Вот пример того, как выглядит мой массив:

 array   0x0080 byte[8]
array[0] 0x0080  0x01 
array[1] 0x0081  0x01 
array[2] 0x0082  '\0'
array[3] 0x0083  0x01 
array[4] 0x0084  0x01 
array[5] 0x0085  0x01 
array[6] 0x0086  0x01 
array[7] 0x0087  '\0'

Значения поступают из входного сигнала (аудиофайл, часы и т. д.) и принимаются в PORTDbits.RD0 для заполнения массива. Значения всегда равны 1 или 0 и никак иначе.

Во-первых, я начал с отправки по одному байту с помощью putcSPI(). Когда я заполняю массив, я отправляю один байт в SPI, и результаты совпадают.

Затем я попытался отправить все байты сразу, используя putsSPI(), как показано ниже:

/// SEND DATA TO SPI
SPI_INT = 0;     // Enable SS 
putsSPI(array);
SPI_INT = 1;     // Disable SS
delay_ms();      // Delay

Но передача кадра останавливается, когда я встречаю 0 (рассматривается как конец массива, так что это нормально). И мой кадр разделен на куски.

например, для показанного выше массива у меня есть на шине SPI "1 1", а затем следующие значения взяты из следующих кадров

При этом я подумал о преобразовании данных из двоичных в шестнадцатеричные (или целые числа), а затем отправить их в SPI. Я пробовал несколько методов преобразования, найденных здесь, но до сих пор ни один из них не увенчался успехом.

Есть ли решение отправить весь массив напрямую в шину или у кого-нибудь есть идеи, как выполнить преобразование в этом конкретном случае?

Спасибо заранее !


person Daymov    schedule 30.05.2016    source источник
comment
Зачем отправлять 8 байтов, каждый из которых может содержать только одно из двух значений? Вы можете тривиально упаковать значения в один байт.   -  person EOF    schedule 30.05.2016
comment
Проблема решена совершенно другим методом. Опубликую решение, которое я использовал позже   -  person Daymov    schedule 03.08.2016
comment
Если putsSPI ожидает строку с завершающим нулем, очевидно, что он будет отправлять только символы до первого нулевого символа. Почему бы вам просто не отправлять по одному байту за раз? Как уже писал @EOF, 8 бит - это один байт, вы уверены, что вам не нужно отправлять получателю только один байт?   -  person Groo    schedule 03.08.2016
comment
@Groo спасибо за ваш ответ. Как я уже сказал в своем предыдущем комментарии, я решил свою проблему, перезапустив ее с нуля с новыми идеями.   -  person Daymov    schedule 03.08.2016
comment
@Tealyf: я видел это, но это несколько отличается от вопроса. Из 8-байтного массива вы перешли к 2-м байтам (16 бит), которые модифицируются с помощью счетчика (разве они не получены из входного сигнала?). Причина, по которой ваш код не работал, заключалась в том, что putsSPI останавливается на \0, а WriteSPI просто отправляет байт вперед, все остальные объявления и манипуляции с битами не имеют значения.   -  person Groo    schedule 03.08.2016
comment
Да, именно из-за '\0' я решил обратиться за помощью. Я знал, что мой код не может работать так, как он есть. Но иногда полезно начать все сначала. :)   -  person Daymov    schedule 03.08.2016


Ответы (1)


В конце концов, чтобы достичь своей цели, я полностью изменил свой метод решения этой проблемы.

Я все еще использую SPI для связи. Но вместо массива я сохраняю значение своего входного сигнала (после всех операций, которые я к нему применяю) в значении. Позже это значение будет разделено на две части, которые будут отправлять один байт на шину.

// Definition
unsigned int value = 0;
unsigned char value_byte1 = 0; 
unsigned char value_byte2 = 0; 
unsigned int onTheBus_byte1 = 0; 
unsigned int onTheBus_byte2 = 0;

// In main function, the value is modified using a counter (value++;)

// Transfer to SPI
value_byte1 = value >> 8;
value_byte2 = value & 0xFF;

SPI_INT = 0;  // Enable SS 
onTheBus_byte1 = WriteSPI(value_byte1);
onTheBus_byte2 = WriteSPI(value_byte2);
SPI_INT = 1;  // Disable SS

Итак, если я получу:

value = 1505 (= 0x05E1)

в основном цикле, то

value_byte1 = 0x05
value_byte2 = 0xE1

(Этот код был протестирован на Proteus, и я вижу оба байта в отладчике SPI, когда значение записывается в шину)

В случае, если мне нужно использовать значение, скажем, на другом рисунке, я собираю две части после того, как прочитаю их:

value = (value_byte1 << 8) | value_byte2; 
person Daymov    schedule 03.08.2016