Eksperymentuję z pisaniem oprogramowania UART na moim mikrokontrolerze za pomocą pinów GPIO. Ma to na celu tymczasowe dodanie kanału UART do projektu, dopóki nie zostanie wdrożony nowy projekt korzystający z interfejsu użytkownika z większą liczbą portów UART.
Problemem jest prawidłowe wykrywanie bitu początkowego w strumieniu szeregowym. Źródło strumienia jest zewnętrzne i nie ma znaczenia, kiedy moje urządzenie się uruchomi. Jest więc bardzo prawdopodobne, że moje urządzenie włączy się i zacznie widzieć bity danych w środku transmisji bajtów. Niewątpliwie spowoduje to, że moje oprogramowanie UART odczyta błędne wartości, ponieważ nie będzie w stanie odróżnić bitu początkowego od jakiegokolwiek innego przejścia od wysokiej do niskiej.
Czy to nieunikniony problem z kanałem UART? A może jest jakiś sprytny trik, którego producenci używają w swoich sprzętowych UART?
Odpowiedzi:
Jeśli użyjesz długości bitu stopu, którą można łatwo odróżnić od reszty strumienia danych, na przykład 1,5-bitowego czasu, powinno być łatwo rozpocząć odbieranie w połowie transmisji. Jednak wiąże się to ze zwiększonym kosztem ogólnym. Łączna dostępna przepustowość danych spadnie wraz ze wzrostem długości bitu stop.
Jeśli nie używasz tak często magistrali i często masz przerwy między ramkami, może to być tylko kwestia oczekiwania na wystąpienie jednej z tych przerw, a następnie wybranie pierwszej transmisji hi-lo na początku następny bit startowy.
Należy pamiętać, że liczba bitów danych powinna być przewidywalna, podobnie jak rozmiar ramki, więc nawet jeśli używasz 100% pojemności magistrali, a bit stopu to jeden bit, nadal możesz znaleźć bit startowy, jeśli zbierzesz wystarczającą liczbę ramek. Każda ramka ma gwarantowane przejście hi-lo. Bit stopu jest tym, który zawsze jest wysoki. Bit startowy to ten, który zawsze jest niski. Zakładając, że Twoje dane są losowe (lub wystarczająco losowe), możesz zrobić coś tak prostego, jak utworzenie bufora wielkości ramki, ustawić każdy bit w nim, a następnie nadal gromadzić ramki i ORAZ je umieszczać w tym buforze, aż bufor będzie miał tylko 1 zestaw bitów. To jest twój bit stopu. Ten po nim jest bitem początkowym. Voila! Znalazłeś to.
Jeśli używasz bitu parzystości, inną opcją byłoby pobranie danych o wartości dwóch ramek, wybranie pierwszego bitu niskiego jako bitu początkowego, a następnie obliczenie sumy kontrolnej i porównanie z bitem parzystości. Jeśli pasuje, to prawdopodobnie znalazłeś bit startowy. Jeśli nie, wybierz następny niski bit i powtarzaj, aż otrzymasz dobrą sumę kontrolną. Jeśli nie możesz znaleźć bitu w dwóch ramkach danych, który jest sprawdzany jako poprawny bit początkowy, oznacza to, że dane zostały uszkodzone i musisz pobrać jeszcze dwie ramki.
źródło
Sprzętowe UART mają ten sam problem. Ale i tak zazwyczaj rozwiązuje się w krótkim czasie. Na końcu każdej ramki sprawdź bit stopu, a jeśli nie jest on wysoki, odrzuć ramkę i poczekaj na następne przejście z wysokiej do niskiej wartości. Zakładając, że dane ze źródła nie są całkowicie patologiczne (np. Długie łańcuchy „UUUU” lub ASCII 0x55), UART ostatecznie „przejdzie” do prawdziwego bitu startowego.
źródło
Zakładając transmisję 8N1.
Musisz poczekać na ciąg 9 wysokich lub niskich bitów z rzędu.
Jeśli wysoki, będzie to oznaczać albo bezczynną przerwę w danych, albo znak 0xFF i bit STOP,
albo
jeśli niski, bit START i znak NULL 0x00.
Każdy z tych warunków pozwoli na resynchronizację.
Aby przyspieszyć: jeśli znasz pewne znaki, które nie są możliwe w danych, możesz kilkakrotnie parsować przychodzące dane (po fakcie) dla każdego bitu i jeśli otrzymasz serię 7 znaków, które są nonsensowne (wysoki zestaw bitów, niższy wielkość liter, kody sterujące, znaki interpunkcyjne itp.), po których następuje poprawny znak, możesz być całkiem pewny, że jesteś ponownie zsynchronizowany.
Podobne problemy będą występować, gdy użyjesz wbudowanego urządzenia peryferyjnego UART i nie będziesz w stanie wykonać bitowej oceny, a także będziesz musiał pamiętać o resetowaniu wszystkich bitów błędów ramkowania i tak dalej, gdy tylko wystąpią (szczególnie po włączeniu).
źródło