Глюк с SPI (виснет на ожидании) Не подскажет ли кто-нибудь в каких случаях программа может виснуть на ожидании окончания SPI приема или передачи? Встречался ли кому-нибудь такой случай, и в какой ситуации он может наблюдаться?
До сих пор мне казалось, что в режиме Master (когда CLK-сигнал генерирует МК) такого в принципе не может быть никогда. И, тем не менее, сама натолкнулась на такой случай. SPI прекрасно работает (!), но только до тех пор, как МК получает связь через USB (AT90USB64 - имеет USB-интерфейс на борту). SPI и USB совершенно разные интерфейсы и влиять друг на друга они не должны. И тем не менее, ровно через 14 секунд после того, как компьютер "узнал" USB-подключение SPI-обмен (используется для получения данных с АЦП) виснет на строке ожидания while(). При этом никакая иная передача по USB не идет, кроме стандартных ответов, положенных при начале работы. Причем, SPI загибается уже после того, как эта процедура закончилась. Разъятие USB кабеля после зависания не помогает.
Самое удивительное, что работоспособность SPI не востановливается даже после ресета по watсhdоg'у! И только кратковременное снимание питания приводит схему в чувство.
Программу связи по USB сначала брала из демонстрашки из апликайшен на сайте Atmel, а потом "USB библиотеку под AT90USBxxx", предложенную на этом форуме OlegPowerC (
http://caxapa.ru/128010.html?todo=full ). Результат один и тот же.
Сначала я искала ошибку у себя в программе, но после того, как однажды схема проработала 10 минут подряд или зависла только после этого, я стала подозревать что-то аппаратное.
Возможен ли случай зависания SPI по ожиданию, а если да, то в каких случаях?
// AT90USB64, IAR AVR 5.11
DDRB = 0x36; // PORTB_DIRECTION, out: PB1,PB2,PB4,PB5
// SPI
SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<SPR0); // enable SPI + master + 1/16 freq
SPSR |= SPI2X; // 1/8 freq
......
void Wr_SPI( unsigned char val)
{
SPDR = val;
while( !(SPSR & (1<<SPIF))); // здесь виснет
}
unsigned char Rd_SPI()
{
SPDR = 0;
while( !(SPSR & (1<<SPIF))); // здесь виснет
return SPDR;
}