Spisu treści:

A więc ładujesz bootloader STM32duino do swojej „niebieskiej pigułki”… Więc co teraz?: 7 kroków
A więc ładujesz bootloader STM32duino do swojej „niebieskiej pigułki”… Więc co teraz?: 7 kroków

Wideo: A więc ładujesz bootloader STM32duino do swojej „niebieskiej pigułki”… Więc co teraz?: 7 kroków

Wideo: A więc ładujesz bootloader STM32duino do swojej „niebieskiej pigułki”… Więc co teraz?: 7 kroków
Wideo: AVT1675 - STM32duino - KOMPATYBILNA Z ARDUINO PŁYTKA Z STM32F103C8T6 2024, Lipiec
Anonim
Więc ładujesz bootloader STM32duino w swoim
Więc ładujesz bootloader STM32duino w swoim
Więc ładujesz bootloader STM32duino w swoim
Więc ładujesz bootloader STM32duino w swoim

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?

Szpilki i szpilki…. Dlaczego kod nie działa?
Szpilki 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…

chodźmy
chodźmy

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

AnalogWrite() kontra PwmWrite()…Wyjście analogowe w 2 smakach
AnalogWrite() kontra PwmWrite()…Wyjście analogowe w 2 smakach
AnalogWrite() kontra PwmWrite()…Wyjście analogowe w 2 smakach
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

Komunikacja szeregowa STM32
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

Przekazywanie wartości do mikrokontrolera
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:

  1. Aby użyć funkcji pwmWrite(), pinMode() MUSI być zadeklarowana jako tryb PWM.
  2. 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…
  3. 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??

A jeśli chciałbym wpisać trzy cyfry…. czy nawet więcej??
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:

  1. 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.
  2. 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: