W odniesieniu do Arduino Uno, Mega2560, Leonardo i podobnych płyt:
- Jak działa komunikacja szeregowa?
- Jak szybki jest serial?
- Jak połączyć się między nadawcą a odbiorcą?
Uwaga: jest to pytanie referencyjne.
serial
c++
hardware
softwareserial
Nick Gammon
źródło
źródło
Odpowiedzi:
Asynchroniczna komunikacja szeregowa (zwykle nazywana szeregową) służy do wysyłania bajtów z jednego urządzenia do drugiego. Urządzeniem może być jedno lub więcej z poniższych:
Częstotliwość zegara i próbkowanie danych
W przeciwieństwie do komunikacji szeregowej SPI / USB / I2C nie ma sygnału zegarowego. Zegar próbkowania to uzgodniona częstotliwość próbkowania (znana jako prędkość transmisji). Zarówno nadawca, jak i odbiorca muszą być skonfigurowani do korzystania z tej samej prędkości, inaczej odbiornik otrzyma bez znaczenia dane (z powodu bitów, które nie są próbkowane z tą samą szybkością, z jaką zostały wysłane).
Transmisja jest asynchroniczna, co w zasadzie oznacza, że bajty mogą być wysyłane w dowolnym momencie, ze zmiennymi przerwami między nimi. Ta grafika ilustruje wysłanie jednego bajtu:
Powyższa grafika pokazuje przesyłaną literę „F”. W ASCII jest to 0x46 (szesnastkowo) lub 0b01000110 (binarnie). Najmniej znaczący (low-order) bit jest przesyłany pierwszy, a więc w powyższy graficzny widać bity przybywających w kolejności:
01100010
.Czas „bezczynności” między bajtami jest przesyłany jako ciągłe bity „1” (w efekcie linia transmisyjna jest utrzymywana na wysokim poziomie w sposób ciągły).
Aby wskazać początek bajtu, bit startowy jest zawsze wskazywany przez pociągnięcie linii w dół, jak pokazano na grafice. Gdy odbiornik zobaczy bit startowy, czeka 1,5 razy czas próbkowania, a następnie próbkuje bity danych. Czeka 1,5 razy, aby:
Jeśli na przykład szybkość transmisji wynosi 9600 bodów, wówczas częstotliwość próbkowania będzie wynosić
1/9600 = 0.00010416
sekundy (104,16 µs).Zatem przy 9600 bodów po odebraniu bitu początkowego odbiornik czeka na 156,25 µs, a następnie próbki co 104,16 µs.
Celem Stop Bit jest upewnienie się, że zdecydowanie jest jeden bit między każdym bajtem. Bez bitu stop, jeśli bajt zakończyłby się na zero, sprzęt nie byłby w stanie stwierdzić różnicy między tym a bitem początkowym następnego bajtu.
Aby wygenerować powyższe dane wyjściowe na urządzeniu Uno, możesz napisać ten kod:
Liczba bitów danych
Aby zaoszczędzić czas transmisji (w dawnych czasach, heh) pozwolono ci określić inną liczbę bitów danych. Sprzęt AtMega obsługuje numerację bitów danych od 5 do 9. Oczywiście im mniej bitów danych, tym mniej informacji można wysłać, ale tym szybciej to będzie.
Bity parzystości
Opcjonalnie możesz mieć bit parzystości. Jest to obliczane, jeśli jest to wymagane, przez zliczenie liczby 1 w znaku, a następnie upewnienie się, że liczba ta jest nieparzysta lub nawet przez ustawienie bitu parzystości na 0 lub 1 zgodnie z wymaganiami.
Na przykład dla litery „F” (lub 0x46 lub 0b01000110) widać, że są tam 3 (w 01000110). Zatem mamy już nieparzystą parzystość. Zatem bit parzystości byłby następujący:
Bit parzystości, jeśli jest obecny, pojawia się po ostatnim bicie danych, ale przed bitem stopu.
Jeśli odbiornik nie otrzyma poprawnego bitu parzystości, jest to nazywane „błędem parzystości”. Wskazuje, że jest jakiś problem. Być może nadawca i odbiornik są skonfigurowani do korzystania z różnych prędkości transmisji (bitów) lub na linii wystąpił szum, który zmienił zero na jeden lub odwrotnie.
Niektóre wczesne systemy stosowały również parzystość „znacznik” (gdzie bit parzystości zawsze wynosił 1 niezależnie od danych) lub parzystość „przestrzeń” (gdzie bit parzystości zawsze wynosił 0, niezależnie od danych).
9-bitowa transmisja
Niektóre urządzenia komunikacyjne wykorzystują dane 9-bitowe, więc w takich przypadkach bit parzystości jest zamieniany na 9-bit. Istnieją specjalne techniki wysyłania tego 9-go bitu (rejestry to 8-bitowe rejestry, więc 9-ty bit należy umieścić gdzie indziej).
Liczba bitów stopu
Wczesne wyposażenie działało elektronicznie nieco wolniej, więc aby dać odbiorcy czas na przetworzenie przychodzącego bajtu, czasami określano, że nadawca wyśle dwa bity stopu. Zasadniczo wydłuża to czas, w którym linia danych jest utrzymywana wysoko (jeszcze jeden bit), zanim pojawi się następny bit startowy. Ten dodatkowy czas bitowy daje odbiornikowi czas na przetworzenie ostatniego przychodzącego bajtu.
Jeśli odbiornik nie otrzyma logicznego 1, gdy ma być bit stopu, jest to nazywane „błędem ramkowania”. Wskazuje, że jest jakiś problem. Całkiem możliwe, że nadawca i odbiorca są skonfigurowani do używania różnych prędkości transmisji (bitów).
Notacja
Zazwyczaj komunikacja szeregowa jest wskazywana przez podanie prędkości, liczby bitów danych, rodzaju parzystości i liczby bitów stopu, jak poniżej:
To mówi nam:
Ważne jest, aby nadawca i odbiorca zgodzili się na powyższe postanowienia, w przeciwnym razie komunikacja prawdopodobnie się nie powiedzie.
Pin-out
Arduino Uno ma cyfrowe styki 0 i 1 dostępne dla szeregowego sprzętu:
Aby połączyć dwa Arduinos, zamień Tx i Rx w następujący sposób:
Prędkość
Obsługiwany jest szeroki zakres prędkości (patrz rysunek poniżej). „Standardowe” prędkości są zwykle wielokrotnością 300 bodów (np. 300/600/1200/2400 itp.).
Inne „niestandardowe” prędkości mogą być obsługiwane przez ustawienie odpowiednich rejestrów. Klasa HardwareSerial robi to za Ciebie. na przykład.
Jako ogólną zasadę, zakładając, że używasz danych 8-bitowych, możesz oszacować liczbę bajtów, którą możesz przesłać na sekundę, dzieląc szybkość transmisji przez 10 (z powodu bitu początkowego i bitu zatrzymania).
Zatem przy prędkości 9600 bodów można przesyłać 960 bajtów (
9600 / 10 = 960
) na sekundę.Błędy prędkości transmisji
Szybkość transmisji w Atmega jest generowana przez podzielenie zegara systemowego, a następnie zliczanie do z góry ustalonej liczby. Ta tabela z arkusza danych pokazuje wartości rejestru i wartości procentowe błędów dla zegara 16 MHz (takiego jak ten na Arduino Uno).
Bit U2Xn wpływa na dzielnik częstotliwości taktowania (0 = dzielenie przez 16, 1 = dzielenie przez 8). Rejestr UBRRn zawiera liczbę, do której zlicza procesor.
Tak więc z powyższej tabeli widzimy, że otrzymujemy 9600 bodów z zegara 16 MHz w następujący sposób:
Dzielimy przez 104, a nie 103, ponieważ licznik jest względem zera. Zatem błąd
15 / 9600 = 0.0016
jest bliski temu, co mówi powyższa tabela (0,02%).Zauważysz, że niektóre prędkości transmisji mają wyższy błąd niż inne.
Zgodnie z arkuszem danych maksymalny procent błędu dla 8 bitów danych mieści się w zakresie od 1,5% do 2,0% (więcej informacji znajduje się w arkuszu danych).
Arduino Leonardo
Arduino Leonardo i Micro mają inne podejście do komunikacji szeregowej, ponieważ łączą się bezpośrednio przez USB z komputerem hosta, a nie przez port szeregowy.
Z tego powodu musisz poczekać, aż Serial stanie się „gotowy” (ponieważ oprogramowanie ustanawia połączenie USB), z dodatkowymi kilkoma liniami, jak poniżej:
Jeśli jednak chcesz komunikować się za pomocą pinów D0 i D1 (zamiast kabla USB), musisz użyć Serial1 zamiast Serial. Robisz to tak:
Poziomy napięcia
Zauważ, że Arduino używa poziomów TTL do komunikacji szeregowej. Oznacza to, że oczekuje:
Starsze urządzenia szeregowe zaprojektowane do podłączenia do portu szeregowego komputera prawdopodobnie wykorzystują poziomy napięcia RS232, a mianowicie:
Jest to nie tylko „odwrócone” w odniesieniu do poziomów TTL („jeden” jest bardziej ujemny niż „zero”), ale Arduino nie jest w stanie wytrzymać ujemnych napięć na swoich pinach wejściowych (ani dodatnich powyżej 5 V).
Dlatego potrzebujesz obwodu interfejsu do komunikacji z takimi urządzeniami. Tylko dla wejścia (do Arduino) wystarczy prosty tranzystor, dioda i kilka oporników:
W przypadku komunikacji dwukierunkowej musisz być w stanie generować ujemne napięcia, więc wymagany jest bardziej złożony obwód. Na przykład układ MAX232 zrobi to w połączeniu z czterema kondensatorami 1 µF, które będą działać jako obwody pompy ładującej.
Oprogramowanie szeregowe
Istnieje biblioteka o nazwie SoftwareSerial, która umożliwia szeregową komunikację (do pewnego stopnia) w oprogramowaniu, a nie w sprzęcie. Ma to tę zaletę, że można używać różnych konfiguracji pinów do komunikacji szeregowej. Wadą jest to, że wykonywanie szeregowe w oprogramowaniu wymaga więcej procesora i jest bardziej podatne na błędy. Aby uzyskać więcej informacji, patrz Serial oprogramowania .
Mega2560
Arduino „Mega” ma 3 dodatkowe sprzętowe porty szeregowe. Są one oznaczone na planszy jako Tx1 / Rx1, Tx2 / Rx2, Tx3 / Rx3. Jeśli to możliwe, należy ich używać zamiast SoftwareSerial. Aby otworzyć te inne porty, użyj nazw Serial1, Serial2, Serial3, takich jak:
Przerwania
Zarówno wysyłanie, jak i odbieranie, przy użyciu biblioteki HardwareSerial, wykorzystuje przerwania.
Wysyłanie
Gdy to zrobisz
Serial.print
, dane, które próbujesz wydrukować, są umieszczane w wewnętrznym buforze „przesyłania”. Jeśli masz 1024 bajty lub więcej pamięci RAM (na przykład Uno), otrzymujesz bufor 64-bajtowy, w przeciwnym razie otrzymujesz bufor 16-bajtowy. Jeśli w buforze jest miejsce, toSerial.print
natychmiast wraca, nie opóźniając twojego kodu. Jeśli nie ma miejsca, „blokuje” ono oczekiwanie na wystarczające opróżnienie bufora, aby było miejsce.Następnie, ponieważ każdy bajt jest przesyłany przez sprzęt, wywoływane jest przerwanie (przerwanie „USART, Data Register Empty”), a procedura przerwania wysyła następny bajt z bufora z portu szeregowego.
Odbieranie
Gdy odbierane są dane przychodzące, wywoływana jest procedura przerwania (przerwanie „USART Rx Complete”), a przychodzący bajt jest umieszczany w buforze „odbierającym” (o takim samym rozmiarze jak wspomniany powyżej bufor nadawczy).
Kiedy zadzwonisz
Serial.available
, dowiesz się, ile bajtów jest dostępnych w tym buforze „odbierającym”. Po wywołaniuSerial.read
bajt jest usuwany z bufora odbiorczego i zwracany do kodu.W Arduinos z 1000 bajtami lub więcej pamięci RAM nie ma pośpiechu, aby usunąć dane z bufora odbiorczego, pod warunkiem, że nie pozwolisz się zapełnić. Jeśli się zapełni, kolejne dane przychodzące są odrzucane.
Zauważ, że ze względu na rozmiar tego bufora nie ma sensu czekać na bardzo dużą liczbę bajtów, na przykład:
To nigdy nie zadziała, ponieważ bufor nie może pomieścić tak dużo.
Porady
Przed czytaniem zawsze upewnij się, że dane są dostępne. Na przykład jest to źle:
Serial.available
Testu gwarantuje tylko masz jeden bajt dostępny, jednak kod próbuje odczytać dwa. Może działać, jeśli w buforze są dwa bajty, jeśli nie, otrzymasz -1, które po wydrukowaniu będą wyglądały jak „ÿ”.Pamiętaj, ile czasu zajmuje przesłanie danych. Jak wspomniano powyżej, przy prędkości 9600 bodów przesyłasz tylko 960 bajtów na sekundę, więc próba wysłania 1000 odczytów z portu analogowego przy prędkości 9600 bodów nie zakończy się sukcesem.
Bibliografia
źródło