|
Связь mega8 -> t2313 по SPI, работать работает, но в чем же соль |
|
|
|
Sep 2 2009, 15:48
|

Участник

Группа: Участник
Сообщений: 32
Регистрация: 28-10-05
Из: Ukraine, Khmelnitsky
Пользователь №: 10 246

|
здравствуйте. пришлось связать два камня по SPI. передача данных в одну сторону Mega8 (master) --> tiny2313. инициализацию мастера и слейва сделал по ДШ. mega8: Код void SPIinit(void) { DDRB |= (1<<PIN_SPI_MOSI) | (1<<PIN_SPI_SCK) | (1<<PIN_SPI_SS); SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); } t2313: Код void USIinit(void) { DDRB = (1<<USI_PIN_DO); PORTB |= (1<<USI_PIN_DI) | (1<<USI_PIN_SCK); USICR = (1<<USIOIE) | (1<<USIWM0) | (1<<USICS1); } отправляю байт Код void SPI_send_byte(char data) { SPDR = data; while( !(SPSR & (1<<SPIF)) ) ; } принимаю на тиньке Код ISR (USI_OVERFLOW_vect) { USISR |= (1<<USIOIF);
usi_in_buf[gBuf_ind_in] = USIDR; gBuf_ind_in++; } после получения каждого нового символа передаю его слэйвом по UART. так вот, один байт таким способом я принять могу, но если посылается несколько байт -- получается каша. правильно принимается только последний символ из всего потока. ставлю после передачи каждого символа задержку -- Код SPI_send_byte('b'); _delay_loop_1(48); SPI_send_byte('a'); _delay_loop_1(48); SPI_send_byte('d'); _delay_loop_1(48); SPI_send_byte(' '); -- слэйв принимает нормально. да, если нужно то mega запущена на 16МГц, tiny2313 -- 8МГц. клок на SPI на мастере делится на 16. если делить на 128 то нормально принимает при значении задержки между символами приблизительно 3мкс (начинает принимать нормально при _delay_loop_1(15)). изначально, было две версии: 1. передача очередного байта начинается до завершения передачи предыдущего. думаю этот вариант исключается поллингом флага SPIF, и флага WCOL. (?) 2. тинька не успевает обрабатывать поток данных. этот вариант тоже вроде как исключил -- понизил частоту клока, сократил до минимума обработчик прерывания. пробовал даже после 4-5 принятых в ОЗУ символов запрещать прерывания на слэйве и спокойненько выдавать буфер в UART. теоретически, могу оставить задержки между символами. но хочется же знать в чем соль. хотя бы на чьей стороне? мастер/слэйв? да, мой первый проэкт именно на C. могу чего-то не знать.
|
|
|
|
|
Sep 3 2009, 20:28
|

Участник

Группа: Участник
Сообщений: 32
Регистрация: 28-10-05
Из: Ukraine, Khmelnitsky
Пользователь №: 10 246

|
Цитата(_Pasha @ Sep 3 2009, 08:59)  Приведите пож код, каким образом Вы его передаете по UART. код стандартный, вытянутый из ДШ Код void USART_transmit_char(char c) { while ( !( UCSRA & (1 << UDRE)) ) ; UDR = c; }
...
int main(void) { counter = 0; for(;;) { while (counter < gBuf_ind_in) USART_transmit_char(usi_in_buf[counter++]); if (counter == IN_BUF_LGTH) counter = 0; } } Цитата Поставьте последовательно с клоками резистор 33 ома ближе к меге8. поставил. картина та же. Цитата Я что-то не увидел из текста - а вы SS-ом дёргаете? нет, SS-ом не дергаю. если честно, смысла в этом я не видел. насколько я понял из ДШ, передача каждого байта пакета не сопровождается дерганьем линии SS. SS сбрасывается вначале пакета данных и устанавливается снова по окончании передачи того-же пакета. Цитата After shifting one byte, the SPI clock gener- ator stops, setting the end of Transmission Flag (SPIF). If the SPI interrupt enable bit (SPIE) in the SPCR Register is set, an interrupt is requested. The Master may continue to shift the next byte by writing it into SPDR, or signal the end of packet by pulling high the Slave Select, SS line.
|
|
|
|
|
Sep 4 2009, 10:56
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(SasaVitebsk @ Sep 4 2009, 11:35)  Посмотрел - действительно. Посмотрел у себя - тоже угадали. Мда-с... Вот здесьобсуждали тиньку 261. Теперь получается, что она может быть только мастером. Вкратце картина такая: ATTINY261 без кварца будет генерить синус с хорошей долговременной стабильностью, а некий управляющий модуль в качестве слейва будет отдавать все, что надо для генерации, получая попутно все необходимое с АЦП для расчета. Режим передачи непрерывный, пакетами по 8-10 байт(еще не решил) И вот тут немного ниасилю: как же все-таки синхронизировать таймеры такого "мастера"? Это при том, что нарушать работу ШИМ "низзя", а использовать phase & freq correct pwm не хватит ног у тиньки. Т.Е синхронизация все равно по каналу данных пойдет. Есть ли у кого советы?
|
|
|
|
|
Sep 4 2009, 12:07
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(DpInRock @ Sep 4 2009, 14:51)  А у автора топика такая система отсутствует как класс. Он надеется исключительно на авось. Добавлю критики  Код ISR (USI_OVERFLOW_vect) { USISR |= (1<<USIOIF); usi_in_buf[gBuf_ind_in] = USIDR;// отсутствует проверка индекса if (gBuf_ind_in < IN_BUF_LGTH) gBuf_ind_in++; //хотя бы так } И, к тому же, где входной индекс обнуляться будет? Вообще-то это делается пресловутой очередью, поминаемой в форуме с завидным постоянством. ЗЫ Цитата(DpInRock @ Sep 4 2009, 14:51)  на тиньке - это вход прерывания, по которому быстренько сбрасывается счетчик бит в SPI (это по спадающему фронту). Ну а по нарастающему - программе сообщается, что байт готов к употреблению. Имхо, такое у меня не прокатит. Вот для случая кварцованного мастера и бескварцевого слейва синхронизацию обеспечит мастер, начиная передачу в строго определенные моменты времени. Тогда можно отследить с помощью PCINTxx начало передачи - и дело сделано. А для наоборот - вот так
|
|
|
|
|
Sep 4 2009, 13:29
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Если честно, то настораживает то, что у автора топика, правильно передаётся именно последний байт. Если бы у него происходил срыв синхронизации, то у него правильно бы передавались первые несколько, а последнего он бы вообще не получил.
Исходя из того, что у автора правильно принимается последний байт, то смею предположить, что предыдущие портятся при передачи от SPI к USART. Это может происходить по причине сопоставимых скоростей и не верной логике передачи. При отсутствии промежуточного буфера с диагностикой заполнения, необходимо синхронизироваться по медленному потоку.
Ну а на грабли с SS, он похоже наступит несколько позднее.
Так, я делал bootloader на SPI с мастером на IBM по 3 проводам. Пришлось вводить несколько принципов синхронизации пакета, для обеспечения достоверности передачи информации.
При тестировании системы (проверял) запаянной на одной плате, с длиной проводников 10-20мм проблем не возникало. При тестировании в течении пары часов. Но, надо понимать, что один сбой - и всё. Система уже сама никогда не засинхронизируется вновь. Поэтому - не надо конечно каждый байт, но вначале пакета - синхронизация должна быть обязательно.
Автор топика в этом обязательно убедится при сколь-нибудь серьёзном тестировании устройства.
|
|
|
|
|
Sep 4 2009, 13:36
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Цитата Если честно, то настораживает то, что у автора топика, правильно передаётся именно последний байт. Это как раз совершенно нормально. Цитата Вот для случая кварцованного мастера и бескварцевого слейва синхронизацию обеспечит мастер, начиная передачу в строго определенные моменты времени А вот тут вы чего-то недопонимаете. "Строго определенные моменты времени" порождаются системой синхронизации. А не наоборот, как выражаетесь вы.
--------------------
On the road again (Canned Heat)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|