Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: обмен по spi
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
vados
Кто может - помогите! Есть проблема при передаче по 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;
}


Можно ли это сделать аппаратно, проблема еще в том что кол-во бит не кратно восьми, или лучше все это делать программно.
mempfis_
Можно сделать программно.
Можно аппаратно.
По поводу программы - инициализацию 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;
}
vados
Вот весь код:
Код
#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 активируется только когда идут данные. На рисунке захватываются не восемь, а девять бит (мне кажется что это скорее всего опеачтка).

В протеусе все передается - единственное что смущает так это то что данные гонятся только побайтно через небольшие промежутки. И даже не знаю как будет реагировать на это микросхема.
Andron_
Цитата
данные гонятся только побайтно через небольшие промежутки

как написали, так и гонятся.
сначала начинается передача, затем вы ждете окончания, и лишь потом идете на начало цикла, проверяете условие, выставляете порт в нужное состояние...
в MasterTransmit если строчки кода местами поменять, задержка между байтами будет меньше.
Палыч
Цитата(vados @ Mar 19 2010, 12:41) *
единственное что смущает так это то что данные гонятся только побайтно через небольшие промежутки.
Не смущайтесь - для SPI эти промежутки всего лишь несколько увиличивают время обмена, но - и только!
vados
Цитата(Andron_ @ Mar 19 2010, 13:52) *
как написали, так и гонятся.
сначала начинается передача, затем вы ждете окончания, и лишь потом идете на начало цикла, проверяете условие, выставляете порт в нужное состояние...
в MasterTransmit если строчки кода местами поменять, задержка между байтами будет меньше.

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


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

Спасибо - будем пробовать!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.