|
|
  |
ATmega slave передаёт по SPI, Нужно как принимать данные от ведущего так и передавать данные в ведущ |
|
|
|
May 8 2012, 20:44
|
Местный
  
Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023

|
Рассматривается возможность ипользования контроллеров ATmega как ведомых (slave) по SPI. Нужно как принимать данные от ведущего так и передавать данные в ведущий. Про передачу данных по SPI там написано такое: Цитата The system is single buffered in the transmit direction and double buffered in the receive direc- tion. This means that bytes to be transmitted cannot be written to the SPI Data Register before the entire shift cycle is completed. То есть следующий байт нужно писать в регистр данных только после того как предыдущее значение полностью передано. На ведущем это может привести к лишним паузам между байтами. Но в ведомом тактовые импульсы продолжают поступать от ведущего, и чтобы следующий байт от ведомого был передан правильный, его нужно успеть положить в регистр за время до следующего синхроиспульса SCK, то есть за время передачи одного бита? Приём данных ведомым заметно легче, так как там есть дополнительный буфер. Цитата When receiving data, however, a received character must be read from the SPI Data Register before the next character has been completely shifted in. Oth- erwise, the first byte is lost. То есть, для такого обмена наверное ATmega лучше не использовать? Как сделано это в ATxmega не понятно из даташита. А вот в AT91SAM7X например есть дополнительный буфер передачи, и есть бит TDRE который показывает что он свободен.
|
|
|
|
|
May 8 2012, 21:23
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(maksimp @ May 8 2012, 23:44)  Рассматривается возможность ипользования контроллеров ATmega как ведомых (slave) по SPI. То есть, для такого обмена наверное ATmega лучше не использовать? Почему не использовать, если скорость позволяет (F_CPU/4 - максимум)? Нужно задействовать прерывания от SPI: первое прерывание по переходу SS в 0, затем по окончании передачи байта. Чему тут тормозить: Код #pragma vector=SPI_STC_vect __interrupt void SpiComplete() { SPDR=*TxData++; *RxData++=SPDR; } ? Цитата(maksimp @ May 8 2012, 23:44)  Как сделано это в ATxmega не понятно из даташита. Непонятно потому, что они что-то скрывают. Там кроме даташита есть ещё и апнота с примерами кода в master и slave-режиме (AVR1309: Using the XMEGA SPI). И что там может быть непонятного? SPI - наверное самый простой интерфейс для обмена.
|
|
|
|
|
May 9 2012, 08:01
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Цитата ... то есть за время передачи одного бита? Нет, за время передачи одного байта. Работаю в xmege мастером SPI на скорости (CLKper/2). Цитата( @ May 9 2012, 02:02)  В xmege, по-моему, двойной буфер на передачу при работе USART в режиме SPI. Но как слэйв не использую. Пишут что есть: Цитата The Transmitter USART in Master SPI mode includes buffering. The XMEGA SPI has no transmit buffer. Цитата(maksimp @ May 8 2012, 23:44)  На ведущем это может привести к лишним паузам между байтами. 100% Чтоб без пауз, думаю, нужна xmega, USART в режиме мастер SPI и DMA.
|
|
|
|
|
May 9 2012, 11:57
|
Местный
  
Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023

|
Цитата(_Артём_ @ May 9 2012, 01:23)  Почему не использовать, если скорость позволяет (F_CPU/4 - максимум)? Нужно задействовать прерывания от SPI: первое прерывание по переходу SS в 0, затем по окончании передачи байта. Чему тут тормозить: Код #pragma vector=SPI_STC_vect __interrupt void SpiComplete() { SPDR=*TxData++; *RxData++=SPDR; } ? Тормозить будет если поступают прерывания также и из других источников. Если прерывание от SPI придёт во время того как обрабатывается другое прерывание, то выполнить SPDR=*TxData++; вовремя она может и не успеть. Цитата(_Артём_ @ May 9 2012, 01:23)  Там кроме даташита есть ещё и апнота с примерами кода в master и slave-режиме (AVR1309: Using the XMEGA SPI). Спасибо, посмотрел, в xmega это устроено так же как и в простой mega - двойного буфера нет. Может быть только можно с DMA сделать. Цитата(zombi @ May 9 2012, 12:01)  Чтоб без пауз, думаю, нужна xmega, USART в режиме мастер SPI и DMA. Речь идёт про slave. USART в режиме slave SPI не умеет работать. Так что во избежание, видимо лучше сразу иметь в виду какой-нибудь ARM для такого применения.
|
|
|
|
|
May 9 2012, 12:26
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(maksimp @ May 9 2012, 14:57)  Тормозить будет если поступают прерывания также и из других источников. Если прерывание от SPI придёт во время того как обрабатывается другое прерывание, то выполнить SPDR=*TxData++; вовремя она может и не успеть. Нужно в другом прерывании разрешить прерывания. Код #pragma vector=INT_vect __interrupt void AnyInterrupt() { __enable_interrupt(); // остальные действия } Цитата(maksimp @ May 9 2012, 14:57)  Речь идёт про slave. USART в режиме slave SPI не умеет работать. У xmega SPI slave может работать совместно с DMA. Цитата(maksimp @ May 9 2012, 14:57)  Так что во избежание, видимо лучше сразу иметь в виду какой-нибудь ARM для такого применения. Лучше суперкомпьютер тогда сразу.
|
|
|
|
|
May 14 2012, 10:22
|
Частый гость
 
Группа: Участник
Сообщений: 147
Регистрация: 25-09-08
Пользователь №: 40 467

|
Цитата Тормозить будет если поступают прерывания также и из других источников. Если прерывание от SPI придёт во время того как обрабатывается другое прерывание, то выполнить SPDR=*TxData++; вовремя она может и не успеть. В таком случае целесообразно в программе ведущего предусмотреть паузу перед выдачей следующего байта. Величину паузы выбрать достаточной, для того что бы ведомый надёжно успевал загружать данные. В развитие этой темы. О протоколах передачи данных для подобных задач. Для организации передачи данных по SPI между одним ведущим и несколькими ведомыми существуют какие либо стандартные протоколы? Или каждый разработчик пишет свой протокол? Особенностью задачи является то, что сигнал SS один для всех ведомых, т.е. ведущий задаёт адрес ведомого в протоколе.
|
|
|
|
|
May 14 2012, 12:29
|
Частый гость
 
Группа: Участник
Сообщений: 147
Регистрация: 25-09-08
Пользователь №: 40 467

|
Цитата Обычно SS у каждого slave свой - соответственно адрес в протоколе не нужен. Это и есть стандартное использование SPI. Да, я понимаю что стандартное использование SPI именно такое, но у меня в шине SPI только 4 провода, и больше просто нет. Поэтому придётся адрес slave передавать в посылке. А что на счёт стандартных протоколов, они существуют?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|