|
|
  |
AVR и W5500, Простой Web-сервер на микроконтроллере |
|
|
|
May 14 2018, 13:13
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 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, а потом "отпускание". Я постарался как можно короче изложить свою проблему, но, тем не менее, указав важные детали. Буду рад любой помощи или совету. Заранее спасибо.
|
|
|
|
|
May 14 2018, 18:22
|
Участник

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

|
Цитата(aiwa @ May 14 2018, 18:35)  opcode должен быть первым в последовательности, затем адрес , потом данные. Большое спасибо за ответ! Завтра я обязательно попробую так сделать. Скажите, пожалуйста, а откуда у Вас такая информация? Просто в даташите SPI Frame начинается с адреса, и я руководствовался именно этой схемой.
|
|
|
|
|
May 15 2018, 00:14
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(Stolbov @ May 14 2018, 21:22)  Скажите, пожалуйста, а откуда у Вас такая информация? Извините, похоже я ввел Вас в заблуждение. Написал по инерции для наиболее распространенного варианта.
|
|
|
|
|
May 18 2018, 09:09
|
Участник

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

|
Если кому-нибудь интересно: все данные в чип пишутся, и читаются (настройки mac, ip и прочее). Даже считал версию чипа (0x04), но он упорно не хочет пинговаться, и выдаёт свои стандартные настройки. Буду разбираться дальше.
|
|
|
|
|
May 18 2018, 09:49
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 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))); } Так как сперва надо передать старший байт адреса, я его двигаю, и потом в след за ним передаю младшую часть, потом сформированный "опкод", а затем непосредственно сами данные. В чём может быть причина неудачи, я не знаю. Само собой, перед записью данных я делаю два сброса, как это сказано в даташите: хард и софт.
|
|
|
|
|
May 18 2018, 10:19
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 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)
|
|
|
|
|
May 18 2018, 11:08
|
Участник

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

|
Думаю, что всё записывается правильно. Каждый байт записывается по своему собственному адресу. 192 пишется в 0x0001, 168 в 0x0002 и т.д. Я попробовал прочитать все адреса и получил правильный порядок байтов.
|
|
|
|
|
May 21 2018, 12:15
|
Участник

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

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