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

 
 
 
Reply to this topicStart new topic
> AVR и W5500, Простой Web-сервер на микроконтроллере
Stolbov
сообщение May 14 2018, 13:13
Сообщение #1





Группа: Участник
Сообщений: 13
Регистрация: 5-08-17
Из: Санкт-Петербург
Пользователь №: 98 653



Всем добрый день!

Я продолжаю изучать программирование микроконтроллеров, и в качестве следующей цели выбрал организацию простого 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, а потом "отпускание".

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

Заранее спасибо.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 14 2018, 15:35
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



opcode должен быть первым в последовательности, затем адрес , потом данные.
Go to the top of the page
 
+Quote Post
Stolbov
сообщение May 14 2018, 18:22
Сообщение #3





Группа: Участник
Сообщений: 13
Регистрация: 5-08-17
Из: Санкт-Петербург
Пользователь №: 98 653



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


Большое спасибо за ответ! Завтра я обязательно попробую так сделать. Скажите, пожалуйста, а откуда у Вас такая информация?
Просто в даташите SPI Frame начинается с адреса, и я руководствовался именно этой схемой.
Go to the top of the page
 
+Quote Post
aiwa
сообщение May 15 2018, 00:14
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Stolbov @ May 14 2018, 21:22) *
Скажите, пожалуйста, а откуда у Вас такая информация?

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



Go to the top of the page
 
+Quote Post
Stolbov
сообщение May 18 2018, 09:09
Сообщение #5





Группа: Участник
Сообщений: 13
Регистрация: 5-08-17
Из: Санкт-Петербург
Пользователь №: 98 653



Если кому-нибудь интересно: все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться, и выдаёт свои стандартные настройки. Буду разбираться дальше.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 18 2018, 09:28
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 313
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Stolbov
сообщение May 18 2018, 09:49
Сообщение #7





Группа: Участник
Сообщений: 13
Регистрация: 5-08-17
Из: Санкт-Петербург
Пользователь №: 98 653



Вот так выглядит "кадр" передачи данных 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)));
}


Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные. В чём может быть причина неудачи, я не знаю. Само собой, перед записью данных я делаю два сброса, как это сказано в даташите: хард и софт.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 18 2018, 10:19
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 313
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Stolbov @ May 18 2018, 12:49) *
Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные.
Так вот в этих "самих данных" не может быть попутаны байты? Вы уверены, что в регистры попадает "192.168.0.1", а не "1.0.168.192"? У W5100 и предыдущих данные хранились в виде больших индейцев (big endian), все известные мне компиляторы для AVR используют маленьких индейцев.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Stolbov
сообщение May 18 2018, 11:08
Сообщение #9





Группа: Участник
Сообщений: 13
Регистрация: 5-08-17
Из: Санкт-Петербург
Пользователь №: 98 653



Думаю, что всё записывается правильно. Каждый байт записывается по своему собственному адресу.
192 пишется в 0x0001, 168 в 0x0002 и т.д. Я попробовал прочитать все адреса и получил правильный порядок байтов.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 18 2018, 11:55
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 313
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Stolbov @ May 18 2018, 14:08) *
192 пишется в 0x0001, 168 в 0x0002 и т.д.
Да, я именно это и имел ввиду. Раз здесь все правильно - остается только схема. Потому что если у вас в MR биты RST и PB сброшены, то после записи GAR, SUBR, SHAR и SIPR оно должно начать пинговаться.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Stolbov
сообщение May 21 2018, 12:15
Сообщение #11





Группа: Участник
Сообщений: 13
Регистрация: 5-08-17
Из: Санкт-Петербург
Пользователь №: 98 653



Ещё одно дополнение.
Чип работает, отвечает на пинг. Нужно было соблюсти несколько условий:
1) Чип и ПК соединяются через кросс-кабель.
2) Чип и ПК должны находится в одной подсети.
3) Обязательно нужно открыть порт.

Всем спасибо за участие! yeah.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th June 2018 - 15:14
Рейтинг@Mail.ru


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