Spisu treści:
- Krok 1: Piny i szpilki….Dlaczego kod nie działa?
- Krok 2: Zdefiniujmy niektóre szpilki…
- Krok 3: PinMode()…Jak będziesz używać swoich szpilek…
- Krok 4: AnalogWrite() kontra PwmWrite()…Wyjście analogowe w 2 smakach
- Krok 5: Komunikacja szeregowa STM32
- Krok 6: Przekazywanie wartości do mikrokontrolera
- Krok 7: A jeśli chciałbym wpisać trzy cyfry…. czy nawet więcej??
Wideo: A więc ładujesz bootloader STM32duino do swojej „niebieskiej pigułki”… Więc co teraz?: 7 kroków
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:28
Jeśli już przeczytałeś moje instrukcje wyjaśniające, jak załadować bootloader STM32duino lub inną podobną dokumentację, spróbuj załadować przykładowy kod i…. może w ogóle nic się nie dzieje.
Problem polega na tym, że wiele, jeśli nie wszystkie przykłady "Ogólnego" STM32 nie będą działać po wyjęciu z pudełka. Niezbędne będą drobne zmiany, aby następnie działać na płycie STM32 "Niebieska pigułka".
Wybiorę 4 przykłady kodu, aby wyjaśnić, co należy zmienić i dlaczego. Kody to: „BlinkWithoutDelay”, „Fading”, „Dimmer” i „AnalogInSerial”.
Uwaga: NIE kodowałem niczego. Wprowadzam tylko drobne zmiany w kodach stworzonych przez:
David A. Mellis i późno zmodyfikowany przez Toma Igoe, Marti Bolivar i kilka przypadków przez Scotta Fitzgeralda
Tom Igoe i późno zmodyfikowany przez Bryana Newbolda
Dlatego wolę zachowywać nazwiska autorów nawet w modyfikowanych przeze mnie kodach, zachowując informacje o kreacji.
Krok 1: Piny i szpilki…. Dlaczego kod nie działa?
Rzućmy okiem na pinezkę STM32 „Niebieska pigułka”. Uwaga piny są identyfikowane jako PA1 lub PC2….coś w tym stylu.
Jeśli spojrzysz na przykład na kod "BlinkWithoutDelay", pin jest zadeklarowany jako "33"…. Dlaczego?
Podejrzewam, że to dlatego, że Pan Marti Bolivar przeportował ten kod na płytę MAPLE.
Myślę, że nie było jego intencją, aby kod był zgodny z płytami "Blue Pill".
Piny płytki mini Maple i Maple są zadeklarowane numerycznie, podobnie jak Arduino, chociaż używają numerów takich jak 33, 24 i niektóre podobne.
Powiedziałem, że kod nie działa? Mój błąd. Kod skompiluje się bez błędów i poprawnie wgra do "Blue Pill", więc moim zdaniem rzeczywiście działa, ale używając wyjścia GPIO nie oczekujemy. Może być nawet niedostępny.
Tak niewiele zmian jest koniecznych w kodzie, aby działał zgodnie z oczekiwaniami.
Krok 2: Zdefiniujmy niektóre szpilki…
Jest to dobra praktyka kodowania deklarowania zasobów jako łatwych do zidentyfikowania lub oznaczania zmiennych lub stałych. Ułatwi to zrozumienie kodu i rozwiązywanie problemów.
Użyłem deklarowania pinów Arduino w ten sposób:
…
const int ledPin =13;
…"
Jeśli mnie lubisz, może zadajesz sobie pytanie: "Jak mogę zadeklarować piny o nazwach takich jak PC13???"
Odpowiedź brzmi: Użyj "#define" instrukcji C.
Tak więc, zgodnie z rysunkiem pinów, PC13 jest pinem, który mamy na płycie LED w "BluePill". Aby z niego skorzystać, zadeklarowałbym tak, zaraz po definicji bibliotek (#include…) i przed wszystkim innym:
…
#define LedPin PC13
…"
Zauważ, że NIE ma ";" zakończenie linii, przypisanie NOR "=".
Porównaj oba kody. Jednym z nich jest oryginalny przykład załadowany z IDE. Drugi to ten, który dostosowałem do pracy z "BluePill".
Zdecydowanie zalecam zadeklarowanie wszystkich pinów, które zamierzasz użyć w kodzie. Nawet te zamierzają używać jako wejście ADC (więcej o tym później).
To ułatwi ci życie.
Krok 3: PinMode()…Jak będziesz używać swoich szpilek…
Zanim przejdziemy dalej, zrozummy funkcję PinMode().
Podobnie jak Arduino, piny STM32 mają wiele funkcji. Najprostszym sposobem wybrania jednego lub drugiego jest użycie instrukcji pinMode().
Arduino ma dostępne tylko 3 tryby, INPUT, OUTPUT lub INPUT_PULLUP.
Z drugiej strony STM32 ma wiele odmian pinMode(). Oni są:
WYJŚCIE - Podstawowe wyjście cyfrowe: gdy pin jest WYSOKI, napięcie jest utrzymywane na poziomie +3,3 V (Vcc), a gdy jest NISKI, jest ściągane do masy
OUTPUT_OPEN_DRAIN - W trybie otwartego spustu pin wskazuje „niski”, akceptując przepływ prądu do ziemi i „wysoki”, zapewniając zwiększoną impedancję
INPUT_ANALOG - Jest to specjalny tryb, gdy pin będzie używany do odczytów analogowych (nie cyfrowych). Umożliwia wykonanie konwersji ADC na napięciu na bolcu
INPUT_PULLUP - Stan pinu w tym trybie jest zgłaszany tak samo jak w przypadku INPUT, ale napięcie pinu jest delikatnie „podciągane” w kierunku +3,3V
INPUT_PULLDOWN - Stan pinu w tym trybie jest zgłaszany w taki sam sposób jak w przypadku INPUT, ale napięcie pinu jest delikatnie „obniżone” w kierunku 0V
INPUT_FLOATING - Synonim INPUT
PWM - Jest to specjalny tryb, kiedy pin będzie używany do wyjścia PWM (specjalny przypadek wyjścia cyfrowego)
PWM_OPEN_DRAIN -Podobnie jak PWM, z tą różnicą, że zamiast naprzemiennych cykli LOW i HIGH, napięcie na pinie składa się z naprzemiennych cykli LOW i Floating (odłączony)
(uwaga: pobrany z
Po prostu otwieram ten nawias, ponieważ kiedy zaczynasz tworzyć własny kod, uważaj, aby użyć poprawnego pinMode() dla swoich potrzeb.
Krok 4: AnalogWrite() kontra PwmWrite()…Wyjście analogowe w 2 smakach
Przed użyciem pinów GPIO "Blue Pill" należy zadeklarować jego zachowanie, czyli jak będzie działać. Dokładnie to robi funkcja pinMode().
Skupmy się więc teraz na tym, jak poprawnie ustawić wyjście analogowe. Może być zadeklarowany jako tryb OUTPUT lub tryb PWM.
W ten sam sposób wartości analogowe można przypisać do GPIO na 2 sposoby: analogWrite() lub pwmWrite(), ALE, analogWrite() BĘDZIE działał tylko wtedy, gdy pinMode()= OUTPUT. Z drugiej strony pwmWrite() BĘDZIE działał tylko wtedy, gdy pinMode()=PWM.
Weźmy na przykład PA0: jest to kandydat na wyjście analogowe/PWM.
analogWrite(): deklarujemy w ten sposób:
….
#define ledPin PA0
pinMode (ledPin, WYJŚCIE);
analogWrite(ledPin, <numer>);
……"
gdzie liczba musi wynosić od 0 do 255, jak Arduino. W rzeczywistości jest wstecznie kompatybilny z Arduino.
pwmWrite(): zadeklaruj w ten sposób:
…
#define ledPin PA0
pinMode (ledPin, PWM);
pwmWrite(ledPin, <liczba.>);
…."
Gdzie liczba musi mieścić się w zakresie 0~65535, rozdzielczość znacznie wyższa niż Arduino.
Na zdjęciach możliwe jest porównanie 2 kodów. Możesz również zobaczyć oryginalny kod.
Krok 5: Komunikacja szeregowa STM32
Zobaczmy jak ułożone są interfejsy USART w STM32. Tak, interfejsy w liczbie mnogiej…..
"Niebieska pigułka" ma 3 USART-y (RX/TX 1~3) i jeśli używasz bootloadera pozwala na użycie USB, nie jest on podłączony do żadnego z nich.
W zależności od tego, czy używasz USB, czy nie, musisz zadeklarować port szeregowy w taki lub inny sposób w swoim kodzie.
Przypadek 1: Korzystanie z USB:
W ten sposób szkice są pobierane bezpośrednio przez USB. Nie ma potrzeby przesuwania zworki BOOT0 do pozycji 1 iz powrotem do pozycji 0.
W tym przypadku każdorazowe zadeklarowanie „Serial” bez indeksu oznacza komunikację przez USB.
Tak więc Serial1 oznacza TX/RX 1 (piny PA9 i PA10); Serial2 oznacza TX/RX 2 (piny PA2 i PA3), a Serial 3 oznacza TX/RX 3 (piny PA10 i PA11).
W ten sposób pracujemy. Przedstawię zmiany na przykładach dla tego sposobu kodowania.
Kolejna sprawa: „Serial USB” nie wymaga inicjalizacji. Innymi słowy, „…Serial.begin(15200);” to nie jest konieczne.
Możliwe jest wywołanie dowolnej funkcji Serial (Serial.read(), Serial.write(), itp.) bez żadnej inicjalizacji.
Jeśli z jakiegoś powodu jest on obecny w kodzie, kompilator go zignoruje.
Przypadek 2: Korzystanie z przejściówki z serii TTL na USB:
W ten sposób bootloader nie obsługuje natywnej komunikacji USB STM32, więc do wgrania szkiców potrzebny jest adapter USB do portu szeregowego podłączony do TX/RX 1 (piny PA9 i PA10).
W tym przypadku zawsze "Serial" bez indeksu jest kodem, czyli TX/RX1 (port używany do wgrania kodu). Tak dalej, Serial1 odnosi się do TX/RX 2 (styki PA2 i PA3), a Serial2 odnosi się do TX/RX 3 (styki PA10 i PA11). Brak dostępnego Serial3.
Krok 6: Przekazywanie wartości do mikrokontrolera
Przykład dimmera to prosty sposób na pokazanie jak przekazać wartość do mikrokontrolera.
Zakłada przekazanie wartości od 0 do 255, aby sterować jasnością LED.
NIE będzie działać zgodnie z oczekiwaniami w Blue Pill z powodu:
- Aby użyć funkcji pwmWrite(), pinMode() MUSI być zadeklarowana jako tryb PWM.
- Nigdy nie dostaniesz całego 3-cyfrowego numeru. Funkcja Serial.read() przechwytuje tylko zawartość bufora, którą jest "BYTE". jeśli wpiszesz "100" i naciśniesz "enter", tylko ostatnie "0" zostanie przechwycone z bufora. A jego wartością będzie „48” (dziesiętna wartość ASCII dla „0”). Jeśli zamierzamy wystawić wartość „100”, należy wpisać „d”. Więc można powiedzieć, że przekonwertuje wartość dziesiętną symbolu ASCII na jasność LED, prawda??…. Cóż, rodzaj…
- Problem, mapowanie wartości bezpośrednio z funkcji Serial.read() to sztuczka. Jest prawie pewne, że uzyskasz nieoczekiwane wartości. Lepszym rozwiązaniem jest przechowywanie zawartości bufora w zmiennej tymczasowej i NIŻ jej mapowanie.
Jak wyjaśniłem wcześniej w punkcie 2, wprowadzany przeze mnie kod pozwoli na wpisanie symbolu ASCII, a to będzie sterować jasnością diody LED w oparciu o jej wartość dziesiętną ASCII… np. „spacja” to wartość 32 (właściwie jest to najniższy możliwy do wpisania znak) a "}" jest możliwym najwyższym (wartość 126). Inne znaki są niedrukowalne, więc terminal nie zrozumie lub mogą być złożone ze znaków (tak jak "~" jest martwym klawiszem na mojej klawiaturze i nie będzie działać poprawnie). Oznacza to, że ten znak złożony po wejściu do terminala wyśle sam znak i coś innego. Zwykle nie do druku. I czy ten ostatni kod zostanie przechwycony. Pamiętaj również, że Twój terminal nie powinien w tym przypadku wysyłać ani „Zwrot karetki” ani „Wysuw linii”. Musisz zwrócić na to uwagę, aby kod działał poprawnie.
Jeśli upadłeś, jest to trochę zagmatwane, robi się gorzej…..
Krok 7: A jeśli chciałbym wpisać trzy cyfry…. czy nawet więcej??
Odbieranie wielu znaków z komunikacji szeregowej nie jest prostym zadaniem.
Bufor szeregowy to stos znaków FIFO. Za każdym razem, gdy funkcja Serial.read() jest wywoływana, pierwszy wysłany znak jest usuwany ze stosu i przechowywany w innym miejscu. Zwykle zmienna typu char w kodzie. Uwaga, w zależności od sprzętu, zwykle istnieje limit czasu, w jaki bufor dziennika może przechowywać informacje.
Jeśli zamierzasz wprowadzić więcej niż jedną cyfrę przez port szeregowy, musisz "skomponować" łańcuch znak po znaku, ponieważ dostaną się one do bufora UART.
Oznacza to cykliczne odczytywanie każdego znaku bufora, przechowywanie w zmiennej temp, załadowanie go na pierwszej pozycji tablicy ciągów, przejście do następnej pozycji i rozpoczęcie od nowa, aż… cóż, zależy od aplikacji. Istnieją 2 sposoby zakończenia cyklu:
- Używając znaku „znacznika końca”, np. „Powrót karetki” lub „Wysuw wiersza”. Jak tylko znak "end Mark" zostanie znaleziony, pętla się kończy.
- Alternatywnie, liczba znaków w łańcuchu może być ograniczona, podobnie jak liczba cykli interaktywnych. Kiedy osiągnie limit, powiedzmy, 4, sam zdobądź rutynowe zakończenia.
Spójrzmy na prosty przykład, jak to zrobić:
- Ustaw znak „koniec”, np. „\n” (oznacza to znak ASCII wysuwu wiersza).
- zapętlenie w międzyczasie Serial.available() jest prawdziwe
- przechowywanie Serial.read() skutkuje tymczasową zmienną char. Pamiętaj: jak tylko Serial.read() faktycznie "czyta" bufor, jest on czysty i ładują się do niego kolejne znaki.
- inkrementuj zmienną łańcuchową o ten znak
- Jeśli ostatnim znakiem jest "end" wyjdź z pętli.
Zwykle procedura pobierania tablicy znaków szeregowych wygląda jak obrazek.
Został on oparty na obszernej adaptacji oryginalnego kodu pana Davida A. Mellisa.
Możesz go używać i testować. Pamiętaj: wartości MUSZĄ być wpisane w formacie 3 cyfrowym.
To na razie. Nie będę się rozpisywał o dodatkowe szczegóły komunikacji szeregowej. Jest to zbyt skomplikowane, aby to omówić tutaj i zasługuje na własne Intructables.
Mam nadzieję, że pomoże ci to użyć przykładów w Blue Pill i da ci trochę oświecenia, jak poprawny kod dla tej małej tablicy.
Do zobaczenia w innych instruktażach.
Zalecana:
Pozbywanie się pierścieniowego znaku słonecznego: Zrobiłem to źle, więc nie musisz: 11 kroków
Ring Solar Sign Teardown: Zrobiłem to źle, więc nie musisz: Mam dzwonek do drzwi, który jest całkiem niesamowity. Tak za Ring. Potem dostałem aparat Ring Stick-up, kiedy odbywały się wszystkie wyprzedaże online w okolicach Święta Dziękczynienia. 50 USD zniżki i wysłali mi ten fajny znak solarny Ring ZA DARMO (tylko 49 USD!). Jestem pewien, że
Alternatywa dla Arduino - programowanie niebieskiej pigułki STM32 przez USB: 5 kroków
Alternatywa dla Arduino - Programowanie Blue Pill STM32 przez USB: Ty i ja uwielbiamy płyty Arduino, od najmniejszego Attiny85 do największego MEGA2560. Jeśli jednak potrzebujesz większej szybkości, większej liczby wejść analogowych, większej precyzji, ale nadal nie chcesz przełączać się z programowania Arduino, istnieje eleganckie rozwiązanie
Inteligentne pudełko na pigułki (IDC2018IOT): 8 kroków
Smart Pill Box (IDC2018IOT): To jest projekt Jonathan Braslaver i Maor Stamati Final w trakcie IOT IDC w 2018 roku. Jest to w pełni działający prototyp z następującymi cechami:1. Wysyła SMS-y
Więc chcesz zbudować gigantycznego robota.: 19 kroków (ze zdjęciami)
Więc chcesz zbudować gigantycznego robota.: Mówisz, że chcesz zbudować gigantycznego robota? Jaki jest Twój cel? Dominacja na świecie? Twoja dziewczyna nie dostanie dla ciebie tego piwa? Cokolwiek to jest, oto jak zacząć budować robota. Celem tego robota było stworzenie rekwizytu scen
Wszyscy inni robią podstawkę pod laptopa, więc dlaczego nie mogę?: 8 kroków (ze zdjęciami)
Wszyscy inni robią podstawkę pod laptopa, więc dlaczego ja nie mogę?: Albo jak przekształciłem tacę w podstawkę pod laptopa. Nie mamy telewizora, ale lubimy leżeć na kocu i oglądać DVD na laptopie. Ta podstawka pod laptopa zapewni dobrą stabilność i przepływ powietrza