реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Mega8 + DP1205
Alex@ndr
сообщение Mar 26 2008, 14:30
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 20
Регистрация: 22-12-06
Пользователь №: 23 802



Доброго времени суток,
Есть такая проблемка, подключаю трансивер 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 подключён светодиод, при зависании перестаёт моргать
Go to the top of the page
 
+Quote Post
=GM=
сообщение Mar 26 2008, 15:22
Сообщение #2


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(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.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Alex@ndr
сообщение Mar 27 2008, 14:05
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 20
Регистрация: 22-12-06
Пользователь №: 23 802



Цитата(=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;
}
Go to the top of the page
 
+Quote Post
=GM=
сообщение Mar 27 2008, 16:37
Сообщение #4


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(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, просто выждите достаточно времени на передачу и начинайте новую. Кстати, на осцилле вы реально видите выдачу двух байт?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Alex@ndr
сообщение Mar 31 2008, 09:30
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 20
Регистрация: 22-12-06
Пользователь №: 23 802



Действительно, дело было в SS, назначил его выходом и всё заработало.
Спасибо за помощь!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th July 2025 - 00:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01415 секунд с 7
ELECTRONIX ©2004-2016