0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
|
|
1 | |
Соединение по SPI?21.01.2011, 22:59. Показов 9628. Ответов 16
Метки нет (Все метки)
Кто нибудь связывал два контроллера по SPI?
Интересует именно работа контроллера как слэйва. Уже мозг закипел. Сделал схему в симуляторе, вроде все правильно настроил. На слэйв по началу все передавалось, а от слэйва никак. В результате перестало работать все. Что накосячил, понять не могу [48.66 Кб]
0
|
21.01.2011, 22:59 | |
Ответы с готовыми решениями:
16
Соединение STM32 + Cubieboard через SPI ILI9341 SPI DMA, SPI, UART библиотеки SPI Flash 25q128 как SD в SPI mode ? ILI9341 SPI DMA, SPI, UART библиотеки |
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
1. Слэв постоянно держит какие-то данные в буфере, и обновляет их в случае изменения, или после обращения мастера. Мастер же время от времени считывает их оттуда, полагая, что там всегда лежит истинное значение. К примеру, температура на улице, которую считывают раз в 5 минут, а то и в час. 2. Мастер посылает слэву какой - то специальный байт, который слэв, считав, понимает как запрос данных, и кладет в буфер нужный байт. Мастер считывает его или через определенное время, гарантирующее, что слэв успел все сделать, или получив от слэва какое-либо подтверждение готовности (например, по отдельной линии). При этом мастер должен предварительно поместить в свой буфер другой байт, который или будет проигнорирован слэвом (если не относится к специально выделенным байтам), или воспринят как команда, например, отправка следующего байта данных, или завершение сеанса обмена, или повторная отправка данных. Да мало ли чего (что программист заложит). |
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
|
|
22.01.2011, 14:45 | 9 |
Сообщение от SWK
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
SPDR = 77; в результате получаем на следующей итерации коллизию и данные мастеру не попадают. А перед следующей итерацией SPIF стал единичкой?
0
|
0 / 0 / 0
Регистрация: 17.12.2010
Сообщений: 62
|
|
22.01.2011, 21:04 | 11 |
Сообщение от Гарнист
вот примерная картинка операции обмена: 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 + С какого то хрена вообще 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 | |
23.01.2011, 01:24 | |
Помогаю со студенческими работами здесь
17
SPI -> 485->SPI Глючит соединение с интернетом. Не открываются сайты, не удается установить DNS соединение Соединение с прокси-сервером как HTTPS-соединение TLSv1.2 соединение - Клиент приложение - подделываем соединение Соединение с БД (соединение через сеть) Базовое соединение закрыто: Соединение было неожиданно закрыто Базовое соединение закрыто: Соединение было неожиданно закрыто Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |