Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/48: Рейтинг темы: голосов - 48, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
1

Соединение по SPI?

21.01.2011, 22:59. Показов 9628. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Кто нибудь связывал два контроллера по SPI?
Интересует именно работа контроллера как слэйва. Уже мозг закипел.
Сделал схему в симуляторе, вроде все правильно настроил. На слэйв по началу все передавалось, а от слэйва никак. В результате перестало работать все.
Что накосячил, понять не могу

[48.66 Кб]
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.01.2011, 22:59
Ответы с готовыми решениями:

Соединение STM32 + Cubieboard через SPI
Добрый день! Соединяю платы STM32 и Cubieboard2 через SPI. Скорость 10МГц. Может ли длинна...

ILI9341 SPI DMA, SPI, UART библиотеки
Доброго времени, форумчане... Посоветуйте библиотек плиз... 0) Либа для работы с контроллером по...

SPI Flash 25q128 как SD в SPI mode ?
ну задача использовать spi флешки вместо sd карт. Как это зделать? Будет ли работать если...

ILI9341 SPI DMA, SPI, UART библиотеки
Доброго времени, форумчане... Посоветуйте библиотек плиз... 0) Либа для работы с контроллером по...

16
0 / 0 / 1
Регистрация: 22.01.2010
Сообщений: 4,000
21.01.2011, 23:04 2
А в чем там проблема то?
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
21.01.2011, 23:48 3
Да, забыл сказать. Если кто будет компилировать:
make spi_test
должны создаться
spi_test_m.elf - код запуска мастера
spi_test_s.elf - код слэйва.
Ну и в Proteust нужно поменять пути загрузки программ.
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 01:31 4
одну дыру сам нашел.
В мастере не включил на SPI режим мастера. естественно и тактирования нет.
...
int main(void)
{
uart_init(0,0,0);
//Initiotyzotion
DDRB |= 1 << PB3 | 1 << PB5; // mosi, sck output
DDRB &= ~(1 << (PB4)); // MISO is input
SPCR = ( 1<<SPE )|( 1 << MSTR );
^^^^^^^^^^^^^^^^^^^^^
SS_PASSIV();
DDRC |= 1 << PC0;
uart_txs("Master stort\r");

ну один хрен, слэйв принимает чушь и отправляет чушь.
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 13:05 5
Теперь хоть восстановил, что было и можно поподробнее описать проблемку.
мастер в цикле, с паузой в 1.5 секунды посылает слэйву какой то байт.
Слэейв принимает этот байт и отсылает обратно. Это первоначальная идея.
В реальности мастер посылает байт, но слэйв принимает только 255. то есть инфа где-то теряется. Самое интересное, что прерывание срабатывает, флаг коллизии погашен.
соединил так:
m.MOSI - s.MISO
m.MISO - s.MOSI
может нужно было все параллельно цеплять ?
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 13:23 6
млять. идиот. точно.
ведь это аппаратный SPI. у него нельзя ничего менять, все железно прошито.
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 13:35 7
В общем удалось добиться приема слэйвом байта. Срабатывает прерывание, байт верен. Теперь на следующем цикле записи мастером своего байта должно, слэйв первоначально должен ответить. как это делать, с использованием прерывания?
без записи мастером чего-либо в свой регистр данных передача не пойдет, так как он управляет тактированием. А в слэйве, после записи чего либо в регистр данных, получаем коллизию данных, о чем свидетельствует флаг ?
0
SWK
22.01.2011, 14:20 8
Цитата Сообщение от svd71
В общем удалось добиться приема слэйвом байта. Срабатывает прерывание, байт верен. Теперь на следующем цикле записи мастером своего байта должно, слэйв первоначально должен ответить. как это делать, с использованием прерывания?
без записи мастером чего-либо в свой регистр данных передача не пойдет, так как он управляет тактированием.
По SPI всегда идет передача в обе стороны, независимо от того, передает мастер или читает. Фактически, содержимое буферов мастера и слэва меняются друг с другом. Чтобы слэв что-то послал мастеру, надо, чтобы этот байт уже лежал в буфере слэва. Возможные варианты:
1. Слэв постоянно держит какие-то данные в буфере, и обновляет их в случае изменения, или после обращения мастера. Мастер же время от времени считывает их оттуда, полагая, что там всегда лежит истинное значение. К примеру, температура на улице, которую считывают раз в 5 минут, а то и в час.

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

А в слэйве, после записи чего либо в регистр данных, получаем коллизию данных, о чем свидетельствует флаг ?
Это происходит, если в буфере слэва был принятый, но несчитанный байт. Его надо было считать. Или сбросить флаг.
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 14:45 9
Цитата Сообщение от SWK
По SPI всегда идет передача в обе стороны, независимо от того, передает мастер или читает. Фактически, содержимое буферов мастера и слэва меняются друг с другом. Чтобы слэв что-то послал мастеру, надо, чтобы этот байт уже лежал в буфере слэва. Возможные варианты:
1. Слэв постоянно держит какие-то данные в буфере, и обновляет их в случае изменения, или после обращения мастера. Мастер же время от времени считывает их оттуда, полагая, что там всегда лежит истинное значение. К примеру, температура на улице, которую считывают раз в 5 минут, а то и в час.

2. Мастер посылает слэву какой - то специальный байт, который слэв, считав, понимает как запрос данных, и кладет в буфер нужный байт. Мастер считывает его или через определенное время, гарантирующее, что слэв успел все сделать, или получив от слэва какое-либо подтверждение готовности (например, по отдельной линии). При этом мастер должен предварительно поместить в свой буфер другой байт, который или будет проигнорирован слэвом (если не относится к специально выделенным байтам), или воспринят как команда, например, отправка следующего байта данных, или завершение сеанса обмена, или повторная отправка данных. Да мало ли чего (что программист заложит).
Все так и есть. И с обменом все ясно но в даташите написано так:
Byt 6 – WCOL: Write COLlision Flag
The WCOL bit is set if the SPI Data Register (SPDR) is written during a data transfer. The
WCOL bit (omd the SPIF bit) are cleared by first reodyng the SPI Status Register wyth WCOL set,
omd then accessing the SPI Data Register.
То есть коллизия происходит во время записи передачи данных (подразумевается в регистр SPDR). Бит очищается при первом чтении первом чтении SPSR и во время доступа к SPDR.
То есть получается, при прямом чтении и записи на слэйве:
Код
      j = SPDR;
SPDR = 77;
в результате получаем на следующей итерации коллизию и данные мастеру не попадают.
0
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
22.01.2011, 20:45 10
Цитата Сообщение от svd71
То есть получается, при прямом чтении и записи на слэйве:
Код:
j = SPDR;
SPDR = 77;

в результате получаем на следующей итерации коллизию и данные мастеру не попадают.
А перед следующей итерацией SPIF стал единичкой?
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 21:04 11
Цитата Сообщение от Гарнист
А перед следующей итерацией SPIF стал единичкой?
нет. вроде и не должен. как правильно заметил SWK, по логике вещей, должно работать так. слэейв засовывает свои данные в этот сдвиговый регистр. мастер засовывает свои. так как мастер является управляющим, то он, задавая тактирование (всех участников), сдвигает данные в своем регистре, попутно читая данные переданные слэйвом. у слэйва такая же петрушка и движение данных между двух регистров напоминает кольцо. естественно и флаг SPIF должен выставляться один раз.
вот примерная картинка операции обмена: http://www.ermicro.com/btog/wp-content/ ... spi_03.jpg
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 22:01 12
Были у меня подозрения, что раз не читает мастер, то что то у него с режимом чтения не правильно: или DDR неправильно выставлен на мастере или на слэйве или протеус глючит, не успевает переключать. Для первых двух бяк записываю жесткие числа в DDR. Для третьей - понизил частоту обмена SPI.
Код для мастера:
Код
int main(void)
{
uart_init(0,0,0);
//Initiotyzotion
DDRB  |= 1 << PB3 | 1 << PB5; // mosi, sck output
DDRB &= ~(1 << (PB4)); // MISO is input

////////DDRB &=~((1 << PB3)|(1 << PB4)|(1 << PB5)|(1 << PB2));
DDRB= 0x2F;

SPCR = ( 1<<SPE )|( 1 << MSTR )    |(1 << SPR1)|(1 << SPR0);
SPSR |= ( 1 << SPI2X );

SS_PASSIV();
DDRC |= 1 << PC0;
uart_txs("Master stort\r");
//
unsykned char j = 0;
unsykned char k,i;
//   j = PINB;uart_txh(j);for(;;);

for(;;)
{
_delay_ms(1500);
uart_txi(j);
uart_txs("=");
SS_AKTIVE(); //S_SS = 0
SPDR = j++;
while(!( SPSR & ( 1 << SPIF ) ));
k = SPSR;
SS_PASSIV(); //S_SS = 1
uart_txi(k);
uart_txs("\r");
}
}
для слэйва:
Код
int main(void)
{
//Initiotyzotion
//DDRB &= ~(1 << (PB4)); // MISO is input
//DDRB &= ~(1 << (PB3)); // MISO is input
//SPSR |= ( 1 << SPI2X );
DDRB |= 1 << PB4;
DDRB &=~((1 << PB3)|(1 << PB5)|(1 << PB2));
DDRB = 0x13;

SPCR = /*(1 << SPIE) |*/ (1 << SPE);//SPI Initiotyzotion
//DDRB = 0;
//DDRB  &= ~(1 << PB2) ;
uart_init(0,0,0);
uart_txs("Slave stort\r");
//   PORTB = 0xFF;for(;;);
//sei();

unsykned char i,j,k;
for(;;)
{
SPDR = 111;
i = SPSR;
while(!( SPSR & ( 1 << SPIF ) ));
k = SPSR;
j = SPDR;
uart_txh(i);uart_txh(k);uart_txs(" ");
uart_txi(j);
uart_txs(" +\r");
}
}
протокол терминала мастера:
Код
Master stort
0=129
1=129
2=129
3=129
4=129
5=129
6=129
7=129
8=129
9=129
первое число то, что он послал, второе, что принял.

Слэйва. У него, посылается для простоты десятичное число 111:
Код
Slave stort
0080 0 +
0080 1 +
0080 2 +
0080 3 +
0080 4 +
0080 5 +
0080 6 +
0080 7 +
0080 8 +
0080 9 +
первые цифры в шестнадцатеричном виде значение SPSR до обмена (2 знака) и после обмена (еще 2 знака). Потом, в десятеричном, что принял. Отправляет он жестко 111. Прерывания все отключены.
С какого то хрена вообще 129 принимается.
0
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
22.01.2011, 22:42 13
Флаг SPIF выставляется (и на мастере и на слейве) всякий раз, как только один байт проедет через SPI. Иначе как удостовериться в завершении передачи и отделить один байт от другого? А в вашем наСИлии, увы я не копенгаген.
На пальцах - так: <ol style="list-style-type: decimal"><li>сделали инит и мастеру и слейву</li><li>слейв помещает данные в SPDR, и курит. (или не помещает, от него тут ничего не зависит)</li><li>мастер засовывает данные в SPDR, при этом какбэ сам собой начинается обмен данными.</li><li>По завершению обмена, и у мастера и у слейва устанавливается SPIF. </li><li>Мастер может забрать принятые данные данные (от этого SPIF мастера сбросился)</li><li>Слейв может забрать принятые данные(от этого SPIF слейва сбросился), и поместить данные для отправки. </li><li>Цикл обмена завершен, для начала нового цикла, идём на п.3 </li></ol>
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 22:49 14
ну не знал, что столица дании теперь означает "не хочу разбирать в тексте". хотя там действительно 3 строчки.
именно так и сделано. и так происходит. тут обнаружил такую вещь: если мастера у мастера повесить ногу MISO на землю или на питание, то он должен принимать 00 или 255. Но он, гад, жестко принимает 129.
0
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,283
22.01.2011, 22:52 15
Может глюк протеуса?
0
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
22.01.2011, 23:00 16
Гарнист, спасибо! нашел последний косяк!

Тоже так думал. даже коллеге скинул попробовать. у него другая версия. Но по наезду горниста, решил еще в код добавить отображение статусов на мастере. и нашел, что в терминал и вывожу значения статуса, а не принятое значение.
0
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
23.01.2011, 01:24 17
Столица Динии пишется с большой буквы.
0
23.01.2011, 01:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.01.2011, 01:24
Помогаю со студенческими работами здесь

SPI -> 485->SPI
Есть необходимость переводить SPI на 485 интерфейс. Хотел бы уточнить, драйвер 485 сажать напрямую...

Глючит соединение с интернетом. Не открываются сайты, не удается установить DNS соединение
Добрый день! Помогите разобраться с проблемой!!! Есть сеть из 30 ПК, последнее 7 дней стал глючить...

Соединение с прокси-сервером как HTTPS-соединение
Доброго времени суток! Мне нужно, чтобы соединение с прокси-сервером выполнялось по SSL или TLS...

TLSv1.2 соединение - Клиент приложение - подделываем соединение
Здравствуйте уважаемые эксперты. У меня к вам вопрос. Есть приложение (на моем ПК), это приложение...

Соединение с БД (соединение через сеть)
Доброго времени суток. Помогите пожалуйста новичку. Создал в Visual Studio Net 2010 C++ проект с...

Базовое соединение закрыто: Соединение было неожиданно закрыто
Здравствуйте. У меня возникла такая проблема, что при вызове метода soap веб-сервиса соединение...

Базовое соединение закрыто: Соединение было неожиданно закрыто
Недавно написал лаунчер для своего сервера, сделал там и регистрацию. Для этого зарегистрировал...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru