Przedstawiony poniżej projekt jest prostym serwerem WWW, który umożliwia prezentację strony internetowej. Na stronie pojawia się informacja uzyskana z peryferii mikrokontrolera, za pomocą strony istnieje także możliwość manipulowania stanem diody LED.

Przedstawiony poniżej projekt jest prostym serwerem WWW, który umożliwia prezentację strony internetowej. Na stronie pojawia się informacja uzyskana z peryferii mikrokontrolera, za pomocą strony istnieje także możliwość manipulowania stanem diody LED.

Zadanie zostało wykonane na mikrokontrolerze STM32F107VC, do obsługi warstwy fizycznej sieci ethernet zastosowano układ STE100P. Projekt jest w adaptacją aplikacji AN3102 wydaną przez ST Microelectronics.

Przygotowany przez ST przykładowy program opisany w nocie jest dedykowany dla płytki ewaluacyjnej STM3210C-EVAL, która jest wyposażona w wiele peryferii m.in. kolorowy wyświetlacz LCD, matrycę dotykową, joystick, przetwornik audio DAC oraz ethernetowy kontroler. Do przykładu dołączono dobrze udokumentowany program. Chcąc jedynie uruchomić serwer WWW możemy pominąć obsługę części elementów. Poniżej przedstawiono podstawowy układ, wystarczający do uruchomienia strony WWW na wymienionym mikrokontrolerze.

 

Rys. 1. Schemat ideowy połączeń

Rys. 1. Schemat ideowy połączeń

 

Na stronie umożliwiono odczyt wartości napięcia na potencjometrze R19 oraz zmianę stanu podłączonych dwóch diod LED. Są to podstawowe operacje wymiany informacji pomiędzy mikrokontrolerem i użytkownikiem strony, które mogą posłużyć jako podstawa dla dużo bardziej zaawansowanego systemu np. automatyki budynkowej.

Pierwszym etapem jest modyfikacja biblioteki pod zaproponowany schemat układu. W aplikacji wprowadzono następujące modyfikacje: zmiana definicji portów diod LED, zmiana elementu docelowego komunikatów z wyświetlacza LCD na interfejs szeregowy, konfiguracja interfejsu ethernetowego.

W pliku stm3210c_eval.h wprowadzono zmiany w definicjach pinów i portów, do których podłączone są diody LED. Dla LED1 zmiany są następujące:

#define LED1_GPIO_PORT GPIO
#define LED1_GPIO_CLK RCC_APB2Periph_GPIO B
#define LED1_GPIO_PIN GPIO_Pin_0

Analogicznie zmiany zostały wprowadzone dla pozostałych diod LED. W przedstawionej aplikacji diody LED są zapalane poprzez ustawienie stanu niskiego na linii, odwrotnie wobec rozwiązania na STM3210C-EVAL. Wobec tego należy wprowadzić zmiany w kodzie funkcji STM_EVAL_LEDOn oraz STM_EVAL_LEDOff w pliku stm32_eval.c. Modyfikacja jest następująca:

 

Listing 1. Funkcje sterujące stanem diod LED

 

Jak zostało wspomniane przykładowy program z aplikacji AN3102 wysyła komunikaty o stanie działania na wyświetlacz LCD. W przedstawianej aplikacji zastąpiono te działanie na wysyłanie komunikatów przez port szeregowy. Aby zapewnić taki sposób prezentacji komunikatów należy w pierwszym kroku przeprowadzić konfigurację interfejsu USART2. Zostało to zrealizowane poprzez dodanie nowej funkcji USART_Configuration(void). Kod funkcji jest następujący:

 

Listing 2. Funkcja inicjalizująca interfejs USART2

 

W tym samym pliku w funkcji System_Setup wprowadzono zmiany, których celem jest włączenie zegar interfejsu USART2 oraz zadbano o wywołanie wyżej wymienionej funkcji USART_Configuration przeprowadzającej inicjalizację peryferii.

Następnym krokiem, jaki należy przeprowadzić, jest zmiana funkcji obsługi wyświetlacza LCD, aby komunikaty były wysyłane przez port szeregowy. Zmiany zaczęto od kodu, który odpowiada za inicjalizowanie wyświetlacza. Następnym elementem było wprowadzenie zmian w funkcji wyświetlającej komunikaty na wyświetlaczu LCD . W nowej wersji komunikaty te są wysyłane przez port szeregowy. Poniżej przedstawiono nowy kod funkcji , która za to odpowiada.

 

Listing 3. Funkcja wysyłająca komunikaty przez interfejs szeregowy

 

Aplikacja AN3102 jest przygotowana do pracy z kontrolerem warstwy fizycznej DP83848, natomiast wprowadzone modyfikacje zmieniają ten kontroler na układ STE100P. W takim przypadku należy zadbać o wprowadzenie pewnych modyfikacji w pliku stm32_eth.h.Wynika to z różnic w inicjalizacji obu układów. Pierwszą zmiana jest poprawienie adresu rejestru statusowego na wartość 17, pod takim adresem występuje ten rejestr w układzie STE100P. Należy także pamiętać o zmianie definicji masek bitowych.

#define PHY_SR 17/*!< Tranceiver Status Register */
#define PHY_Speed_Status ((u16)0x0200) /*!< Configured information of Speed: 100Mbps */
#define PHY_Duplex_Status ((u16)0x0100) /*!< Configured information of Duplex: Full-duplex */

Kolejną zmianą jest korekta warunku odpowiadającego za ustawienie prędkości transmisji. W DP83848 ustawiony bit PHY_Speed_Status oznacza prędkość 10 Mbps, natomiast w układzie STE100P ustawienie tego bitu powoduje wybór prędkości 100 Mbps. Poniżej zostały przedstawione zmiany dokonane w pliku stm32_eth.c w funkcji ETH_Init.

 

Listing 4. Wprowadzone zmiany w funkcji ETH_Init

 

Po tych zabiegach dotyczących warstwy fizyczna należy dokonać korekty w konfiguracji przetwornika analogowo-cyfrowego. W funkcji w pliku stm32f107.c należy zmienić kanał przetwornika ADC z 14 na 10, który został użyty w przedstawionym projekcie. Pamiętać trzeba także o zmianie definicji numer użytego pinu, do którego podłączony jest potencjometr.

 

Listing 5. Zmiany linii przetwornika ADC

 

W tym momencie biblioteka jest przygotowana do pracy w proponowanym układzie, przedstawionym na rysunku 1. Jeżeli konfiguracja przebiegła oprawnie po uruchomieniu układ będzie zabiegał o przydzielenie mu adresu IP. Aktualny status programu jest wysyłany na port szeregowy. Kiedy układ otrzyma adres IP zostanie on również przesłany na ten port. Jeśli urządzenie podłączono do sieci lokalnej jest to lokalny adres IP. Po wpisaniu w pasku adresu przeglądarki tego adresu IP można zobaczyć przykładową stronę załączoną przez ST. Strona ta zawiera trzy zakładki, pierwsza jest stroną startową, na drugiej zakładce możemy manipulować stanem diod LED w naszym układzie, a na trzeciej jest wizualizowany stan napięcia na potencjometrze.

Domyślnie urządzenie łączy się z routerem na porcie 80, czyli standardowym dla protokołu http. Zmiany portu można dokonać w pliku httpd.c w funkcji httpd_init, poprzez odnalezienie linijki tcp_bind(pcb, IP_ADDR_ANY, 80). W przypadku chęci zmiany na inni port należy zmienić wartość 80 na żądaną.

Stworzony serwer WWW jest widoczny jedynie z poziomu sieci lokalnej, aby był widoczny na zewnątrz należy w routerze przekierować ustawiony port do stworzonego serwera. Należy również dopuścić połączenia z zewnątrz na tym porcie, co jest również konfigurowane po stronie routera. Po przekierowaniu portu w routerze uzyskuje się możliwość dostępu do urządzenia z sieci Internet.

Cała ta procedura byłaby nieprzydatna, gdyby umożliwiała jedynie uruchomienie domyślnej strony z przykładu przygotowanego przez STMicroelectronics. Kolejnym krokiem jest przedstawienie w jaki sposób zaprogramować własną stronę w pamięci mikrokontrolera.

Łatwym sposobem dodania własnej strony jest jej dopisanie do istniejącej już struktury zawartej w przykładzie. Jej elementy są zawarte w pliku fsdata.c. Struktura ta zawiera pliki tworzące stronę internetową np. pliki html lub obrazy. Każdy jej element zawiera wskaźnik do następnego pliku, własną nazwę, tablicę znaków reprezentującą zawarte w nim dane oraz rozmiar tej tablicy.

Do pliku fsdata.c dodano tablicę z zawartością nowej strony.

 

Listing 6. Kod HTML przygotowanej. Nowej strony WWW

char moja_stronka1[] =
   “HTTP/1.0 200 OK\r\n\
   Content-type: text/html\r\n\
   \r\n\
   <html> \
   <head>\
   <meta http-equiv=\”Content-Type\” content=\”text/html; charset=ISO-8859-2\”>\
   <title>Strona testowa</title>\
   </head> \
   <body> \
   <H2><center>Przykładowa strona na STM32</center></H2>\
   <img src= \”/images/KNR1.jpg\” > \
   <form action=\”method=switch_led\”>\
   <input value=\”1\” name=\”dioda\” type=\”checkbox\”>LED1<br>\
   <br>\
   <input value=\”Send\” type=\”submit\”> </form>\
   Napięcie na potencjometrze: V\
   </body> \
   </html>”;

 

Przedstawiona strona zawiera tytuł, obraz o nazwie KNR1.jpg, formę umożliwiającą zmianę stanu diody LED oraz miejsce do wyświetlenia wyniku pomiaru z przetwornika A/C. Stronę oraz obraz należy dołączyć do istniejącej struktury, dodajemy więc w pliku fsdata.c:

static const struct fsdata_file file_moj_plik[] = {{file_STM32F107_html, “/moja_stronka.html”, moja_stronka1, sizeof(moja_stronka1)}};

Każdy obraz dodawany do pamięci mikrokontrolera trzeba zapisać w postaci oddzielnej tablicy wartości. Należy więc, wcześniej przetworzyć obraz graficzny na postać tablicy wartości szesnastkowych. Przykładową realizacją tego zadania jest wykorzystanie poniższego skryptu napisanego w Bashu.

 

Listing 7. Skrypt Bash tworzący tablicę wartości z pliku graficznego

 

Wywołanie skryptu następuje komendą: ./skrypt < KNR1.jpg > plik_wynikowy.txt. Wynik działania skryptu dodano w fsdata.h jako tablicę: static const char img_konar_jpg[] = {0xff, 0xd8 ..}.

Uzyskanie tablicy wartości szesnastkowych, która przedstawia plik można także dokonać przez użycie dowolnego edytora heksadecymalnego.

Podobnie jak w przypadku zawartości strony, utworzoną tablicę z obrazem wpisujemy także do ciągu przedstawiającego kolejne pliki w pamięci mikrokontrolera: static const struct fsdata_file file_images_konar_bmp[] = {{NULL, “/images/KNR1.jpg”, img_konar_jpg, sizeof(img_konar_jpg)}};

Przełączanie stanu diod LED zrealizowane zostało zgodnie z aplikacją, wykorzystano element języka HTML jakim jest forma.

 

Listing 8. Fragment kodu HTML przełączający stan diody LED

 

W powyższym przykładzie do formy dodano element typu checkbox w który umożliwia zmianę stanu diody LED oraz element typu submit, czyli przycisk, za pomocą którego potwierdza się wybór. Po naciśnięciu przycisku, w zależności od stanu elementu checkbox wysyłana jest komenda:

  • “GET /method=switch_led?dioda=1 …” dla zaznaczonego pola lub
  • “GET /method=switch_led …” dla odznaczonego pola.

Polecenia te są parsowane w funkcji http_recv zawartej w pliku httpd.c. Sprawdzając otrzymaną komendę można zmieniać stan diody LED w zależności od stanu elementu checkbox. Poniższy przykład, realizujący ten proces, w pierwszej kolejności porównuje otrzymany ciąg z “GET /method=switch”. W przypadku spełnienia warunku następuje porównanie drugiej części, w której zakodowany jest stan diod LED jaki należy wprowadzić.

 

Listing 9. Wprowadzenie nowego stanu diod LED

 

Następnym etapem jest wyświetlenie na stronie informacji z mikrokontrolera. Informacją tą jest wartość napięcia na potencjometrze, odczytywana z przetwornika A/C. Miejsce na jej wypisanie znajduje się w linii „Napięcie na potencjometrze: V\”.

Pierwotnie w miejscu wyniku wstawiono spacje pod które należy wpisać cyfry z odczytu napięcia. Proces podstawiania nowej wartości napięcia realizowany jest w funkcji, w której jest obsługiwane zapytanie z przeglądarki internetowej, czyli w http_recv(…). Za podstawienie odpowiedniej wartości odpowiada kod przedstawiony poniżej.

 

Listing 10. Podstawianie wartości napięcia na potencjometrze do pliku HTML

 

Wartość offset jest miejscem w tablicy, w której zapisano źródło strony, przeznaczonym do wyświetlenia wyniku. Można je odszukać eksperymentalnie. Na koniec należy dodać warunek w funkcji parsującej http_recv(…), który będzie odpowiedzialny za wyświetlanie dodanej strony.

 

Listing 11. Obsługa utworzonej strony

 

W powyższym fragmencie parser sprawdza, czy nastąpiło wywołanie typu: ADRES_IP:numer_portu/moja_stronka (np. 192.168.10.213:80/moja_stronka). W przypadku poprawności warunku wyświetlana jest stworzona strona internetowa, na niej obraz, kontrolki sterujące diodą LED, wynik pomiaru napięcia z przetwornika A/C. Strona ta została przedstawiona na rysunku 2.

 

Rys. 2. Strona internetowa WWW

Rys. 2. Strona internetowa WWW

 

Autor:
Jacek Urbanowicz