пришлось связать два камня по 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);
}
{
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);
}
{
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)) )
;
}
{
SPDR = data;
while( !(SPSR & (1<<SPIF)) )
;
}
принимаю на тиньке
Код
ISR (USI_OVERFLOW_vect)
{
USISR |= (1<<USIOIF);
usi_in_buf[gBuf_ind_in] = USIDR;
gBuf_ind_in++;
}
{
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(' ');
_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. могу чего-то не знать.