Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Mega8 + DP1205
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Alex@ndr
Доброго времени суток,
Есть такая проблемка, подключаю трансивер DP1205 к AtMega8 и при обращении по SPI, Mega зависает.
Зависание происходит абсолютно непредсказуемо, иногда сразу после включения, иногда после нескольких минут работы.
Программу(WinAVR) максимально упростил, читаю и пишу в один из регистров, но всё равно виснет. может SPI неправильно настроен? Помогите разобраться плиз
Код
#include <avr/io.h>
#include <util/delay.h>

void init(void)  //инициализация
{
DDRC |= (1 << 5); //сделать выходом
DDRD |= (1 << 4); //сделать выходом
DDRD |= (1 << 5); //сделать выходом
PORTD |= (1 << 4);  //установка в 1 NSS_CONFIG
PORTD |= (1 << 5);  //установка в 1 NSS_DATA
DDRB |= (1 << 3);  //MOSI сделать выходом
DDRB |= (1 << 5);  //SCK сделать выходом
SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR0);
}

void WriteConfig(char adres, char value)
    {
    adres = ((adres << 1) & 0x3F) | 0x01;
    PORTD |= (1 << 5);  //установка в 1 NSS_DATA
    PORTD &= ~(1 << 4);  //активация NSS_CONFIG    
    SPDR=adres;
    while(!(SPSR & (1 << SPIF)));
    SPDR=value;
    while(!(SPSR & (1 << SPIF)));
    PORTD |= (1 << 4);  //деактивация NSS_CONFIG
    }

char ReadConfig(char adres)
    {    
    char value = 0;
    PORTD |= (1 << 5);  //установка в 1 NSS_DATA
    adres = ((adres << 1) & 0x7F) | 0x41;
    PORTD &= ~(1 << 4);  //активация NSS_CONFIG
    SPDR=adres;
    while(!(SPSR & (1 << SPIF)));
    value = SPDR;
    PORTD |= (1 << 4);  //деактивация NSS_CONFIG
    return value;
}


void main (void)
{
char Data;
init();  
while(1)
{
_delay_ms(100);
Data = ReadConfig(4);
if (Data > 0)
{
WriteConfig(4, 0x00);
PORTC |= (1 << 5);
}
else
{
WriteConfig(4, 0x01);
PORTC &= ~(1 << 5);
};
}; //конец цикла
} //конец

P.S. На PORTC 5 подключён светодиод, при зависании перестаёт моргать
=GM=
Цитата(Alex@ndr @ Mar 26 2008, 14:30) *
Зависание происходит абсолютно непредсказуемо, иногда сразу после включения, иногда после нескольких минут работы[code]
void WriteConfig(char adres, char value)
{
adres = ((adres << 1) & 0x3F) | 0x01;
PORTD |= (1 << 5); //установка в 1 NSS_DATA
PORTD &= ~(1 << 4); //активация NSS_CONFIG
SPDR=adres;
while(!(SPSR & (1 << SPIF)));
SPDR=value;
while(!(SPSR & (1 << SPIF)));
PORTD |= (1 << 4); //деактивация NSS_CONFIG
}

В подпрограмме WriteConfig у вас не сбрасывается SPIF после второго оператора while(!(SPSR & (1 << SPIF))). Попробуйте добавить фиктивное чтение из регистра SPDR.
Alex@ndr
Цитата(=GM= @ Mar 26 2008, 17:22) *
В подпрограмме WriteConfig у вас не сбрасывается SPIF после второго оператора while(!(SPSR & (1 << SPIF))). Попробуйте добавить фиктивное чтение из регистра SPDR.

Не помогло, всё равно виснет.
Определил где именно, на ожидании завершения работы SPI. Причем, то в WriteConfig, то в ReadConfig wacko.gif
Код
void WriteConfig(char adres, char value)
{
adres = ((adres << 1) & 0x3F) | 0x01;
PORTD |= (1 << 5);
PORTD &= ~(1 << 4);
SPDR=adres;
while(!(SPSR & (1 << SPIF)));
SPDR=value;
while(!(SPSR & (1 << SPIF)));  //ЗАВИСАЕТ ЗДЕСЬ
adres = SPDR;
PORTD |= (1 << 4);
}

char ReadConfig(char adres)
    {    
    char value = 0;
    PORTD |= (1 << 5);  
    adres = ((adres << 1) & 0x7F) | 0x41;
    PORTD &= ~(1 << 4);  
    SPDR=adres;
    while(!(SPSR & (1 << SPIF)));  // ЗАВИСАЕТ ЗДЕСЬ
    value = SPDR;
    PORTD |= (1 << 4);  
    return value;
}
=GM=
Цитата(Alex@ndr @ Mar 27 2008, 14:05) *
Не помогло, всё равно виснет.
Определил где именно, на ожидании завершения работы SPI. Причем, то в WriteConfig, то в ReadConfig
Код
void WriteConfig(char adres, char value)
{
adres = ((adres << 1) & 0x3F) | 0x01;
PORTD |= (1 << 5);
PORTD &= ~(1 << 4);
SPDR=adres;
while(!(SPSR & (1 << SPIF)));
SPDR=value;
while(!(SPSR & (1 << SPIF)));  //ЗАВИСАЕТ ЗДЕСЬ
adres = SPDR;
PORTD |= (1 << 4);
}

Не должно быть так, вторая выдача ничем не отличается от первой. Если только SPIF не торчит всё время в 1 по какой-то причине.

Это может зависеть от состояния SS. Поставьте его на вывод на всякий случай.

Если не поможет, попробуйте обойтись без ожидания готовности SPIF, просто выждите достаточно времени на передачу и начинайте новую. Кстати, на осцилле вы реально видите выдачу двух байт?
Alex@ndr
Действительно, дело было в SS, назначил его выходом и всё заработало.
Спасибо за помощь!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.