Четверг, 27 октября 2011 04:44

Подключение ENC28J60 + PIC к локальной сети . Featured

Written by
Rate this item
(0 votes)

1 часть.

 

Эта статья будет интересна в первую очередь тем, кто пишет программы  для микроконтроллеров на ассемблере и есть желание  собрать устройство , работающие в локальной сети или сети ethernet. Здесь будет применена связка  ethernet контроллер  enc28j60 и PIC18F46K20. Но можно применить и любой другой микроконтроллер , мне было просто удобно использовать именно этот , т.к. был  под рукой  и питание у обоих  3.3 вольта . 

 

 

 

При использовании микроконтроллера с 5 вольтовым питанием  необходимо согласовать  уровни ,  на пример как показано в даташите.

 

 

 

 

 

 

 

 

 

 

 

 

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

Сразу хочу определиться. Я не «крутой спец» в данной теме и практически сам постепенно разбираюсь в деталях , хотя и собирал различные конструкции (на СИ) в основном из  доработанных примеров. Так что прошу сильно не ругать. Но в любом случае все , что здесь будет написано (программа ) в начале проверяется  в «железе». Если будут замечания , или предложения , то пожалуйста на форум…

В этой части статьи мы дойдем  до приема пакетов, что уже позволит тем , кто более менее  разбирается в протоколах TCP/IP написать  ПП  для своей задачи.

Ну что ж начнем :

И начнем  с отладочной платы  , которую я использую для тестирования . Хотя это могут быть и другие платы или готовые модули на базе Ethernet контроллера NC28J60 (MM-ENC28J60 на пример ) или собственные , главное что бы они соответствовали рекомендаций производителя . Но лучше конечно собрать такую же плату, тем более что она не столько отладочная , сколько в конечном итоге должна стать законченным устройством.

 

 

 

 

 

Как видно из фотографий плата собрана из одностороннего текстолита и имеет минимальное количество деталей . Все свободные "пины" портов выведены на разъемы , к которым в последствии мы будем подключать различные датчики и управления нагрузками. Разъем RG-45 с интегрированными трансформаторами , полностью совместимый с контроллером enc28j60 . На плате установлен стабилизатор на 3.3 вольта , для питания как самого адаптера enc28j60 ,так и микроконтроллера PIC18F46K20 .Ток потребления enc28j60 приличный  - 250 мА . В начале я подумал , что мне попалась бракованная партия т.к.  сильно греются (температуру не измерял , думаю градусов 40 есть ) . Потом  выяснилось что это нормальное состояние для этой микросхемы .

Ну и теперь  что нам необходимо знать о enc28j60 , что бы понять как все это работает.

Микросхемы enc28j60 выпускаются в разных корпусах  (DIP, SOIC и QFN) и назначение выводов могут отличаться. Я использовал в SOIC-28 , правда они чуть дороже чем DIP . Схему подключения , печатную плату можно будет скачать в конце статьи по ссылке ,  рассматривать технические характеристики будем частично , т.е. только то , что непосредственно нам необходимо . Ниже , на рисунке показана упрощенная архитектура ethernet-контроллера  и связь с PICом ,обмен данными   производится   по протоколу  SPI , прерывания не задействованы и соответственно в схеме не указаны .

 

 

 

  1. TX/RX Bufer -буфер , размером 8КБ , большая часть используется для приема пакетов ,другая  для передачи.
  2. MAC -  MAC (Medium Access Controller) модуль, который реализует IEEE 802.3 MAC-логики.
  3. PHY - (Physical Layer) модуль, для работы с витой парой (интерфейс , физический уровень) .

 

Организация памяти:

Вся память в ENC28J60 реализован в виде статической оперативной памяти. Есть три типа памяти в ENC28J60:

  • регистры управления
  • буфер Ethernet памяти
  • PHY регистры

 

 

 

Управляющие регистры - находятся в  4 банках , в каждом по 32 регистра (0х00-0x1F) ,  последние 5 регистров  в каждом банке одни и те же , т.е. при обращении к этим регистрам не нужно переключать банки.

Ethernet буфер (0х00-0FFF) - (8KB) буфер.

PHY регистры - регистры состояния, управления и конфигурирования модуля PHY . Прямого доступа к этим регистрам нет, к ним можно обращаться только через регистры Media Independent Interface (MII), реализованных в MAC.

 

Регистры управления.

На стадии "изготовления " программы нам необходимо постоянно "подглядывать"  где какой регистр расположен и за что отвечает, для удобства подкрасим регистры  и выделим по группам . Регистры прерывания и DMA использовать не будем , как и встроенный тест. По большей части к регистрам будем обращаемся только в процессе инициализации , когда настраиваем ENC28J60.

 

 

 

 

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

Банк0. 2 байта L и H (младший и старший).

  • ERDPT    (L/H) - указатель чтения буфера .      
  • EWRPT   (L/H) - указатель записи буфера.
  • ETXST (L/H) - начало  отправляемого пакета.
  • ETXND (L/H) - конец отправляемого пакета.
  • ERXST (L/H) - начало кольцевого буфера
  • ERXND (L/H) - конец кольцевого буфера.
  • ERXRDPT(L/H) - указатель кольцевого буфера .
  • ERXWRPT(L/H) - указатель кольцевого буфера .
  • ESTAT  - основной регистр (флаги)
  • ECON2 - основной регистр (авто инкрементирование указателей чтения и записи,уменьшение счётчика пакетов....)
  • ECON1 - основной регистр (выбор банка,разрешение прием данных ,разрешение отправка пакетов....)

Банк1

  • EPKTCNT - основной регистр (указатель (счетчик)принятых пакетов).

Банк2

  • MACON1- регистр MAC (управление потоком ,разрешение приема пакетов...)
  • MACON2- регистр MAC
  • MACON3- регистр MAC (режим работы,контрольная сумма,проверка длины фреймов...)
  • MACON4- регистр MAC
  • MABBIPG- регистр MAC (задержка между отправляемыми пакетами - 0x15 в полнодуплексном режиме)
  • MAIPGL - регистр MAC   (задержка между отправляемыми пакетами-0х12 рекомендация )
  • MAIPGH - регистр MAC  (задержка между отправляемыми пакетами-0х0C рекомендация )
  • MACLCON1 -регистр MAC (задержка  при возникновении коллизии= по умолчанию.)
  • MACLCON2 -регистр MAC (задержка  при возникновении коллизии= по умолчанию.)
  • MAMXF(L/H)-максимальная длина пакетов (прием , передача)
  • MICON  - регистр MII  (rezet MII)
  • MICMD - регистр MII (управление , операции с PHY) .
  • MIREGADR-регистр MII(указатель регистра PHY с которым будем работать)
  • MIWR (L/H) - регистр MII (данные для записи  в  регистр PHY)
  • MIRD(L/H) - регистр MII ( чтение данных из регистра PHY)

Банк3

  • MAADR1 - MAC адрес , байт № 5 .
  • MAADR0 - MAC адрес , байт № 6
  • MAADR3 - MAC адрес , байт № 3
  • MAADR2 - MAC адрес , байт № 4
  • MAADR5 - MAC адрес , байт № 1
  • MAADR4 - MAC адрес , байт № 2
  • MISTAT  - регистр MII (проверка занятости PHY регистра....)
  • EREVID - номер ревизии enc28J60
  • ECOCON - управление CLKOUT
      Регистры PHY:

Как отмечалось ранее , прямого доступа к этим регистрам нет. Для того что бы сделать с ними какие либо действия необходимо обратиться к регистрам MII, которые и созданы как раз для этих целей .Процедура обращения к регистрам следующая:
Чтение:

  • Указываем адрес регистра к которому мы обращаемся в MIREGADR.
  • Устанавливаем бит MIIRD в регистре MICMD.
  • Ждем сброса бита BUSY в регистре MISTAT.
  • Сбрасываем бит MIIRD в регистре MICMD.
  • Читаем данные из регистров MIRDL и MIRDH

 

Запись:

  • Указываем адрес регистра к которому мы обращаемся в MIREGADR.
  • Записываем данные в регистры MIWRL (младший байт) и после младшего MIWRH (старший байт).
  • Ждем сброса бита BUSY в регистре MISTAT.

 

Регистры PHY:

  • 0х00  PHCON1 (управление режимом работы  PHY)
  • 0х01  PHSTAT  (статус PHY)
  • 0х02  PHID1    (идентификатор PHY)
  • 0х02  PHID2 (идентификатор PHY (остаток))
  • 0х10  PHCON2 (управление режимом  работы  PHY)
  • 0х11  PHSTAT2 (статус PHY)
  • 0х12  PHIE      (управления прерываниями PHY)
  • 0х12  PHIR      (флаги прерывания PHY)
  • 0x14  PHLCON (управление светодиодами)

С регистрами более менее понятно  , а что дальше ? Как с ними работать?

 


 

Реализация работы с регистрами на ассемблере.

 

Для этого предусмотрено семь инструкций  состоящей из 3-битового opcode и  5-битового аргумента (1 байт),opcod - команда , аргумент - при работе с регистрами содержит адрес регистра.

 

 

 

Рассмотрим все инструкции  и реализуем в ПП на асемблере:

Для того что бы прочитать регистр управления ,к примеру ERDPTL(0Х00),нужно передать по SPI команду "000000000", для прочтения ECON1 (0X1F) передать "00011111" и получить значение данного регистра , за исключением регистров MAC и  MII , для получения правильных  значений нужно считывать второй байт .Не забывая конечно в каком банке находится необходимый нам регистр, кроме последних 5 регистров в каждом банке  , которые присутствуют во всех банках и переключать банки соответственно нет необходимости. Ну и конечно регистры PHY , к которым прямого доступа нет и для работы с ними нужно обращаться к "посреднику" регистрам управления MII .Как это делать было рассмотрено выше.  Для индификации  регистров MAC и  MII  добавим в ПП флаг. Хотя по большому счету они нам нужны только при начальной  конфигурации enc28J60.

В микроконтроллере PIC18F46k20 есть модуль SPI , который мы и задействуем. Настроим его для правильной работа   с enc28j60 (CPOL=0, CPHA=0) . Модуль находится в PortC  ,  задействуем для сигнала CS  и REZET свободные ножки  0,1.

 

 

 

Если будут задействованы другие "ножки" , то соответственно нужно внести изменения  в ПП.Для микроконтроллера не имеющего данного модуля можно реализовать его программно.

Для чтения и записи байта данных по SPI напишем следующую ПП:

 

 

 

Как видите она проста , в регистр TXdata должен быть предварительно записан байт для передачи (при передачи).Прочитать полученное значение нужно из регистра RXdata.

С SPI все, перейдем к чтению регистра управления:

 

 

 

Первоначально мы проверяем банк в каком находится данный регистр , это нужно для того что бы не переключать каждый раз банк , а для начало проверить , может он уже в этом банке . Хотя можно и отказаться от этой ПП и устанавливать каждый раз банк , когда нужно обратиться к регистру . Подпрограмма проверки банку будет ниже . Затем мы выбираем  МК сбросом ножки CS . Записываем адрес регистра (ADRreg) в регистр TXdata для передачи . Сама команда чтения регистра имеет значение 000ХХХХХ , по этому в ПП команда не указывается , а учитывается в адресе регистра 000 и адрес регистра . Далее передаем  значение в enc28J60 и при следующей передаче получаем значение данного регистра управления.  Если это регистр MAC или MII то при проверке флага в регистре ( Flag,0) мы прочитаем еще раз исключив тем самым не правильное значение . Устанавливаем ножку CS. Результат получим в регистре RXdata.

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

Запись регистра управления:

 

 

 

В этой  ПП практически так же , как и  при чтении , только к адресу регистра добавляется команда записи регистра 010ХХХХХ , вторым байтом передается байт данных , заранее записанного в регистр "TXper".

Чтение буфера:

Отдельной ПП чтения буфера (как и записи ) нет .Чтение буфера реализована в -ПП  "RW_PAKET" . Для чтения буфера необходимо сбросить CS , передать команду чтения буфера 0Х3А ,прочитать необходимое количество байт и поднять CS.

Запись буфера:

Для записи в  буфер необходимо сбросить CS , передать команду записи в  буфер 0Х7А  , передать  необходимое количество байт и поднять CS.

Установка бита по маске:

 

 

 

Предварительно необходимо указать адрес регистра (ADRreg),банк (Prov_banka) и байт данных (SetBitReg).

Сброс бита по маске:

 

 

 

Предварительно необходимо указать адрес регистра (ADRreg),банк (Prov_banka) и байт данных (ClearBitReg).

Мягкий сброс enc28j60:

 

 

 

Процедура сброса софта заключается подачей команды 0хFF и паузой в 1 мс.

Инструкции разобрали. Для удобства проверки выбранного банка применим эту ПП.

 

 

 

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

На этом вроде как и закончили с ПП и переходим к формированию нашей программы . Начнем с инициализации enc28j60 :


 

Инициализация enc28j60.

  1. Настраиваем модуль SPI в микроконтроллере .
  2. Настраиваем размер FIFO для приема данных.Регистры ERXST, ERXND
  3. Устанавливаем указатель FIFO , регистр ERXRDPT
  4. Фильтрацию пакетов оставляем по умалчиванию
  5. Очищаем регистр MACON2 .
  6. Устанавливаем MACON1.MARXEN   (разрешить прием данных MAC)
  7. Устанавливаем MACON1.RXPAUS и MACON1.TXPAUS  (аппаратное управление потоком)
  8. Настраиваем биты PADCFG, TXCRCEN в MACON3. (выравниваем пакеты 60 байт, добавляем контрольную сумму).
  9. Настраиваем максимальный  размер фрейма (кадра). Регистр MAMXF
  10. Настраиваем интервал между фреймами .Регистры MABBIPG, MAIPG
  11. Устанавливаем MAC-адрес.Регистры MAADR 0-5.
  12. Включаем бит PHCON2.HDLDIS.
  13. Настраиваем индикацию светодиодов . Регистры PHLCON.
  14. Устанавливаем биты PHCON1.PDPXMD и MACON3.FULDPX (полнодуплексный режим).
  15. Разрешаем прием пакетов.Регистр ECON1_RXEN.

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

Попробуем принять пакет.

В первую очередь после инициализации ENC28J60 мы должны проверить есть ли вообще принятый пакет,если он есть считываем его и обрабатываем . Для этих целей служит регистр EPKTCNT , в нем хранится значение  принятых  пакетов.После прочтения  необходимо уменьшить значение принятых пакетов установкой бита PKTDEC в регистре ECON2 , тем самым освобождая это место для новых пакетов.Все пакеты располагаются в отведенной нами зоне кольцевого буфера.Естественно мы должны знать а по какому адресу в буфера находится необходимый нам пакет.Первоначально мы считываем адрес пакета из регистра ERXRDPT , а после прочтения пакета ,  записываем в него новое значение (адрес следующего пакета ).

Рассмотрим ПП принятия пакета .

В начале проверяем в регистре ERKTCNT наличие пакетов.Регистр находится в первом банке , выбираем первый банк , указываем его адрес (0Х19) , читаем и проверяем наличие принятых пакетов.В случае отсутствия таковых возвращаемся.Если это первый пакет то считываем адрес пакета из регистра ERXRDPT.

 

 

 

Здесь читаем регистр ERXRDPT старший и младший байты , потом записываем эти значения в указатель адреса пакета ERDPT (адрес от куда мы будем забирать пакет).

 

 

 

Принимаем заголовок пакета 8 байт в ОЗУ с адреса 0100H.

 

 

 

Пропускаем первый байт и считываем  из ОЗУ микроконтроллера   адрес следующего пакета  (2,3 байты) и длину принятого пакета 3,4 байты (иначе откуда мы узнаем сколько нужно прочитать байт ?).Флаги (5,6 байты) пока не рассматриваем .Далее принимаем сам пакет и записываем его в ОЗУ микроконтроллера начиная с адреса 0200H.

Записываем адрес следующего пакета.

 

 

 

Результат:

Мы отправили пакет "ping" (обведено красным цветом).

 

 

И получили его в памяти ПИКа (с адреса 0200H).

По адресу 1001h,1002h адрес следующего пакета,1003h,1004h длина текущего пакета,и два байта флаги.

 

 

 

Последние четыре байта  это контрольная сумма .

На этом первая часть статьи закончена.  Отправка пакетов и реализация протоколов будет в следующих статьях.

Ссылки:

Вопросы можно задать на форуме.

Данный проект для pic18f46k20 можно скачать здесь 

Ссылка для скачивания доступна только авторизованным пользователям сайта !
.

Read 6823 times

Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

ChipMk.ru Яндекс.Метрика
PRCY.ru