Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AVR и W5500
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Stolbov
Всем добрый день!

Я продолжаю изучать программирование микроконтроллеров, и в качестве следующей цели выбрал организацию простого web-сервера на AVR.
Я изучил основные моменты инициализации в официальной документации, плюс нашёл в интернете несколько примеров (правда, все они под STM32), но у меня всё равно не получается его инициализировать даже на обычный пинг. Вот как выглядит сам девайс:


Общаюсь я с ним по SPI. В документации сказано, что сначала передаётся старший байт адреса назначения, потом младший, затем контрольная фаза и, на конец, сами данные. Сейчас я приведу небольшой пример, как я всё это реализовываю:

Код
uint8_t opcode = 0; //Переменная для хранения опкода
uint8_t ip[4] = {192,168,1,197}; //ip адрес

//Данные, необходимые для формирования контрольной фазы
#define BSB_COMMON 0x0000     //bsb блок
#define WRITE 1                         //бит записи
#define READ 0                           //бит чтения
#define OM_FDM0 0x00 //Режим передачи данных переменной длинны

#define SIPR0 0x000F //Адреса регистров w5500, в которых хранится ip адрес
#define SIPR1 0x0010
#define SIPR2 0x0011
#define SIPR3 0x0012

//Провожу инициализацию SPI
void spi_init()                    
{
    DDRB = (1<<PORTB7)|(1<<PORTB5)|(1<<PORTB4); //Clock - 7, MOSI - 5, Chip Select - 4. Всё на выход. MISO (6) - на вход.
    SPCR = (1<<MSTR)|(1<<SPE)|(1<<SPR0); //Мастер, SPI включен.
}

//Функция записи данных в чип
void w5500_write(uint16_t addr, uint8_t opcode, uint8_t data) //Функция записи данных в регистр
{
        selectW5500();        //Выбрать чип
    unsigned char i;       //счётчик                  
    uint8_t buf[4];         //буфер для данных
    buf[0] = (uint8_t)(addr >> 8);   //передаём старшую часть адреса
    buf[1] = (uint8_t)(addr);            //передаём младшуя часть адреса
    buf[2] = opcode;                        //передаём контрольную фазу
    buf[3] = (uint8_t)(data);            //передаём данные
    
    for(i=0;i<4;i++)                       //цикл передачи данных
    {
        SPDR = buf[i];
        while(!(SPSR&(1<<SPIF)));
    }    
        deselectW5500();
}


Не знаю, почему, но мне кажется, что я что-то делаю не так с передачей данных. Я привёл пример записи одного
байта данных в регистр, отвечающий за хранение ip адреса. Формирование контрольной фазы выглядит так:

Код
opcode = (BSB_COMMON<<3)|(WRITE<<2)|OM_FDM0;


Функции выбора чипа в этом посте я писать не стал, так как там происходит просто "притягивание" линии к 0, а потом "отпускание".

Я постарался как можно короче изложить свою проблему, но, тем не менее, указав важные детали. Буду рад
любой помощи или совету.

Заранее спасибо.
aiwa
opcode должен быть первым в последовательности, затем адрес , потом данные.
Stolbov
Цитата(aiwa @ May 14 2018, 18:35) *
opcode должен быть первым в последовательности, затем адрес , потом данные.


Большое спасибо за ответ! Завтра я обязательно попробую так сделать. Скажите, пожалуйста, а откуда у Вас такая информация?
Просто в даташите SPI Frame начинается с адреса, и я руководствовался именно этой схемой.
aiwa
Цитата(Stolbov @ May 14 2018, 21:22) *
Скажите, пожалуйста, а откуда у Вас такая информация?

Извините, похоже я ввел Вас в заблуждение. Написал по инерции для наиболее распространенного варианта.



Stolbov
Если кому-нибудь интересно: все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться, и выдаёт свои стандартные настройки. Буду разбираться дальше.
Сергей Борщ
QUOTE (Stolbov @ May 18 2018, 12:09) *
все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться
Я работал с 5100, по параллельной шине и очень давно. В порядке предположения: а порядок байт при записи "ip и прочего" не попутан случайно?
Stolbov
Вот так выглядит "кадр" передачи данных SPI:




Функцию записи я немного переписал:

Код
void w5500_write(uint16_t addr, uint8_t op, uint8_t data) //Функция записи данных в регистр
{
    char MSB = (addr>>8);
    char LSB = (addr);
    char opcode = op;
    char sdata = data;
    SPDR = MSB;
    while(!(SPSR&(1<<SPIF)));
    SPDR = LSB;
    while(!(SPSR&(1<<SPIF)));
    SPDR = opcode;
    while(!(SPSR&(1<<SPIF)));
    SPDR = sdata;
    while(!(SPSR&(1<<SPIF)));
}


Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные. В чём может быть причина неудачи, я не знаю. Само собой, перед записью данных я делаю два сброса, как это сказано в даташите: хард и софт.
Сергей Борщ
QUOTE (Stolbov @ May 18 2018, 12:49) *
Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные.
Так вот в этих "самих данных" не может быть попутаны байты? Вы уверены, что в регистры попадает "192.168.0.1", а не "1.0.168.192"? У W5100 и предыдущих данные хранились в виде больших индейцев (big endian), все известные мне компиляторы для AVR используют маленьких индейцев.
Stolbov
Думаю, что всё записывается правильно. Каждый байт записывается по своему собственному адресу.
192 пишется в 0x0001, 168 в 0x0002 и т.д. Я попробовал прочитать все адреса и получил правильный порядок байтов.
Сергей Борщ
QUOTE (Stolbov @ May 18 2018, 14:08) *
192 пишется в 0x0001, 168 в 0x0002 и т.д.
Да, я именно это и имел ввиду. Раз здесь все правильно - остается только схема. Потому что если у вас в MR биты RST и PB сброшены, то после записи GAR, SUBR, SHAR и SIPR оно должно начать пинговаться.
Stolbov
Ещё одно дополнение.
Чип работает, отвечает на пинг. Нужно было соблюсти несколько условий:
1) Чип и ПК соединяются через кросс-кабель.
2) Чип и ПК должны находится в одной подсети.
3) Обязательно нужно открыть порт.

Всем спасибо за участие! yeah.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.