|
|
  |
обмен по spi, как передать по spi 52 бита |
|
|
|
Mar 19 2010, 08:10
|
Группа: Участник
Сообщений: 5
Регистрация: 19-12-08
Пользователь №: 42 609

|
Кто может - помогите! Есть проблема при передаче по SPI. Нужно организовать передачу 52 бит для управления аудиопроцессором lc75373(только в одну сторону). В принципе код есть - точная копия из ДШ. Но при прогоне в PROTEUS, между байтами получается промежуток, как понял из ДШ после передачи одного байта генератор SPI останавливается и из-за этого получаются промежутки, или это глюк PROTEUS? Код unsigned char i=0; unsigned char mass_data [7] = { 0x0A, 0xff, 0x3A, 0xAf, 0xdd, 0xA0, 0xcf };// mass_data - массив с данными вместо 52 56бит(пока) void SPI_MasterTransmit(char cData) { /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR & (1<<SPIF))) ;
while (1) { while(i<7) { PORTB=0x10;// PORTB.4 - вывод SS - chip select SPI_MasterTransmit( mass_data [i] ); i++; } PORTB=0; } Можно ли это сделать аппаратно, проблема еще в том что кол-во бит не кратно восьми, или лучше все это делать программно.
|
|
|
|
|
Mar 19 2010, 08:30
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Можно сделать программно. Можно аппаратно. По поводу программы - инициализацию SPI выполняете (её нет в приведённом коде)? PORTB.4 настроен как выход (в DDRB бит 4 установливается в 1)? SS точно лог 1 когда устройство выбрано? И почему вы каждый раз устанавливаете его в цикле? Откройте страницу в документации где описан протокол общения с микросхемой. Там наверняка сначала активируется SS, потом отсылается необходимое кол-во байт/бит, потом SS деактивируется. Т.е. код модифицируется: Код spiMasterInit(); //этого нет - надо обязательно выполнить DDRB = (1<<4); //PORTB.4 - выход
while (1) { PORTB=0x10;// PORTB.4 - вывод SS - chip select
while(i<7) { SPI_MasterTransmit( mass_data [i] ); i++; }
PORTB=0; }
Сообщение отредактировал mempfis_ - Mar 19 2010, 08:34
|
|
|
|
|
Mar 19 2010, 09:41
|
Группа: Участник
Сообщений: 5
Регистрация: 19-12-08
Пользователь №: 42 609

|
Вот весь код: Код #include <mega16.h> void SPI_MasterTransmit(unsigned char cData) { /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR & 0x80)); } void main(void) { unsigned char i=0; unsigned char mass_data [7] = { 0x0A, 0xff, 0x3A, 0xAf, 0xdd, 0xA0, 0xcf };
PORTA=0x00; DDRA=0x00;
PORTB=0x00; DDRB=0xB0;
PORTC=0x00; DDRC=0x00;
PORTD=0x00; DDRD=0x00;
// SPI initialization // SPI Type: Master // SPI Clock Rate: 500,000 kHz // SPI Clock Phase: Cycle Half // SPI Clock Polarity: Low // SPI Data Order: MSB First SPCR=0xD1; SPSR=0x00;
#asm in r30,spsr in r30,spdr #endasm
#asm("sei")
while (1) { while(i<7) { PORTB=0x10; SPI_MasterTransmit( mass_data [i] ); i++; } PORTB=0; } С функциями не стал пока заморачиваться - сразу в инициализации портов все прописал. При обращении к микросхеме - сначала идет адрес чипа (восемь бит), затем гонятся данные, SS активируется только когда идут данные. На рисунке захватываются не восемь, а девять бит (мне кажется что это скорее всего опеачтка). В протеусе все передается - единственное что смущает так это то что данные гонятся только побайтно через небольшие промежутки. И даже не знаю как будет реагировать на это микросхема.
Эскизы прикрепленных изображений
|
|
|
|
|
Mar 19 2010, 09:52
|
.NET developer
  
Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532

|
Цитата данные гонятся только побайтно через небольшие промежутки как написали, так и гонятся. сначала начинается передача, затем вы ждете окончания, и лишь потом идете на начало цикла, проверяете условие, выставляете порт в нужное состояние... в MasterTransmit если строчки кода местами поменять, задержка между байтами будет меньше.
|
|
|
|
|
Mar 19 2010, 13:30
|
Группа: Участник
Сообщений: 5
Регистрация: 19-12-08
Пользователь №: 42 609

|
Цитата(Andron_ @ Mar 19 2010, 13:52)  как написали, так и гонятся. сначала начинается передача, затем вы ждете окончания, и лишь потом идете на начало цикла, проверяете условие, выставляете порт в нужное состояние... в MasterTransmit если строчки кода местами поменять, задержка между байтами будет меньше. в MasterTransmit никак нельзя менять строчки : Код void SPI_MasterTransmit(unsigned char cData) { while(!(SPSR & 0x80));//если поменять, то этот цикл не завершится никогда! Это условие проверяет закончена ли передача байта, SPDR = cData; //а она даже не начнется если в SPDR ничего не положили }
|
|
|
|
|
Mar 19 2010, 14:05
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(vados @ Mar 19 2010, 16:30)  в MasterTransmit никак нельзя менять строчки : Код void SPI_MasterTransmit(unsigned char cData) { while(!(SPSR & 0x80));//если поменять, то этот цикл не завершится никогда! Это условие проверяет закончена ли передача байта, SPDR = cData; //а она даже не начнется если в SPDR ничего не положили } Зря Вы так - категорично. Andron_ хотел сказать, что можно проверять: закончилась ли предыдущая передача байта и можно ли передавать следующий байт - ведь предыдущая передача когда-то закончится и этот флаг взведётся (а сбросится он по занесению данных в SPDR)... Проблема только с установкой этого байта ДО первой передачи... Но, и это легко обходится, если передать в начале программы один байт без проверок на окончание передачи "в пустоту" (т.е. без сигнала SS). Всё это актуально, если Вы ещё "смущаетесь" пауз между передачами байтов.
|
|
|
|
|
Mar 19 2010, 15:19
|
Группа: Участник
Сообщений: 5
Регистрация: 19-12-08
Пользователь №: 42 609

|
Похоже нужно перестать смущаться по поводу "дыр" в клоках, поискал по другим форумам - похоже не я один этим озадачился,  - и похоже другого выхода нет. А насчет того что хотел предложить Andron_(теперь допер) - то особо не смог нормально это реализовать.
|
|
|
|
|
Mar 19 2010, 19:37
|
Группа: Участник
Сообщений: 5
Регистрация: 19-12-08
Пользователь №: 42 609

|
Цитата(mempfis_ @ Mar 19 2010, 22:54)  Для SPI не важны дыры в клоках. Главное чтобы на байт приходилось 8 клоков и SS не дёргался. А так можете делать паузы хоть в секунду между байтами. Спасибо - будем пробовать!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|