- Przygotowanie sprzętu
- Zrozumienie pinów GPIO na STM8S103F
- Opis pinów i wskazówki dotyczące wyboru GPIO STM8S103F
- Programowanie STM8S dla wejścia i wyjścia GPIO przy użyciu SPL
- Przesyłanie i testowanie programu
W przypadku mikrokontrolerów program migania diod LED jest odpowiednikiem programu „hello world”. W naszym poprzednim samouczku dowiedzieliśmy się, jak rozpocząć pracę z płytą rozwojową STM8S103F3 oraz jak skonfigurować IDE i kompilator do programowania naszych kontrolerów STM8S. Dowiedzieliśmy się również, jak korzystać ze standardowych bibliotek peryferyjnych oraz jak skompilować i przesłać kod do naszego mikrokontrolera. Po uwzględnieniu wszystkich podstaw, zacznijmy pisać kod. W tym samouczku nauczymy się, jak wykonywać ogólne funkcje GPIO na kontrolerach STM8S. Płytka ma już wbudowaną diodę LED podłączoną do pinu 5 portu B, nauczymy się migać tą diodą, a także dodać zewnętrzną diodę LED i sterować nią za pomocą przycisku. Jeśli jesteś zupełnie nowy, zdecydowanie zaleca się przeczytanie poprzedniego samouczka, zanim przejdziesz dalej.
Przygotowanie sprzętu
Zanim zagłębimy się w program, przygotujmy połączenia sprzętowe. Jak wspomniano wcześniej, będziemy tutaj używać dwóch diod LED, jedna to wbudowana dioda LED, która będzie migać w sposób ciągły, a druga to zewnętrzna dioda LED, która będzie przełączana za pomocą przycisku. Chodzi o to, aby nauczyć się wszystkich funkcji GPIO w prostej konfiguracji. Wbudowana dioda LED jest już podłączona do PB5 (pin5 PORTB), więc właśnie podłączyłem diodę LED do PA3 i przycisk do PA2, jak widać na poniższym schemacie.
Ale ze wszystkich pinów wyjściowych dostępnych w naszym kontrolowanym celu wybrałem PA3 na wyjście i PA2 na wejście? Pytania są ważne i wyjaśnię to w dalszej części tego artykułu. Poniżej przedstawiono moją konfigurację sprzętu dla tego samouczka. Jak widać, podłączyłem również programator ST-link do pinów programujących, które nie tylko zaprogramują naszą płytkę, ale również będą działać jako źródło zasilania.
Zrozumienie pinów GPIO na STM8S103F
Wracając do pytania, dlaczego PA2 jest wejściem i dlaczego PA3 jest wyjściem? Aby to zrozumieć, przyjrzyjmy się bliżej pinoutowi mikrokontrolera, który pokazano poniżej.
Zgodnie ze schematem pinoutów mamy cztery porty na naszym mikrokontrolerze, a mianowicie PORT A, B, C i D oznaczone odpowiednio przez PA, PB, PC i PD. Każdy pin GPIO jest również wyposażony w inne specjalne funkcje. Na przykład, PB5 (pin 5 PORT B) może nie tylko działać jako pin GPIO, ale także jako pin SDA do komunikacji I2C i jako pin wyjściowy Timera 1. Tak więc, jeśli użyjemy tego pinu do prostych celów GPIO, takich jak podłączenie diody LED, nie będziemy w stanie jednocześnie używać I2C i diody LED. Niestety wbudowana dioda LED jest podłączona do tego pinu, więc nie mamy tu dużego wyboru, aw tym programie nie będziemy używać I2C, więc nie jest to duży problem.
Opis pinów i wskazówki dotyczące wyboru GPIO STM8S103F
Prawdę mówiąc, użycie PA1 jako pinu wejściowego nie zaszkodzi, a po prostu zadziała. Ale celowo podniosłem to, aby dać mi możliwość pokazania kilku typowych pułapek, w które możesz wpaść podczas wybierania pinów GPIO w nowym mikrokontrolerze. Najlepszym sposobem uniknięcia pułapek jest zapoznanie się ze szczegółami pinów i opisami pinów podanymi w arkuszu danych STM8S103F3P6. Dla opisu pinów mikrokontrolera STM8S103F3P6 szczegóły, które są wymienione w arkuszu danych, są pokazane poniżej obrazów.
Piny wejściowe naszego mikrokontrolera mogą być pływające lub słabo podciągane, a styki wyjściowe mogą być otwarte lub push-pull. Różnica między pinami Open Drain i Push-Pull Output została już omówiona, dlatego nie będziemy się tym zajmować. Mówiąc prościej, pin wyjściowy Open Drain może sprawić, że wyjście będzie tylko tak niskie, a nie tak wysokie, podczas gdy pin wyjściowy push-pull może sprawić, że wyjście będzie zarówno wysokie, jak i wysokie.
Oprócz tego z powyższej tabeli można również zauważyć, że pin wyjściowy może być szybkim wyjściem (10 MHz) lub wolnym wyjściem (2 MHz). To określa prędkość GPIO, jeśli chcesz bardzo szybko przełączyć piny GPIO między wysoką a niską, możemy wybrać szybkie wyjście.
Niektóre piny GPIO w naszym kontrolerze obsługują True Open Drain (T) i High Sink Current (HS), jak wspomniano na powyższym obrazku. Istotna różnica między Open Drain i True Open Drain polega na tym, że wyjście podłączone do otwartego drenu nie może być wyciągnięte wyżej niż napięcie robocze mikrokontrolera (Vdd), podczas gdy prawdziwy pin wyjściowy otwartego spustu może być wyciągnięty wyżej niż Vdd. Kołki z funkcją High Sink oznaczają, że może pobierać więcej prądu. Prąd źródła i wypływu dowolnego pinu GPIO HS wynosi 20 mA, podczas gdy linia zasilająca może pobierać do 100 mA.
Jeśli przyjrzysz się bliżej powyższemu obrazowi, zauważysz, że prawie wszystkie piny GPIO są typu High Sink Current (HS), z wyjątkiem PB4 i PB5, które są typu True Open Drain (T). Oznacza to, że te szpilki nie mogą być wykonane wysoko, nie będą w stanie zapewnić 3,3 V, nawet gdy pin jest wykonany wysoko. Dlatego wbudowana dioda LED jest podłączona do 3,3 V i uziemiona przez PB5, zamiast zasilać ją bezpośrednio z pinu GPIO.
Szczegółowy opis pinów znajduje się na stronie 28 arkusza danych. Jak wspomniano na powyższym obrazku, PA1 jest automatycznie konfigurowany jako słaby pull-up i nie jest zalecane, aby był używany jako pin wyjściowy. W każdym razie może być używany jako pin wejściowy wraz z przyciskiem, ale zdecydowałem się użyć PA2 tylko po to, aby spróbować włączyć podciąganie z programu. To tylko kilka podstawowych rzeczy, które przydadzą się podczas pisania znacznie bardziej skomplikowanych programów. Na razie w porządku, jeśli wiele rzeczy odbije się od twojej głowy, przejdziemy do tej warstwy w innych samouczkach.
Programowanie STM8S dla wejścia i wyjścia GPIO przy użyciu SPL
Utwórz obszar roboczy i nowy projekt, jak omówiliśmy w naszym pierwszym samouczku. Możesz dodać wszystkie pliki nagłówkowe i źródłowe lub tylko dodać pliki gpio, config i stm8s. Otwórz plik main.c i zacznij pisać swój program.
Upewnij się, że dołączyłeś pliki nagłówkowe, jak pokazano na powyższym obrazku. Otwórz plik main.c i uruchom kod. Pełny kod main.c znajduje się na dole tej strony, a stamtąd będzie można również pobrać plik projektu. Objaśnienie kodu jest następujące, możesz również zapoznać się z instrukcją obsługi SPL lub filmem, do którego link znajduje się na dole tej strony, jeśli nie masz pewności co do części kodującej.
De-inicjalizacja wymaganego portu
Rozpoczynamy nasz program od de-inicjalizacji wymaganych portów. Jak omówiliśmy wcześniej, każdy pin GPIO będzie miał wiele innych związanych z nim funkcji, poza działaniem jak normalne wejście i wyjście. Jeśli te styki były wcześniej używane w innych aplikacjach, należy je zdeinicjalizować przed ich użyciem. Nie jest to obowiązkowe, ale jest dobrą praktyką. Poniższe dwie linie kodu służą do deinicjalizacji portu A i portu B. Wystarczy użyć składni GPIO_DeInit (GPIOx); i podaj nazwę portu zamiast x.
GPIO_DeInit (GPIOA); // przygotuj Port A do pracy GPIO_DeInit (GPIOB); // przygotuj Port B do pracy
Deklaracja wejścia i wyjścia GPIO
Następnie musimy zadeklarować, które piny będą używane jako wejście, a które jako wyjście. W naszym przypadku pin PA2 zostanie użyty jako wejście, zadeklarujemy również ten pin z wewnętrznym Pull-upem, abyśmy nie musieli używać go zewnętrznie. Składnia to GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Gdzie x to nazwa portu, y to numer pinu, az to tryb pinów GPIO.
// Zadeklaruj PA2 jako wejście podciągnij pin GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Następnie musimy zadeklarować piny PA3 i PB5 jako wyjście. Ponownie, możliwych jest wiele typów deklaracji wyjściowych, ale będziemy używać „GPIO_MODE_OUT_PP_LOW_SLOW”, co oznacza, że zadeklarujemy go jako pin wyjściowy typu push-pull z małą prędkością. Domyślnie wartość będzie niska. Składnia będzie taka sama.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Zadeklaruj PB5 jako push pull Pin wyjściowy GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
Poniższa migawka z instrukcji obsługi SPL wymienia wszystkie możliwe tryby GPIO (z).
Nieskończona pętla while
Po zadeklarowaniu pinu musimy stworzyć nieskończoną pętlę, wewnątrz której będziemy ciągle migać diodą LED i monitorować stan przycisku, aby przełączyć diodę. Nieskończona pętla może tworzyć się za pomocą while (1) lub for (;;) . Tutaj użyłem while (1).
podczas (1) {}
Sprawdzanie stanu pinu wejściowego
Musimy sprawdzić stan pinu wejściowego, składnia do tego to GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); gdzie x to nazwa portu, a y to numer pinu. Jeśli pin jest wysoki, otrzymamy „1”, a jeśli pin jest niski, otrzymamy „0”. Kiedyś wewnątrz pętli if sprawdzaliśmy, czy pin jest wysoki czy niski.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // po naciśnięciu przycisku
Tworzenie wysokiego lub niskiego pinu GPIO
Aby zrobić pin GPIO High lub Low, możemy użyć GPIO_WriteHigh (GPIOx, GPIO_PIN_y); i GPIO_WriteLow (GPIOx, GPIO_PIN_y); odpowiednio. Tutaj sprawiliśmy, że dioda LED włącza się, gdy przycisk jest naciśnięty i wyłącza się, gdy przycisk nie jest naciśnięty.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // jeśli naciśnięto przycisk GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ON w przeciwnym razie GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // Dioda LED wyłączona
Przełączanie pinów GPIO
Aby przełączyć pin GPIO, mamy GPIO_WriteReverse (GPIOx, GPIO_PIN_y); wywołanie tej funkcji zmieni stan pinu wyjściowego. Jeśli pin jest wysoki, zostanie zmieniony na niski, a jeśli jest niski, zostanie zmieniony na wysoki. Używamy tej funkcji do migania wbudowanej diody LED na PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Funkcja opóźnienia
W przeciwieństwie do Arduino, kosmiczny kompilator nie posiada predefiniowanej funkcji opóźnienia. Musimy więc stworzyć samodzielnie. Moja funkcja opóźnienia jest podana poniżej. Wartość doe the delay zostanie odebrana w zmiennej ms i użyjemy dwóch for do wstrzymania lub wykonania programu. Podobnie jak _asm („nop”) jest instrukcją asemblera, która oznacza brak operacji. Oznacza to, że kontroler będzie przechodził do pętli for bez wykonywania żadnej operacji, tworząc w ten sposób opóźnienie.
void delay (int ms) // Definicja funkcji {int i = 0; int j = 0; for (i = 0; i <= ms; i ++) {for (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Nie wykonuj żadnej operacji // kod zespołu}}
Przesyłanie i testowanie programu
Teraz, gdy nasz program jest gotowy, możemy go przesłać i przetestować. Po przesłaniu mój sprzęt działał zgodnie z oczekiwaniami. Wbudowana czerwona dioda LED migała co 500 milisekund, a zewnętrzna zielona dioda LED włączała się za każdym razem, gdy naciskałem przełącznik.
Pełną pracę można znaleźć w poniższym filmie wideo. Po osiągnięciu tego punktu możesz spróbować podłączyć przełącznik i diodę LED do różnych pinów i ponownie napisać kod, aby zrozumieć koncepcję. Możesz także pobawić się czasem opóźnienia, aby sprawdzić, czy dobrze zrozumiałeś pojęcia.
Jeśli masz jakieś pytania, zostaw je w sekcji komentarzy poniżej, a w przypadku innych pytań technicznych możesz skorzystać z naszych forów. Dziękujemy za śledzenie. Do zobaczenia w następnym samouczku.