Wykrywanie bitu początkowego w oprogramowaniu UART

9

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?

Dan Laks
źródło
Dobre pytanie. Czy Twoje urządzenie zewnętrzne stale wysyła znaki? Jeśli nie, powinieneś sprawdzić, czy bit startowy i bit stop są wyrównane. A jeśli dane pomiędzy nimi pasują do twojego czeku (suma / bit)?
Paul
Czy możesz poprosić zewnętrzny strumień UART o przesłanie preambuły? Podobnie jak strumień specjalnych danych wskazujący, że nadchodzi strumień, który różni się od bitu początkowego? Gdybyś mógł to zrobić, byłbyś w stanie stwierdzić, czy dane są błędne, gdybyś włączył się w trakcie transmisji, czy nie.
Funkyguy,
1
Jeśli strumień szeregowy nie zawiera dostatecznie długiego okresu bezczynności - prawdopodobnie nie będzie można z niego zrestartować. Częściowe rozwiązanie może nastąpić w przypadku, gdy bit „stop” nie zostanie wyświetlony w oczekiwanym miejscu. Wtedy możesz zresetować stan i spróbować ponownie.
Eugene Sh.
1
Nie potrzebujesz specjalnej preambuły ... tylko od czasu do czasu odpoczynku dłuższego niż jedna postać (włączając start, stop bit). Lub 10+ bitów stop z rzędu, co jest tym samym.
Brian Drummond
2
@Fuaze, urządzenie zewnętrzne wysyła długi strumień znaków w sposób ciągły, ale czasami nie pracuje. W najgorszym przypadku mogę po prostu zignorować dane wejściowe, aż do pierwszego użycia na biegu jałowym.
Dan Laks

Odpowiedzi:

5

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.

Dr. Funk
źródło
Świetny pomysł na łączenie klatek ORAZ do momentu, gdy bit startu i stopu przetrwa. To będzie zbyt duże obciążenie dla mojej konkretnej aplikacji, ale jednak sprytne.
Dan Laks
Jeśli urządzenie zewnętrzne jest czymś, nad czym OP nie ma kontroli (co stwierdził we wcześniejszym komentarzu do pytania), jest mało prawdopodobne, że będzie w stanie zmienić długość bitu stopu.
tcrosley,
Ten komentarz nie został opublikowany, kiedy zacząłem pisać tę odpowiedź. Jednak pozostałe trzy opcje, które wymieniłem, nadal obowiązują w przypadku, gdy długość bitu stopu jest stała.
Dr Funk
3

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.

Dave Tweed
źródło
1

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).

KalleMP
źródło