- Komunikacja szeregowa na STM8S103F3P6
- Szeregowe szpilki komunikacyjne w STM8S103F3P6
- Schemat obwodu komunikacji szeregowej STM8S
- Konfigurowanie STVD do komunikacji szeregowej
- Programowanie STM8S do komunikacji szeregowej
- Kontrolowanie LED z monitora szeregowego
- Głębszy wygląd biblioteki szeregowej STM8S
Programowanie nowego mikrokontrolera często zajmuje więcej czasu ze względu na nowe metody obsługi rejestrów i brak wiedzy, który bit robi dokładnie co. To samo dotyczy debugowania, nie mówiąc już o tym. Dlatego programiści dość często używają punktów przerwania w swoim kodzie i przechodzą przez niego za pomocą debuggera. Jednak użycie debuggera może wymagać dodatkowego sprzętu (najczęściej kosztownego), a także dodatkowego czasu. Będąc fanem Arduino, wszyscy możemy się zgodzić, że używanie instrukcji drukowania seryjnego do debugowania, a zrozumienie naszego kodu znacznie ułatwia życie. Co możemy powielić na STM8s za pomocą kompilatora Cosmic C i bibliotek SPL? Cóż, jest to bardzo możliwe i właśnie to zamierzamy zrobić w tym trzecim samouczku z naszej serii samouczków.Sprawdź także wprowadzenie do STM8S (samouczek 1) i sterowanie STM8S GPIO (samouczek 2), jeśli jesteś tu zupełnie nowy. Zbadaliśmy również możliwość programowania STM8S z Arduino dla szybkiego startu. Biorąc to wszystko pod uwagę, przejdźmy do samouczka.
Komunikacja szeregowa na STM8S103F3P6
Z arkusza danych STM8S103F3P6 widzimy, że nasz 8-bitowy kontroler obsługuje komunikację UART w wielu różnych trybach. Kontroler ma również wyjście zegara do synchronicznej komunikacji UART i może również obsługiwać SmarCard, IrDA i LIN. Ale nie będziemy tego badać w tym samouczku, aby uniknąć złożoności. Dowiemy się, jak czytać i pisać proste UART.
Samouczek zawiera również plik nagłówkowy o nazwie stm8s103 serial.h, za pomocą którego możesz wykonywać proste polecenia UART, takie jak Serial begin, Serial read, serial print, itp. Zasadniczo będziesz mógł wydrukować char, int i string na monitorze szeregowym a także czytać char z monitora szeregowego. Pod koniec tego samouczka będziesz w stanie sterować diodą LED z monitora szeregowego i uzyskać informacje zwrotne o stanie diody LED. Wspomniany powyżej plik nagłówkowy zależy od bibliotek SPL, więc upewnij się, że postępowałeś zgodnie z samouczkiem wprowadzającym.
Szeregowe szpilki komunikacyjne w STM8S103F3P6
Zacznijmy od strony sprzętowej. Biorąc okiem na wyprowadzeń na STM8S103F3P6 mikrokontrolera podanym poniżej, możemy zobaczyć, że szpilki 1, 2 i 3 będą wykorzystywane do komunikacji UART.
Pośród tych trzech pin 1 to pin zegara UART, który będzie używany tylko podczas synchronicznej komunikacji UART, więc nie będziemy go tutaj potrzebować. Pin 2 to pin nadajnika UART, a pin 3 to pin odbiornika UART. Zwróć uwagę, że te piny mogą również podwoić się jako pin analogowy lub normalny pin GPIO.
Schemat obwodu komunikacji szeregowej STM8S
Schemat obwodu jest tutaj bardzo prosty, musimy podłączyć nasz ST-LINK 2 do programowania i konwerter USB na TTL do odczytu danych szeregowych. Zwróć uwagę, że nasz kontroler STM8S działa na poziomie logicznym 3,3 V, więc upewnij się, że konwerter USB na TTL obsługuje również logikę 3,3 V. Pełny schemat obwodu przedstawiono poniżej.
Musisz podłączyć ST-link do jednego portu USB, a konwerter USB na TTL do innego portu USB laptopa, aby móc jednocześnie programować i monitorować dane. Połączenie UART jest proste, wystarczy podłączyć uziemienie i pin Rx / Tx mikrokontrolera STM8S do pinów Tx / Rx konwertera USB na TTL. Tutaj zasiliłem kontroler pinem Vcc ST-Link i zostawiłem pin vss konwertera TTL otwarty, możesz to również zrobić na odwrót. Na rynku dostępnych jest wiele typów konwerterów USB na TTL, po prostu upewnij się, że może on działać na sygnałach logicznych 3,3 V i po prostu szukaj pinów Tx, Rx i GND i wykonaj połączenie pokazane powyżej. Poniżej przedstawiono moją konfigurację sprzętu.
Aby umożliwić komunikację szeregową, udostępniliśmy plik nagłówkowy STM8S_Serial.h . Korzystając z tego pliku nagłówkowego, możesz wykonywać proste funkcje podobne do Arduino dla komunikacji szeregowej.
Możesz znaleźć wszystkie wymagane pliki do tego projektu na naszej stronie STM8S103F3_SPL Github. Jeśli potrzebujesz tylko tego konkretnego pliku nagłówkowego, możesz go pobrać z poniższego łącza.
Pobierz STM8S_Serial.h
Konfigurowanie STVD do komunikacji szeregowej
Do pracy z komunikacją szeregową będziemy używać wielu funkcji pliku nagłówkowego STM8S_Serial.h , o której mówiliśmy wcześniej. Ale biblioteka ma inne zależności, wiele plików nagłówkowych i C związanych z SPL UART i Clock. Więc od tego momentu lepiej jest dołączyć wszystkie pliki nagłówkowe i C do naszego projektu, aby uniknąć błędu kompilacji. Moje środowisko pracy STVD wygląda tak.
Upewnij się, że dołączyłeś wszystkie pliki źródłowe SPL i dołącz plik, tak jak to zrobiliśmy w naszym pierwszym samouczku. Upewnij się również, że dodałeś plik nagłówkowy stm8s103_serial.h . Nie ma pliku C dla tego nagłówka.
Programowanie STM8S do komunikacji szeregowej
Gdy konfiguracja projektu STVD jest gotowa, możemy rozpocząć pisanie naszego kodu w pliku main.c. Pełny kod tego samouczka można znaleźć na dole tej strony. Wyjaśnienie jest następujące.
Pierwszym krokiem jest dołączenie wymaganych plików nagłówkowych, tutaj dodałem główny plik nagłówkowy (stm8s) i plik nagłówkowy stm8s_103_serial , który właśnie pobraliśmy .
// Wymagane nagłówki #include "STM8S.h" #include "stm8s103_serial.h" //https://github.com/CircuitDigest/STM8S103F3_SPL/blob/master/stm8s103%20Libraries/stm8s103_Serial.h
Następnie używamy makr projektowych do określenia pinów wejściowych i wyjściowych. Tutaj będzie sterować tylko wbudowaną diodą LED, która jest podłączona do pinu 5 portu B, więc nadajemy mu nazwę test_LED .
#define test_LED GPIOB, GPIO_PIN_5 // testowa dioda LED jest podłączona do PB5
Przechodząc dalej do funkcji głównej, zdefiniujemy pin jako wyjście. Jeśli nie jesteś zaznajomiony z podstawowymi funkcjami GPIO, wróć do samouczka STM8S GPIO.
// Definicje pinów // Zadeklaruj PB5 jako push pull Pin wyjściowy GPIO_Init (test_LED, GPIO_MODE_OUT_PP_LOW_SLOW);
Następnie inicjalizujemy nasze porty komunikacji szeregowej z szybkością 9600 bodów. Dla tych, którzy są nowi, 9600 to szybkość, z jaką bity danych będą przesyłane podczas komunikacji. Jeśli ustawisz tutaj 9600, musisz również ustawić to samo w oprogramowaniu monitorującym. Następnie drukujemy również napis „Enter polecenie” i przechodzimy do następnej linii.
Serial_begin (9600); // Zainicjuj komunikację szeregową z szybkością 9600 bodów Serial_print_string ("Wprowadź polecenie"); // wypisuje łańcuch Serial_newline (); // przejdź do następnej linii
Przechodząc do nieskończonej pętli while, używamy funkcji Serial_available, aby sprawdzić, czy są jakieś przychodzące dane szeregowe. Jeśli tak, czytamy i zapisujemy go w zmiennej o nazwie ch, a także drukujemy to samo używając Serial_print . Wówczas, jeśli otrzymana wartość będzie równa 0, wyłączymy diodę, a jeśli będzie równa 1, włączymy diodę
if (Serial_available ()) {Serial_print_string ("Nacisnąłeś:"); ch = Serial_read_char (); Serial_print_char (ch); Serial_newline (); if (ch == '0') GPIO_WriteHigh (test_LED); // LED WYŁĄCZONY if (ch == '1') GPIO_WriteLow (test_LED); // LED ON}
Dzięki temu programowanie tego samouczka jest zakończone, po prostu prześlij kod podany na dole tej strony i powinieneś być w stanie kontrolować diodę LED z monitora szeregowego.
Kontrolowanie LED z monitora szeregowego
Po przesłaniu kodu możesz otworzyć dowolny monitor szeregowy z szybkością 9600 bodów. Użyłem samego monitora szeregowego Arduino dla łatwości korzystania z niego. Naciśnij przycisk resetowania. Powinien zostać wyświetlony komunikat „Wprowadź polecenie”. Następnie, jeśli wpiszesz 1 i naciśniesz enter, wbudowana dioda LED powinna się zaświecić, podobnie dla 0, powinna zgasnąć.
Cała praca jest dostępna w wideo, do którego link znajduje się na dole tej strony. Jeśli masz jakieś pytania, zostaw je w sekcji komentarzy. Możesz również skorzystać z naszych forów, aby zadać inne pytania techniczne.
Głębszy wygląd biblioteki szeregowej STM8S
Dla ciekawskich, którzy chcą wiedzieć, co faktycznie dzieje się w pliku nagłówkowym STM8S103F3_Serial , czytaj dalej….
Ten plik nagłówkowy działa dobrze w programowaniu na poziomie początkującym, ale jeśli używasz innej wersji kontrolera STM8S lub szukasz niektórych zaawansowanych opcji, możesz nieco poprawić ten nagłówek lub bezpośrednio pracować z bibliotekami SPL. Napisałem ten plik nagłówkowy jako dojrzałość z pliku nagłówkowego UART1, wyjaśnienie mojego pliku nagłówkowego jest następujące.
Czytanie postaci z Serial Monitor
Funkcja ta pomaga odczytać pojedynczy znak, który został wysłany do mikrokontrolera z monitora szeregowego.
char Serial_read_char (void) {while (UART1_GetFlagStatus (UART1_FLAG_RXE) == RESET); UART1_ClearFlag (UART1_FLAG_RXNE); return (UART1_ReceiveData8 ()); }
Czekamy, aż flaga RXE zostanie ustawiona, aby zakończyć odbiór, a następnie usuwamy flagę, aby potwierdzić odbiór. Na koniec wysyłamy otrzymane 8-bitowe dane jako wynik tej funkcji.
Drukowanie znaku na Serial Monitor
Ta funkcja przesyła pojedynczy znak z mikrokontrolera do monitora szeregowego.
void Serial_print_char (wartość znaku) {UART1_SendData8 (wartość); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); // czekaj na wysłanie}
Funkcja po prostu zapisuje 8-bitową wartość i czeka na zakończenie transmisji, sprawdzając UART1_FLAG_TXE na SET
Inicjowanie komunikacji szeregowej
Ta funkcja inicjalizuje komunikację szeregową z wymaganą szybkością transmisji.
void Serial_begin (uint32_t baud_rate) {GPIO_Init (GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init (GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT); UART1_DeInit (); // Deinicjalizacja urządzeń peryferyjnych UART UART1_Init (baud_rate, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE); // (BaudRate, Wordlegth, StopBits, Parity, SyncMode, Mode) UART1_Cmd (ENABLE); }
Oprócz szybkości transmisji są inne parametry, które należy ustawić dla komunikacji szeregowej, takie jak liczba bitów danych, liczba bitów stopu, parzystość itp. Najpopularniejszym (podobnie jak w Arduino) są dane 8-bitowe. z jednym bitem stopu i bez parzystości, a zatem będzie to ustawienie domyślne. W razie potrzeby możesz to zmienić.
Drukowanie liczby całkowitej do monitora szeregowego
W większości przypadków, jeśli używamy monitora szeregowego do debugowania lub monitorowania, możemy chcieć wydrukować zmienną typu int na monitorze szeregowym. Ta funkcja robi dokładnie to
void Serial_print_int (int number) // Funkcja wypisywania wartości int do monitora szeregowego {char count = 0; znak cyfry = ""; while (liczba! = 0) // podziel int na char tablica {cyfra = liczba% 10; liczyć ++; liczba = liczba / 10; } while (count! = 0) // wypisz tablicę znaków we właściwym kierunku {UART1_SendData8 (cyfra + 0x30); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); // czekaj na wysłanie licznika--; }}
Pobiera wartość całkowitą i konwertuje ją na tablicę znaków w pierwszej pętli while, a następnie w drugiej pętli while, wyślemy każdy ze znaków podobnych do naszej funkcji print char.
Drukowanie nowej linii
Jest to prosta funkcja umożliwiająca wydrukowanie nowego wiersza. Wartość szesnastkowa, aby to zrobić, to „0x0a”, po prostu wysyłamy ją za pomocą 8-bitowego polecenia transmisji.
void Serial_newline (void) {UART1_SendData8 (0x0a); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); // czekaj na wysłanie}
Drukowanie ciągu do monitora szeregowego
Inną przydatną funkcją jest faktyczne drukowanie łańcuchów na monitorze szeregowym.
void Serial_print_string (ciąg znaków) {. char i = 0; while (ciąg! = 0x00) {UART1_SendData8 (ciąg); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); i ++; }}
Ta funkcja również konwertuje ciąg znaków na tablicę znaków i wysyła każdy znak. Jak wiemy, wszystkie ciągi zakończą się wartością zerową. Musimy więc po prostu przechodzić i transmitować znaki, aż osiągniemy zerowy 0x00.
Sprawdzanie, czy dane szeregowe są dostępne do odczytu
Ta funkcja sprawdza, czy w buforze są jakieś dane szeregowe gotowe do odczytu.
bool Serial_available () {if (UART1_GetFlagStatus (UART1_FLAG_RXNE) == TRUE) return TRUE; else zwraca FALSE; }
Sprawdza flagę UART1_FLAG_RXNE , jeśli jest prawdziwa, zwraca prawdę, a jeśli nie, zwraca fałsz.