Урок 40
Часть 1
LAN. ENC28J60
Сегодня мы попробуем подключить наш контроллер к локальной сети с помощью модуля на микросхеме ENC28J60.
Так как мы интерфейсом LAN ещё ни разу не пользовались, программируя микроконтроллеры AVR, я решил всё-таки данный пробел восполнить. Ещё меня на это побудило то, что довольно-таки немного уроков по LAN с использованием микроконтроллеров, а видеоуроков я и совсем не нашел, исключительно только с использованием Arduino и, как водится, готовых библиотек, которые, я считаю, не дают свободы в программировании, а когда пишешь своё, больше возможности прочувствовать тот или иной интерфейс изнутри.
Данный модуль выглядит вот так
Сердцем данного модуля является одноименная микросхема ENC28J60, которая представляет собой готовое сетевое решение, в котором присутствует и физический и канальный уровень. Обмен данными с контроллером данная микросхема осуществляет посредством шины SPI. Физический уровень у неё организован по стандарту 10BASE-T. То есть максимальная скорость передачи данных — 10 мегабит в секунду, что довольно-таки неплохо для общения контроллера AVR с компьютерами, и я думаю это будет удобнее, чем по USB, так как, находясь в сети и имея свой адрес и канальный и сетевой, контроллер может обращаться к любому компьютеру как в локальной сети, так и в глобальной, что сравнительно-таки неплохо.
Внутренняя структура микросхемы представляет собой следующий вид (нажмите на картинку для увеличения изображения)
Мы видим здесь, что у нас существуют управляющие регистры, в которые мы будем отправлять определённые команды для управления теми или иными действиями и настройками, Также мы видим буфер размером 8 килобайт для получения и отправки данных по сети.
Поставляется микросхема в различных корпусах. На нашем модуле она в корпусе, предназначенном для поверхностного монтажа.
В качестве контроллера, который мы будем подсоединять к данной микросхеме, мы возьмём МК Atmega328P, который находится на готовой отладочной плате, которую мы с вами уже используем активно последнее время.
Для подключения модуля имеется следующий разъём
Все обозначения контактов мы видим справа.
К отладочной плате мы подключим модуль следующим образом
ENC28J60 — ATMEGA328
VCC — VCC
GND — GND
CS — 10
RESET — VCC
SI — 11
SCK — 13
SO — 12
Кроме всего прочего мы к плате подключим переходник USART таким же образом как и на предыдущем занятии.
Регистры в микросхеме организованы следующим образом
Мы видим здесь, что кроме адресов регистров существуют и банки, то есть порядок адресации регистров сегментированный, а начиная с адреса 1Bh обращение к регистрам от банков не зависит, они мапятся на все банки.
Основное назначение регистров можно узнать по их начальным буквам в аббревиатуре
E — Ethernet,
MA — MAC,
MII — MI.
Конкретно с некоторыми регистрами мы будем знакомиться уже при написании исходного кода, так как его будет очень много и к тому моменту, когда нам потребуется тот или иной регистр, мы уже забудем его назначение.
Само собой, чтобы заниматься программированием передачи данных по сети, необходимы знания сетевых уровней, модели OSI и всего, что связано с сетью, так как учить данным вещам я не буду, по этим вопросам есть очень много информации, могу только если что-то посоветовать, так что обращайтесь если что в комментариях. Но некоторые сведения я, конечно, давать буду, не без этого.
Вообще сетевая модель делится на несколько уровней. Основные из них следующие:
1. Прикладной уровень
2. Уровень представления
3. Сеансовый уровень
4. Транспортный уровень
5. Сетевой уровень
6. Канальный уровень
7. Физический уровень
При передаче данных из программы в сетевой провод мы проходим путь сверху вниз по вышенаписанному списку. Сначала мы наши данные объединяем в какие-то удобные последовательности или массивы, понятные для прикладного уровня принимаемой стороны, затем мы их шифруем либо ещё как-то их преобразуем для защиты от несанкционированного использования, затем обёртываем в определённый протокол, который поможет поддержать соединение и не потерять его (сеансовый уровень), затем прицепляем ещё заголовок спереди, который обеспечит передачу определённому порту от другого определённого порта, затем ещё обёртываем в протокол, который обеспечит доставку к определённому устройству, имеющему сетевой адрес (IP), затем ещё обёртываем протокол, который несёт в себе физические адреса устройств MAC (канальный уровень), а последний уровень уже обеспечит непосредственную доставку всех этих несколько раз обёрнутых пакетов (физический уровень), к которому относятся трансформаторы, провода, концентраторы, повторители сигнала и медиаконвертеры.
Вообщем кратко как-то вот так. Поконкретней с протоколами будем знакомиться по мере их использования.
Ну давайте, чтобы от этой всей теории немного отвлечься, создадим наш проект, назовём его по имени нашей используемой микросхемы незатейливо — ENC28J60.
И проекта предыдущего занятия возьмём свою библиотеку для USART и подключим, чтобы не сочинять её заново, а также можно взять и подключить оттуда файл main.h.
Также создадим ещё четыре файла: net.c, net.h, enc28j60.c и enc28j60.h.
После всех первоначальных настроек файлов они у нас будут следующего содержания.
Файл main.c:
#include «main.h»
int main(void)
{
USART_Init(16);//Зададим скорость работы USART 115200
sei();
while (1)
{
}
}
Файл main.h
#ifndef MAIN_H_
#define MAIN_H_
#define F_CPU 16000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include «usart.h»
#include «net.h»
#include «enc28j60.h»
#endif /* MAIN_H_ */
Файлы usart.h и usart.c не трогаем вообще и они остаются в прежнем состоянии.
Файл net.h
#ifndef NET_H_
#define NET_H_
//——————————————
#include <string.h>
#include «usart.h»
#include «enc28j60.h»
//——————————————
//——————————————
#endif /* NET_H_ */
Файл net.c
#include «net.h»
//———————————————
Файл enc28j60.h
#ifndef ENC28J60_H_
#define ENC28J60_H_
//————————————————
#include «main.h»
//—————————————————
#endif /* ENC28J60_H_ */
Файл enc28j60.c
#include «enc28j60.h»
//———————————————-
Ну, и как всегда, первым делом инициализация.
Перейдём в файл enc28j60.c и создадим функцию
#include «enc28j60.h»
//—————————————-
void enc28j60_ini(void)
{
}
//—————————————-
Сделаем для неё прототип в хедер-файле, перейдём в файл net.c и напишем там также функцию инициализации, в которой вызовем вышенаписанную функцию
#include «net.h»
//———————————————————
void net_ini(void)
{
enc28j60_ini();
}
//———————————————————
Сделаем для данной функции также прототип в хедер-файле net.h и вызовем её в main()
USART_Init(16);//Зададим скорость работы USART 115200
net_ini();
sei();
В следующей части нашего занятия мы напишем ещё несколько макросов и функций для работы с микросхемой.
Предыдущий урок Программирование МК AVR Следующая часть
Техническая документация:
Документация на микросхему ENC28J60
Перечень ошибок ENC28J60 (Errata)
Приобрести плату Atmega 328p Pro Mini можно здесь.
Приобрести программатор USBASP USBISP с адаптером можно здесь USBASP USBISP 3.3 с адаптером
Ethernet LAN Сетевой Модуль можно купить здесь ENC28J60 Ethernet LAN Сетевой Модуль.
Смотреть ВИДЕОУРОК (нажмите на картинку)
Спасибо !
Вам также спасибо!
Добрый день!Очень понравилась инфа про enc. Большое спасибо.Возник вопрос по поводу функции arp_read. Там выполняется проверка op == ARP_REQUEST) && (msg->ipaddr_dst == IP_ADDR) )>. Как комп может знать IP_ADDR при первоочередном запросе arp?
Спасибо за интерес к ресурсу!
не совсем понял при чём тут комп. Мы должны знать адрес компа заранее, когда узнаём его MAC-адрес. А если не знаем, то там только перебор по сетевой маске.
Я скорее всего не правильно выразил свою мысль.С одной стороны компьютер,с другой enc. При подключении enc изначально идет запрос arp (broadcast,как я понял)от компьютера. Получая этот запрос в микроконтр. мы попадаем в функцию arp_read, где проверяем условие совпадения ip адреса(хотя мы его изначально не знаем,опять же как я понял).Или я что-то упустил?
Приветствую всех, почти уверен что не ответите (был опыт), но всё-таки спрошу: На первой же части настоящего урока получил ошибку (программирую в АС 6,2 перейти на 7,х не смог по причине старенького компа и вследсвие чего виндус 10 32 бит (предполагаю что в этом и причина)) при сборке проекта выдаёт 2 ошибки:
Error 1 multiple definition of `main' C:\ISH\AVR\STUDIO\ENC28J60\ENC28J60\Debug/.././main.c 5 1 ENC28J60
Error 2 ld returned 1 exit status collect2.exe 0 0 ENC28J60
Или что то подскажете проверить.