Aktualizacja: 2016-10-17

Moduł ENC28J60

Moduł ENC28J60 pozwala na połączenie mikrokontrolerów z siecią pracującą w standardzie 10/100/1000Base-T.  Moduł posiada 8-Kbyte bufor, generator CRC, automatyczny detektor kolizji (w przypadku detekcji retransmituje dane), komunikacja z mikrokontrolerem odbywa się za pośrednictwem magistrali SPI z prędkością maksymalną 20MHz.
Napięcie zasilania układu wynosi 3,3V jednak jego wejścia dopuszczają użycie 5V.

Tabela 1. Specyfikacja modułu ENC28J60

Napięcie zasilania 3,3V
Prędkość transmisji 10 Mb/s
   
   

Tabela 2. Wyprowadzenia modułu ENC28J60

Pin Nazwa Opis
1 CLKOUT Wyprowadzenie sygnału zegarowego
2 INT  Interrupt
3 WOL Wake On Lan
4 SO Dane wychodzące (SPI)
5 SI Dane wchodzące (SPI)
6 SCK Zegar (SPI)
7 CS Chip Select
8 RESET Reset układu
9 VCC 3,3v (zasilanie)
10 GND GND (zasilanie)

Układ testowy

Układ testowy został zbudowany w oparciu o mikrokotroler PIC18F2550 taktowany zewnętrznym rezonatorem kwarcowym o częstotliwości 25MHz. Do mikrokontrolera podłączono LED którego włączenie i wyłączenie realizowane jest przez generowaną przez układ stronę internetową. Dostęp do sieci realizowany jest przez moduł ENC28J60. Urządzenie jest dostępne w sieci lokalnej pod adresem http://192.168.0.6

Tabela 3. Podłączenie ENC28J60 z PIC18F2550

PIN ENC PIN PIC
4 (SO) 18 (C7)
5 (SI) 13 (C2)
6 (SCK) 17 (C6)
7 (CS) 11 (CO)
8 (RST) 12 (C1)
9 (VCC) 8 lub 19 (VDD)
10 (GND) 20 (VSS)

Program

Program dla mikrokontrolerów został napisany w CCS C. Koniecznym jest dołączenie do projektu "biblioteki" umożliwiającej obsługę protokołu TCP/IP. Została ona przeportowana do CCS C ogólnodostępnej wersji udostępnionej przez Microchip.
Głównymi elementami programu na które należy zwrócić uwagę w pliku "picweb.h" są:

 Głównymi elementami programu na które należy zwrócić uwagę w pliku "picweb.c" są:

Powyższe definicje powodują iż układ staje się prostym serwerem stron internetowych. Uruchomienie obsługi modułu ENC28J60 jak i jego wstępna konfiguracja odbywa się w funkcji main():

MACAddrInit();
IPAddrInit();  
StackInit();
delay_ms(10);
while(TRUE) {
           StackTask();
   }

Przykłady zastosowania i opisy funkcji serwera stron internetowych.

Urządzenie testowe ma na celu wyświetlenie użytkownikowi formularza w przeglądarce internetowej i umożliwienie obsługi LED. Formularz ma również informować o aktualnym stanie LED.
Uruchomienie prostego serwera stron definicją:

#define STACK_USE_HTTP  1

Dało dostęp do następujących funkcji:

Kod stron internetowych w HTML

Przewidziano dwie strony. Strona główna będzie zawierać formularz sterujący LED, strona Info będzie jedynie prostym przykładem obsługi podstron i zawierać będzie komunikat informacyjny iż stronę obsługuje mikrokontroler PIC.
Obie strony będą zawierać proste menu umożliwiające poruszanie się między nimi.

Utworzono dwie zmienne zawierające źródła stron:

//zrodlo strony index
const char  HTML_INDEX_PAGE[]="
<HTML><BODY>
<H1>PIC okH1>
<AHREF=\"/info\">infoA>
<hr/>
<FORMMETHOD=GET>
LED1:<br/>
<INPUTtype=\"radio\"name=\"led1\"value=\"1\" %1>ON<br/>   
<INPUTtype=\"radio\"name=\"led1\"value=\"0\" %0>OFF<br/>
<INPUTTYPE=\"submit\"value=\"Ustaw\">
FORM>
BODY>HTML>
";

//zrodlo strony info
const char  HTML_INFO_PAGE[]="
<HTML><BODYBGCOLOR=#FFFFFFTEXT=#000000>
<H1>INFOH1>
<AHREF=\"/\">glownaA>
<hr/>
to strona z serwera na mikrokontrolerze PIC<br/>
i ukladzie ENC28J60<br/>
BODY>HTML>
";

http_get_page

To podstawowa funkcja obsługująca serwer stron internetowych. Zależnie od zapytania - podstrony podanej w URL, wysyła do przeglądarki zawartość konkretnej zmiennej zawierającej źródło danej strony.

int32 http_get_page(char *file_str) {
   int32 file_loc=0;
   static char index[]="/";
   static char info[]="/info";

   if (stricmp(file_str,index)==0){
      file_loc=label_address(HTML_INDEX_PAGE);
   }
   else if (stricmp(file_str,info)==0){
      file_loc=label_address(HTML_INFO_PAGE);
   }
   return(file_loc);
}

W przypadku braku podstrony w URL zostanie wysłana zawartość zmiennej HTML_INDEX_PAGE, w przypadku podania w URL podstrony "info" (http://192.168.0.6/info) zostanie wysłana do przeglądarki internetowej zawartość zmiennej HTML_INFO_PAGE.

http_exec_cgi()

Strona główna (HTML_INDEX_PAGE) zawiera formularz wysyłany metodą GET.  Serwer wykrywając owo zdarzenie wywołuje funkcję http_exec_cgi()

//Obsluga GET ?led1=1
void http_exec_cgi(int32 file, char *key, char *val) {
   static char led1_key[]="led1";
   int8 v;
  //led1
   if (stricmp(key,led1_key)==0) {
      v=atoi(val);
      if (v) {
      output_high(PIN_A0);
                    LedState = 1;
       }
      else {
                     output_low(PIN_A0);
                      LedState = 0;
               }
   }
}

Metoda GET powoduje "dołączenie" do URL zmiennej (po znaku zapytania) oraz jej wartości np. http://192.168.0.6/?led1=1.
Wartość zmiennej led1 wynosząca 1 oznacza w tym przypadku podanie wysokiego stanu na PIN_A0 mikrokontrolera, czyli włączenie LED. Wartość wynosząca 0 (bądź inna niż jeden - gdyż użyto "else") spowoduje podanie stanu niskiego na PIN_A0 do którego podłączony jest LED, nastąpi jego wyłączenie.
Formularz w HTML pozwala jedynie szybko skonstruować owy adres, możliwe jest włączenie, bądź wyłączenie LED wpisując w pasek przeglądarki powyższy adres który spowoduje wykonanie funkcji po stronie serwera.

http_format_char()

Funkcja zostaje automatycznie wywołana w przypadku napotkania w źródle strony znaku "%" i nazwy zmiennej. Jeśli została ona zdefiniowana (np. %0) następuje jej podmiana w kodzie na daną wartość.
W omawianym przypadku pole typu "radio" formularza HTML:

<INPUTtype=\"radio\"name=\"led1\"value=\"1\" %1>ON<br/>   
<INPUTtype=\"radio\"name=\"led1\"value=\"0\" %0>OFF<br/>

ma zostać ustawione automatycznie w pozycji zależnej od stanu LED, który jest przechowywany w zmiennej LedState.
Zaznaczenie pola radio w HTML można dokonać poprzez dopisanie "checked". Zależnie od stanu zmiennej LedState jedna z dwóch zmiennych (%1 lub %0) otrzymuje wartość "checked" natomiast druga staje się pusta.

//zmienna przechowujaca stan LED, 0-wylaczona 1-wlaczona
char LedState=0;

// ten przyklad formatuje dwie zmienne z HTML %0 i %1 podstawiajac za nie odpowiednie wartosci
int8 http_format_char(int32 file, char id, char *str, int8 max_ret) {
   char new_str[10];
   int8 len=0;
   memcpy(str, 0, sizeof(str));
   switch(id) {
       //zmienna %0 czy wylaczona
      case '0':
         if (LedState == 0){
            sprintf(new_str,"checked");
         } else {   memset(new_str, 0, sizeof(new_str)); }
         len=strlen(new_str);
         break;
       //zmienna %1 czy wlaczona
       case '1':
         if (LedState == 1){
            sprintf(new_str,"checked");
         } else {   memset(new_str, 0, sizeof(new_str)); }
         len=strlen(new_str);
         break;
   }
   if (len) {
      if (len>max_ret) {len=max_ret;}
      memcpy(str,new_str,sizeof(new_str));
   }
   return(len);
}

Pliki

Wyślij komentarz