Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI в СЛЭЙВ режиме - ничего не передет
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Андрей К. Ф.
Пишу в IARе следующее:

/******************************************************************************/
void SPI_init()
{
volatile char c;
SPCR = (1<<SPIE)|(1<<SPE)|(0<<DORD)|(0<<MSTR)|(0<<CPOL)|(0<<CPHA);
c = SPSR;
c = SPDR;
}


//******************************************************************************
#pragma vector=SPI_STC_vect
__interrupt void SPI_STC_vect_handler()
{
char in_byte;
in_byte = SPDR;

//...

SPDR = param.bt[0];

// ....
}

В итоге все ВХОДЯЩИЕ байты принимаются на ура.
Но передает SPI (по линии MISO) не то, что я ему говорю, а то что в него пришло от мастера в прошлом цикле передачи (проверял осциллографом).
Подскажите пожалуйста в чем проблема???
WHALE
Попробуйте записывать данные в SPDR после выхода из прерывания
rezident
Цитата(Андрей К. Ф. @ May 23 2008, 19:48) *
В итоге все ВХОДЯЩИЕ байты принимаются на ура.
Но передает SPI (по линии MISO) не то, что я ему говорю, а то что в него пришло от мастера в прошлом цикле передачи (проверял осциллографом).
Подскажите пожалуйста в чем проблема???
Действительно. А чем проблема? SPI это интерфейс для обмена данными. Передача и прием по SPI происходят одновременно. Для того, чтобы что-то slave передал, нужно в буфер положить "это" до начала транзакции. Либо учитывать на стороне master-а, что ответ на команду переданную первым байтом, придет никак не ранее второго байта. А первый принятый байт в текущем фрейме master должен игнорировать.
=GM=
Цитата(Андрей К. Ф. @ May 23 2008, 12:48) *
В итоге все ВХОДЯЩИЕ байты принимаются на ура. Но передает SPI (по линии MISO) не то, что я ему говорю, а то что в него пришло от мастера в прошлом цикле передачи (проверял осциллографом)


Данные на передачу вам надо записывать в регистр SPDR ДО чтения пришедших данных (и в вашем случае, как можно быстрее, пока новая передача не началась, поскольку нет двойной буферизации, как на приём), т.е. примерно так
Код
__interrupt void SPI_STC_vect_handler()
{
  char in_byte;
  SPDR = param.bt[0];
  ...
  in_byte = SPDR;
  ....
}

Цитата
When configured as a Slave, the SPI interface will remain sleeping with MISO tri-stated as long
as the SS pin is driven high. In this state, software may update the contents of the SPI Data
Register, SPDR, but the data will not be shifted out by incoming clock pulses on the SCK pin
until the SS pin is driven low
. As one byte has been completely shifted, the end of Transmission
Flag, SPIF is set. If the SPI Interrupt Enable bit, SPIE, in the SPCR Register is set, an interrupt
is requested. The Slave may continue to place new data to be sent into SPDR before reading
the incoming data
. The last incoming byte will be kept in the Buffer Register for later use.
Андрей К. Ф.
Большое спасибо, сейчас буду пробовать
sysel
Линию порта, которая выход данных MISO необходимо настроить как выход через регистр направлений (DDRx)
Андрей К. Ф.
Ситуация прояснилась. Во всем виновато низкое быстродействие AVR, который работает как слэйв.
Частота кварца 4 МГц, а частота сигнала SCK ~ 78 кГц, получается ~ 51 командный цикл. И за это время обработчик прерывания должен сформировать новый байт на передачу.
Вот такой обработчик исправно выдает 0х55 на выход:
Код
#pragma vector=SPI_STC_vect
__interrupt void SPI_STC_vect_handler()
{
  char in_byte;
  SPDR = 0x55;
  in_byte = SPDR;
}

Значит придется пожертвовать преимуществом SPI - а именно одновременной передачей в обоих направлениях.
=GM=
Цитата(Андрей К. Ф. @ May 26 2008, 06:23) *
Ситуация прояснилась. Во всем виновато низкое быстродействие AVR, который работает как слэйв.
Частота кварца 4 МГц, а частота сигнала SCK ~ 78 кГц, получается ~ 51 командный цикл. И за это время обработчик прерывания должен сформировать новый байт на передачу

Объяснение притянуто за уши, поскольку после завершения обмена возникает ОДНО прерывание, которое может обрабатываться хоть до морковкина заговенья, причём здесь 51 МЦ? А после того, как прерывание обработано и запущена новая передача должно пройти 51*8=408 МЦ до нового прерывания. Вагон времени даже на си.
Цитата(Андрей К. Ф. @ May 26 2008, 06:23) *
Значит придется пожертвовать преимуществом SPI - а именно одновременной передачей в обоих направлениях

Чепуха это всё, 78 кГц это черепашья скорость для спи, ничем не надо жертвовать. Вот здесь обсуждалась передача на скорости Fclk/2, для вашего случая будет 2 МГц (ну или 1 МГц, если ведомое устройство). Обратите внимание на посты #19 и #28. Даже можно написать на си, но лучше приём-передачу оформить подпрограммой на ассемблере.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.