Stm32f407 подключение lan w5100

Обновлено: 06.07.2024



WIZ812MJ — это ethernet-шилд для подключения к Arduino или STM32.

Встречаются различные версии — wiz810mj, wiz811mj, наверняка есть ещё какие-то, у меня wiz812mj. Чем они отличаются я не интересовался.


Плата построена на базе микроконтроллера W5100.


• Питание — 3.3 вольта.

• Интерфейс — SPI (пины толерантны к пяти вольтам).


Примеры подключения и кода приведены для плат Arduino и BluePill (stm32).



Arduino

Схема для Arduino Nano, Uno:




Схема для Arduino Mega:



Питание лучше брать от стороннего источника.


Код для Arduino



Перед прошивкой нужно указать свободный IPAddress ip(192, 168, 1, 170); своей домашней сети, а потом ввести его в браузере 192.168.1.170


В будет выводиться отладочная информация. В частности при старте выводится ip-адрес присвоенный устройству (тот что в скетче указан), а после печатаются ответы (заголовки) браузера…


server address должен вернуть адрес, который вы указывали. Если не вернул, значит что-то не так.

На страничке в браузере будут две ссылки для вкл/откл D13 и счётчик обновлений. Страничка будет перезагружаться каждые 5 сек. Чтоб отключить постоянную перезагрузку, нужно закомментировать строку client.println(«Refresh: 5»); , а после того как убедитесь, что всё работает, можно закомментировать строки Serial.write( с); и Serial.println(«client disconnected»);

STM32



Код для stm32

Код такой же как и для Ардуино, только взят из примеров для stm32 (Примеры ⇨ Ethernet_STM ⇨ Web Server) и тоже немного изменён. Прежде чем его зашивать, надо подкорректировать файл ./arduino-1.8.5/hardware/ArduinoSTM32/STM32F1/libraries/Ethernet_STM/src/utility/w5100.h …



Теперь можно прошивать плату…

Собственно и всё, не забудьте указать правильный ip-адрес.

В статье не ставилась задача описания различных вариантов использования, я хотел лишь показать схему подключения и скетч «чтоб заработало». В примерах IDE есть всё необходимое…


… настройка DNS, шлюза, подсети и т.д.

В довершение могу сказать, что если подключить всё не «на соплях» и дать качественное питание (не от ардуины), то девайс работает вполне стабильно.

В процессе ковыряния столкнулся с тем, что в «Монитор порта» возвращался какой-то нелепый ip-адрес, проблема была в плохой «земле» между устройствами.



Всем спасибо


В этой, первой, статье рассмотрим физическое подключение, инициализацию интерфейсов, настройку ENC28J60 и, пожалуй, напишем сразу драйвер для работы с вышеупомянутым контроллером. Все буду описывать по возможности подробнее, но если вдруг возникнут вопросы, добро пожаловать в комментарии, а еще лучше к нам на форум )

Подключение ENC28J60.

Отладочная плата Blue Pill.

Для ENC28J60 у меня среди прочих есть такой модуль, пусть будет он:

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

Вспоминаем сетевую модель OSI (здесь в ближайшее время я помещу ссылку на статью об OSI):

Сетевая модель OSI.

Подключение ENC28J60 к STM32.

Настройка периферии в STM32CubeMx.

У меня внешний кварцевый резонатор на 8 МГц, поэтому в окне тактирования:

Тактирование в STM32CubeMx.

Настройка SPI.

После этого можно переходить к генерации проекта, больше в CubeMx ничего менять не будем.

Сразу же зададим адекватную структуризацию в проекте, которой и будем придерживаться по мере его, проекта, развития. Создадим папку Modules, в которую будем помещать наши файлы для работы с тем или иным протоколом или устройством. И сразу добавляем подпапку, а также заголовочный и файл с исходным кодом для драйвера ENC28J60, который и будем реализовывать:

Структура проекта.

Инициализация и работа с ENC28J60.

Начнем с базовых функций для отправки и приема данных по SPI, которые сопровождаются установкой и сбросом сигнала Chip Select:

Далее последовательно функции для записи/отправки байта, записи нескольких байт, чтения байта:

  • управляющие регистры
  • регистры для работы с буфером Ethernet
  • и регистры PHY

Сегодня наш акцент будет смещен на работу с первой из этих групп. Управляющие регистры распределены по 4-м банкам:


Первые буквы регистров указывают на принадлежность регистров:

Это может показаться очень запутанным, непрозрачным и непонятным, но все встанет на свои места по мере того, как мы будем решать практические задачи. Так что не стоит на этом сильно зацикливаться.

Описание всех регистров и их битов я приводить не буду, поскольку это будет банальным переводом даташита, в этом толку, кроме увеличения объема статьи, никакого нет.


Соответственно, как тут указано, байт команды состоит из кода OpCode (3 бита) и 5 битов, которые либо отвечают за адрес регистра из таблицы выше, либо имеют фиксированное значение для некоторых команд. Разберем, к примеру, команду чтения управляющего регистра (Read Control Register):



В общем, несложная модель, реализуем практически. Для начала определим все существующие регистры. Нюанс тут заключается в том, что помимо адреса каждый регистр имеет еще и свой собственный тип (Ethernet, MAC, MII), а также относится к какому-либо банку. Поэтому для описания каждого из регистров будем использовать 8 битов таким вот образом:


Итак, в заголовочном файле определены enum для банков и типов регистров:

И набор дефайнов:

Все эти определения подчиняются схеме описания регистров, которую мы разобрали. Для номера банка у нас 5-ый и 6-ой из 8 битов, соответственно, ENC28J60_REG_BANK_OFFSET = 5 и ENC28J60_REG_BANK_MASK = 0x60 (0b01100000). Аналогично для бита, который отвечает за тип регистра (он у нас 7-ой).

Также для тех 5-ти регистров, которые не относятся к конкретному банку мы будем использовать такое же значение битов, как для нулевого банка (ENC28J60_BANK_COMMON_BITS). Но для их идентификации будем использовать не значения битов, как для других регистров, а непосредственно значение адреса. Поскольку мы знаем, что эти уникальные регистры расположены по адресам старше, чем ENC28J60_COMMON_REGS_ADDR (0x1B).

В итоге имеем изящную систему определения регистров: Register = Address | Type | Bank, где:

Для работы с определенными битами регистров определяем их позиции. Возьмем, к примеру, регистр ECON1:

Перед любыми операциями с регистрами нам нужно будет проверять текущий активный банк в ENC28J60, номер которого хранится в двух младших битах регистра ECON1:

И если нам нужен регистр из другого банка, то банк следует переключить. И чтобы не вычитывать это значение из регистра каждый раз, будем хранить номер текущего банка в переменной:

Функция проверки банка:

Вспоминаем о тех 7-ми командах, которые предоставляет нам ENC28J60, и определяем их:

Опкоды команд, в свою очередь, в массиве:

Функция отправки байта команды:

И на базе этой функции мы создадим все команды. Рассмотрим пару из них, чтение регистра:

Вот итоговый список тех 7-ми функций-команд для взаимодействия с ENC28J60:

И, во-вторых, есть отдельная группа PHY регистров, не относящихся к банкам, которые мы обсудили, имеющих свое собственное адресное пространство.

Их мы просто определяем адресами:

Особенность этих регистров в том, что с ними нельзя работать напрямую, а только через MIREGADR и MIRDL/MIRDH:

База для работы с ENC28J60 полностью готова, так что стартовую статью цикла мы сейчас завершим инициализацией модуля, которую будем использовать и в последующих проектах:

И снова я не буду расписывать биты, копируя эту информацию из даташита, если потребуется, задавайте вопросы в комментариях, буду рад помочь! В следующей статье разберемся с приемным и передающим буферами, которые будут использоваться для приема и отправки Ethernet-фреймов.

Поскольку в этом эксперименте я использовал макетную плату без пайки, все стало выглядеть очень симпатично (по сравнению с предыдущими экспериментами). Поэтому не стыдно выложить фото этой сборки:

stm32, stm32f103, Ethernet, W5500

Микроконтроллер STM32F103 и модуль Ethernet W5500 в сборе

Как работать с библиотекой я расскажу дальше, а пока поработаем с нашим фото.

Пройдемся по макетке слева направо и посмотрим, что я там разместил.

Макетная сборка

От МК этой плате требуется только одна линия: Tx (отдаем строчки), которая на адаптере будет обозначаться уже как Rx (принимаем строчки). Ну и само собой кабель, который вы видите на торце платы, подключен к USB разъему PC.

Переключатель на плате устанавливаем в положение 3.3В: это будут уровни линий передачи данных, с которыми работает адаптер.

МК STM32F103 Blue Pill

Модуль питания сконфигурирован джамперами на выходное напряжение 3.3В, отбор питания идет по внешним линиям модулями W5500 и МК STM32, которым требуется 3.3В. На фото видны эти желтые и коричневые короткие перемычки, которые идут рядом.

Нюанс: вы пожете подключить к МК вместо 3.3В 5В к соответствующему (другому естественно!) контакту. Эти 5В будут преобразованы в 3.3В.

Внимание! Не подключайте к плате внешнее питание 3.3В и 5В от USB одновременно. Можете потерять МК ) Также по этой причине провод +5В для JTAG от USB PC болтается в воздухе, как может заметить внимательный читатель )

Модуль UART требует электропитание 5В, которое мы обеспечиваем внешним проводком который подключается к пину +5В модуля питания. Есть подозрение, что он прекрасно будет работать и без этого проводка от USB, когда тот подключен (и работает на самом деле).

Конфигурация

Как и раньше, для создания проекта воспользуемся услугами STM32CubeMX. По традиции создаем проект на основе Makefile, чтобы не городить огород с визуальными системами разработки (помните наш проект hardcore? Только Makefile и vim!). Как обычно, включаем пункт Debug:Serial Wire в меню SYS, чтобы иметь возможность прошивки и отладки. Сразу включатся пины PA13, PA14: через них STLINK будет общаться с МК.

Создаем проект и переходим к следующему шагу.

Соединения

Поскольку распиновка модулей W5500 и UART-USB и так известна, а распиновку Blue Pill мы уже получили с помощью Куба, займемся соединениями. Работа приятная, медитативная, навевает мысли о тщете всего сущего, хорошо заниматься этим перед сном, глубокое погружение гарантировано 🙂

Похоже, что Etherent и TCP/IP — все ещё самый распространенных способ связи самых разных устройств. Хотя WiFi в последнее время потихоньку вытесняет проводной «медный» Etherent, тем не менее, найти порт и «воткнуться в локалку» — до сих пор самый простой способ подключения. Такая доступность Ethernet не обошла стороной и самые маленькие железки: контроллеры, датчики, счетчики потребления и т.д. которые нынче называются модным маркетинговым словом "Интернет вещей*" (Internet Of Things, IoT).


И тут нам могут здорово помочь корейские микросхемки от WIZnet. Компания WIZnet — это довольно активный производитель чипов класса IOcP (Internet Offload co-Processor). Что это? Говоря человеческим языком — это такой чип, который: с одной стороны имеет Etherent, внутри содержит собственный крошечный процессор для обработки TCP/IP, а с другой стороны — простой интерфейс для связи с нашей маленькой железкой.

В первой части будет небольшой теоретический обзор подключения «маленьких железок» и куча ссылок на разные чипы.

Но сразу возникает вопрос: ЗАЧЕМ вводить в систему еще один процессор, если всё можно обработать на основном? Давайте попробуем ответить.

Давайте попробуем уйти «вниз» по шкале стоимости (до единиц долларов и даже ниже) и рассмотрим различные способы включения «мелочи» в сеть.

Самый-самый простой способ «выхода в сеть» для микроконтроллеров — это разного рода преобразователи COMпорт-в-Telnet, Serial2Ethernet иногда называемые еще Реверсивный Telnet. В этом случае преобразователь «ловит» telnet сессию и «загоняет» ее в обычный COM-порт микроконтроллера. Далее оператор попадает в обычный диалог, только по сети. Ну что тут сказать? Во первых, там тоже стоит отдельный микроконтроллер и устройства получаются совсем не дешевые (Статьи про самодельный модуль и про модуль Tibbo). Для простенькой задачи «поменять/прочитать один параметр» этого может и вполне хватит. Минусов тоже много — единственная сессия, фиксированный протокол — трудно, например, прикрутить SSL если его нет, сложности конфигурирования самого преобразователя, например сменить ему IP адрес или порт и т.д.

Другой вариант — это микроконтроллеры с настоящим Etherent на борту, но они как правило, имеют только MAC уровень и требуют внешнего чипа PHY (KS8721BL, DM9161A, RTL8201). Соединение с таким чипом, MII или RMII как минимум требует внешних пинов. Для соединения PHY с LAN требуется еще впаять трансформатор или MagJack. Таким образом, по «числу компонентов» выигрыша тут не получается. Удивительно, но внешние Etherent PHY — довольно дорогие чипы, несколько долларов за корпус. Но примерно столько же стоит весь чип от WIZnet целиком, кремний-то в массовом производстве стоит копейки. Да, трансформатор для WIZnet тоже потребуется, но значительного выигрыша от встроенного MAC-контроллера по цене не получится. Второе: программная поддержка MAC/PHY довольно сложна и объёмна. Например, для STM32Fxx7 исходные коды Ethernet драйвера занимают примерно 100К текста на C. (статья про PIC-и с Ether). Кроме драйвера Etherent нужен еще сам стек TCP/IP (LwIP или uIP). Кроме размера не стоит забывать и о скорости исполнения (хотя… STM32 уже по скорости превышает первый Pentium и про ограничение производительности можно забыть).

Но если ли преимущества «полного» программного IP-стека на микроконтроллере? Конечно есть. Рассмотрим их потом, а пока продолжим.

Третий вариант — это глубоко любимый «эмбеддерщиками» чип SPI Ethernet контроллера Microchip ENC28J60 (и чуть менее известный Silabs CP2200). Обратите внимание, это именно настоящие контроллеры Ethernet, а не TCP/IP сопроцессоры. Все что умеет чип — принимать и получать Etherent фреймы. То есть, стек TCP/IP все равно придется делать самим. Да, стеков есть несколько готовых, от замечательных небольших до классических LwIP и uIP.

Но все же, такое решение скорее напрямую конкурирует со встроенным MAC контроллером, да и цена на чип — те же несколько долларов и около 5..7$ за готовый модуль (плата с чипом, трансформатором и гнездом RJ45) на ebay/aliexpress. Так что вернемся к продуктам фирмы WIZnet.

Первое устройство W3100 было выпущено довольно давно, в 2001 году. Это был полноценный TCP/IP IOcP (сопроцессор), который предлагал некий средний путь между COM-портом и MAC-контроллером, реализуя идею TCP/UDP «сокетов» внутри чипа. Физически же W3100 был не очень удобный двухчиповый набор MAС/PHY и настоящая популярность в среде «ардуинщиков» (AVR) и «пиководов» пришла к устройству W5100. Достаточно сказать, что «официальный» Arduino Ethernet Shield собран именно на W5100.

С тех пор прошло немало времени и стали заметны недостатки W5100: чип довольно сильно греется, скорость сети всего 10Mbit/s, чип имеет несколько (документированных в Errata) глюков, корпус довольно большой из за наличия параллельной шины, несколько нетривиальная реализация SPI. Неудивительно, что вскоре WIZnet представила следующую модель: W5200. Этот чип научился работать на 100Mbit, засыпать и экономить электричество, лишился параллельного подключения, в нем остался чисто SPI, что резко уменьшило число ног. (Для поддержки параллельной шины у него есть «братик» W5300).

Внедрение и освоение W5200 пошло на ура! и продолжается до сих пор, выпускаются модули (начиная от «родного» WizNET WIZ820io) и кончая различными ардуиновскими шилдами, желающие могут легко их найти. Например, чуть менее «официальный» Ethernet Shield V2.0 из проекта Seeeduino или Ethernet Shield for Arduino от Dfrobot. А тут большой список других модулей (список реально большой, мотаем вниз).

И вот наконец, в октябре 2013 WIZnet анонсировала новый W5500 о котором собственно и планировалось рассказать в этой статье (извините за такое затянувшееся предисловие). Чип получил чуть более удобный
для ЛУТ-самодельщиков корпус 48LQFN, быстрый «пакетный» SPI и Cortex M0 внутри, что позволило уменьшить техпроцесс и потребляемую мощность. В целом же чип выглядит как «W5200 на стероидах». Сравнение W5200 и W5500.

Следом WizNET выпустила модуль WIZ550io (там же есть и схема), а чтобы не остаться в стороне от «ардуиномании» вскоре сама же WIZnet выпустила еще и Arduino Shield (это просто пассивный переходник с Arduino на WIZ550io).

Но давайте не будем рассматривать Arduino, это сделают и без нас (например прямо тут, на Хабре: Ethernet термометр на основе Arduino и т.д.) а попробуем прикрутить W5500 к какому-нибудь популярному микроконтроллеру, например к тому же STM32. Даже сама компания WizNET в курсе этого замечательного семейства и выпускала модуль W5200E01-M3 на предыдущем W5200 ( STM32F103C8 и FT232RQ для USB2Serial). Вскоре вышел и модуль на STM32 + W5500: WIZ550web.

Кстати, в марте 2014 на Circuitcellar был объявлен конкурс Connect The Magic (до августа 2014) на разработку с использованием W5500, а WIZnet скинула цены на чипы и модули (купить). В конкурсе можно было выиграть до 15.000$. Подробности на сайте, там же есть отличная статья.

Во второй части (если я её допишу. ) мы попробуем прикрутить W5500 (а точнее WIZ550io) к маленькой отладочной плате от компании Shenzhen LC Technology Co.,Ltd. и выиграть 15.000$. Платки продаются на Aliexpress по 7.99$ и даже упоминались несколько раз на Хабре.

Читайте также: