Skocz do zawartości

Kurs? Raspberry Pi Pico [2] - UART


H1M4W4R1

Pomocna odpowiedź

1875113323_Template(6).thumb.jpg.ba6aa0e938b107140ae0bee489686be0.jpg

O czym w tym rozdziale?

W tym rozdziale dowiesz się czym są magistrale oraz nauczysz się obsługi magistrali UART - przesyłania i pobierania danych z wykorzystaniem gotowej biblioteki.

Czym jest magistrala?

Magistrala to trasa pomiędzy urządzeniami służąca do przesyłania danych. Wyróżniamy magistrale szeregowe i równoległe - w zależności od sposobu przesyłania danych. Niektóre magistrale przesyłają bajt w ciągu stanów wysokich/niskich (lub różnic sygnałów, ale tego nie będziemy dotykać) - są to magistrale szeregowe. Magistrale, które wykorzystują wiele linii i przesyłają bajt w jednej sekwencji zegara (w tym samym czasie) nazywamy równoległymi - jest to dość uproszczony opis, aczkolwiek więcej można doczytać we własnym zakresie  

Przykłady magistrali szeregowych: UART, I2C, SPI, USB, PCI-E, RS-232, RS-485, RS-422

Przykłady magistrali równoległych: PCI (dawno temu nie było złącz  PCI-E w komputerach tylko były złącza PCI )

Ten artykuł bierze udział w naszym konkursie! 🔥
Na zwycięzców czekają karty podarunkowe Allegro, m.in.: 2000 zł, 1000 zł i 500 zł.

konkurs_forbot_nagrody_1-350x147.png

Potrafisz napisać podobny poradnik? Opublikuj go na forum i zgłoś się do konkursu!
Czekamy na ciekawe teksty związane z elektroniką i programowaniem. Sprawdź szczegóły »

UART

UART to podstawowa magistrala, z którą będziesz się komunikował. Jest ona w pełni dupleksowa. Okej kolejny trudny termin. Magistrale dupleksowe pozwalają na równoczesne przesyłanie danych w dwóch kierunkach. Magistrale simpleksowe pozwalają na przesyłanie danych tylko w jednym kierunku. Są też magistrale half-dupleks, która pozwala na przesyłanie w obu kierunkach ale tylko w jednym z dwóch w danym momencie. Dodatkowo UART jest magistralą asynchroniczną - dane nie są przesyłane w określonym porządku czasowym. W dowolnym momencie możesz rozpocząć transmisję na każdej z linii (wysyłania, odbierania) i przesłać dane. Warto również powiedzieć, że UART pozwala wyłącznie na komunikację urządzenie - urządzenie (1:1).

Pinami od UART, których będziemy używać jest pin 0 - odpowiada za transmisję (TX) oraz pin 1 - odpowiada za odbiór danych (RX). 

Uwaga: w magistrali UART ważne jest, by pin TX jednego urządzenia połączyć z pinem RX drugiego urządzenia (skrzyżować połączenie).

Do naszego przykładu wykorzystamy konwerter USB->UART, który pozwoli nam podłączyć tą magistralę do naszego komputera. W tym celu pin 0 na Pico łączymy z pinem RX na konwerterze, pin 1 w Pico łączymy z pinem TX na konwerterze. Pin VCC konwertera łączymy zworką z pinem 3V3 (SPRAWDZIĆ PIĘĆ RAZY, inaczej możemy uszkodzić płytkę!) oraz pin GND konwertera z pinem GND na Pico.

ForBot_16.thumb.png.a1b4acf3abf07aa03fbb61e9fecf52fa.png

Pinout Pi Pico

Czerwona ramka oznacza interesujące nas piny  

RPI-PICO-B_m.thumb.jpg.e229e7301478ba5d06c1860a63754c9d.jpg

Teraz też warto wspomnieć o pobraniu wygodnego programu do komunikacji z UART. Do tego celu polecam RealTerm. Instalujemy i zostawiamy w spokoju (nie zaśmiecamy sobie pulpitu kolejnym oknem )

Komunikujemy się  po UART

Dobrze no to nadszedł czas na komunikację. Na samym początku możemy dodać na szczycie pliku dołączenie dodatkowej biblioteki UART (którą pobieramy i wypakowujemy do folderu z projektem) 😉 [oczywiście mam na myśli pliki z katalogu UART]

Uwaga: wymaga modyfikacji i “refreshu” pliku CMakeLists.txt - niezbędna jest modyfikacja linijki 

add_executable(<NAZWA_PROJEKTU> <NAZWA_PROJEKTU>.cpp)

na

add_executable(<NAZWA_PROJEKTU> <NAZWA_PROJEKTU>.cpp UART.cpp UART.h)

oraz dodanie linijki

target_link_libraries(<NAZWA_PROJEKTU> pico_multicore)

Ta biblioteka powstała by ułatwić Ci programowanie - inaczej kilka godzin musiałbym tłumaczyć wskaźniki i konwersje typów, a tak biblioteka robi to za Ciebie i nie musisz sobie tym aktualnie zawracać głowy.

By dodać bibliotekę musimy na górze naszego głównego pliku dodać:

#include "UART.h"

I jesteśmy szczęśliwi 😉

Teraz możemy napisać prosty program, który odlicza od 0 do 255 na magistrali UART co sekundę. 

Na samym początku musimy zainicjować magistralę.

UART uart; // Tworzymy obiekt magistrali
uart.begin(uart0, 115200); // Inicjujemy magistralę uart0.

W celu wysyłania danych używamy metody uart.write(<dane>) dla tekstu oraz uart_write_int(<liczba>), uart_write_uint(<liczba>) oraz uart_write_double(<liczba>). Wybór metody zależy od typu - float i double to ostatnia metoda. Pozostałe względem nazwy naszego typu - czy nazwa zaczyna się od uint czy od int. 

Wszystkie funkcje biblioteki są wymienione w pliku README.md.

#include <cstdio>
#include "pico/stdlib.h"
#include "UART.h"

int main() {
   stdio_init_all();
  
   // Inicjacja UART z prędkością transmisji 115200 bit/s
   UART uart;
   uart.begin(uart0, 115200);

   for (uint16_t i = 0; i < 256; i++) {
       // Wyślij bajt danych
       uart.write_uint(i);
       uart.write(" ");
   }

}

Wgrywamy go na Pi Pico.

RealTerm

Uruchamiamy program RealTerm - jego okienko będzie wyglądać następująco:

realterm_n1kZGZ9zOw.thumb.png.4535146c7b153a42c8be3c636224a8b3.png

Po lewej wybieramy format wyświetlania danych (wymieniam najczęściej używane):

ASCII - znaki plus symbole specjalne (np. CR, LF)

ANSI - wyłącznie czytelne przez ludzi znaki zgodne z tabelą ASCII

HEX (Space) - wartości hexadecymalne (00 - FF) rozdzielone spacją

Tablica ASCII

800px-ASCII-Table-wide_svg.thumb.png.baa7a875faffa55287df513cc0bf7ae8.png

Na aktualne potrzeby zastosujemy ANSI po czym klikniemy zakładkę Port.

realterm_h5Kb46nJTU.thumb.png.e8c944894da176a4f669515f4f826b6c.png

Jak już pewnie widzisz w zakładce Port musimy ustawić Baud na 115200 oraz wybrać port komunikacyjny. Jeżeli jeszcze tego nie zrobiłeś / zrobiłaś podłącz konwerter do USB. Wtedy możesz kliknąć dwa razy na listę rozwijaną w zakładce Port, by zaktualizować listę i szukasz wartości liczbowej. Następnie odznaczasz Open i klikasz ponownie. 

Uwaga: czasem konwerter się rozłącza i trzeba podłączyć go ponownie odznaczając Open i zaznaczając ponownie  

Po prawidłowym otworzeniu portu, który jest podłączony do Pico (i nikt nie pomylił przewodów) powinien pokazać się taki piękny widok: 

realterm_wpceHjfa7n.thumb.png.36dbc9de8da4417b2930f7f29958ffb8.png

Oznacza on, że wszystko jest poprawnie i dane są przesyłane z Pico na komputer  

W drugą stronę

Teraz powinniśmy przesłać dane z komputera na Pico. To jest równie proste, aczkolwiek można to zrobić na kilka sposobów. My po prostu będziemy czekali aż coś prześle dane w nieskończonej pętli. Nasz prosty program będzie odpowiadał na zapytania wysłane z komputera - będzie zwracał bajt podniesiony do kwadratu poprzez UART.

Na początku musimy poprosić użytkownika o podanie liczby z zakresu 0-255, potem odczytać tę liczbę na Pi Pico, podnieść ją do kwadratu oraz zwrócić w czytelnej formie użytkownikowi.

To co? Spróbujesz sam(a)? Biblioteka UART.h zawiera parę przydatnych funkcji 😉

read(); // odczytuje jeden bajt
parse_int(); // odczytuje liczbę całkowitą wpisaną tekstem
parse_uint(); // odczytuje liczbę całkowitą bez znaku wpisaną tekstem

Niestety na moment pisania artykułu biblioteka nie zawiera narzędzi do odczytu liczb zmiennoprzecinkowych. Jeżeli Ci nie wychodzi oto przykład: 

#include <cstdio>
#include "pico/stdlib.h"
#include "UART.h"

int main() {
   stdio_init_all();
   UART uart;
   uart.begin(uart0, 115200); // Inicjacja UART

   // Lokalna zmienna liczbowa
   uint64_t wynik = 0;
  
   // Nieskończona pętla ;)
   while(true){
       uart.write("Podaj liczbe: \r\n\0"); // Zadaj użytkownikowi pytanie ;)
     
       // Czekaj na liczbę
       while(uart.available() < 1) { // Poczekaj na dane ;)
           sleep_ms(100);
       }

       wynik = uart.parse_int(); // odczytaj podaną przez użytkownika liczbę
       wynik *= wynik; // wynik^2
       uart.write_uint(wynik); // Wyślij liczbę na UART
       uart.write("\r\n"); // Nowa linia
   }

}

Do przesyłania danych w RealTerm służy zakładka... Tak Send! Dwie pierwsze linijki służą do przesyłania danych tekstowych, ta wąska obok przycisku 0 do przesyłania danych binarnych.

image.thumb.png.35d1fa118db7b169b607550c8120cda6.png

Dobrze to już raczej potrafisz korzystać z magistrali UART? 😉

W tym rozdziale to byłoby na tyle

Wiesz już jak komunikować się po jednym z podstawowych protokołów - następne omówimy później 😉

Zadania domowe

  1. Stwórz kalkulator obsługiwany poprzez magistralę UART
    Użytkownik podaje 1 liczbę, potem znak operacji, a na sam koniec drugą liczbę. Znak w języku C++ zapisujemy jako symbol w '. np.
     
char znak = '+';

Zamiast słowa "char" można zastosować znany nam typ uint8_t.

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.