Jak odczytać dane szeregowe z oscyloskopu

21

Mam mikrokontroler (PICAXE 20X2) i miernik puli. Zaprogramowałem micro tak, aby wysyłać dowolną zmianę miernika puli do portu szeregowego komputera. Oczywiście jest to 8-bitowy ADC. Teraz interesującą rzeczą jest dla mnie możliwość dekodowania tych danych szeregowych na oscyloskopie.

Oto dwa zdjęcia, pierwsze to kiedy mikro wysyła „0” do komputera, a następne to „255”. Dane są przesyłane przy użyciu 9600 buad i mogę je odbierać na terminalu PC.

Pierwsze zdjęcie wprowadź opis zdjęcia tutaj

Drugie zdjęcie wprowadź opis zdjęcia tutaj

Moje pytanie brzmi: czy przechwyciłem odpowiednie dane w moim zakresie, a po drugie, jak można odczytać i zdekodować te impulsy do formatu szesnastkowego lub ascii. Mam na myśli, jak odczytać te rosnące i opadające impulsy (0/1).

Dzięki.

Sean87
źródło
3
linie szeregowe są bezczynne w logicznym stanie „1”, więc pamiętaj, że masz 1 na dole i 0 na górze tutaj. Wiem, że ludzie już się na to skupili. Mój komentarz ma na celu wskazanie przyszłych zakresów danych seryjnych; możesz sondować rzeczy, aby stan bezczynności był wysoki.
JustJeff

Odpowiedzi:

14

Po pierwsze coś, co zauważył Olin: poziomy są odwrotnością tego, co zwykle produkuje mikrokontroler:

wprowadź opis zdjęcia tutaj

Nie ma się czym martwić, przekonamy się, że możemy to również przeczytać w ten sposób. Musimy tylko pamiętać, że w zakresie bit startowy będzie 1a bit stop 0.

μμμ1μ0

0x001μ
0xFFμ

szacuje:

0b11001111 = 0xCF
0b11110010 = 0xF2

0b11001101 = 0xCD
0b11001010 = 0xCA
0b11001010 = 0xCA
0b11110010 = 0xF2

edytuj
Olin ma absolutną rację, to coś w stylu ASCII. W rzeczywistości jest to 1 uzupełnienie ASCII.

0xCF ~ 0x30 = „0”
0xCE ~ 0x31 = „1”
0xCD ~ 0x32 = „2”
0xCC ~ 0x33 = „3”
0xCB ~ 0x34 = „4”
0xCA ~ 0x35 = „5”

0xF2 ~ 0x0D = [CR]

Potwierdza to, że moja interpretacja zrzutów ekranu jest poprawna.


edytuj 2 (jak interpretuję dane, na popularne żądanie :-))
Ostrzeżenie: to długa historia, ponieważ jest to zapis tego, co dzieje się w mojej głowie, gdy próbuję dekodować coś takiego. Przeczytaj go tylko, jeśli chcesz nauczyć się jednego sposobu na jego rozwiązanie.

Przykład: drugi bajt na pierwszym zrzucie ekranu, zaczynając od 2 wąskich impulsów. Zaczynam od drugiego bajtu celowo, ponieważ jest więcej krawędzi niż w pierwszym bajcie, więc łatwiej będzie go poprawnie ustawić. Każdy z wąskich impulsów ma około 1/10 części podziału, więc każdy może mieć 1 bit wysokości, a pomiędzy nimi niski bit. Nie widzę też nic węższego niż to, więc myślę, że to tylko kawałek. To jest nasza referencja.
Następnie, po 101dłuższym okresie na niskim poziomie. Wygląda na około dwa razy szerszy niż poprzednie, więc może być 00. Wysokie podążanie, które znów jest dwa razy szersze, tak będzie 1111. Mamy teraz 9 bitów: bit początkowy ( 1) plus 8 bitów danych. Więc następny bit będzie bitem stopu, ale ponieważ jest0 nie jest od razu widoczny. Więc mamy to wszystko razem1010011110 , w tym bit startu i stopu. Gdyby bit stopu nie wynosiłby zero, zrobiłbym gdzieś złe przypuszczenie!
Pamiętaj, że UART najpierw wysyła LSB (najmniej znaczący bit), więc będziemy musieli odwrócić 8 bitów danych: 11110010= 0xF2.

Znamy teraz szerokość pojedynczego bitu, podwójnego bitu i 4-bitowej sekwencji i przyjrzeliśmy się pierwszemu bajtowi. Pierwszy wysoki okres (szeroki impuls) jest nieco szerszy niż 1111w drugim bajcie, więc będzie miał szerokość 5 bitów. Okres niski i wysoki po nim są tak szerokie jak podwójny bit w drugim bajcie, więc otrzymujemy 111110011. Znowu 9 bitów, więc następny powinien być bitem niskim, bitem stopu. Zgadza się, więc jeśli nasza ocena trafności jest poprawna, możemy ponownie odwrócić bity danych: 11001111= 0xCF.

Potem dostaliśmy wskazówkę od Olin. Pierwsza komunikacja ma 2 bajty długości, 2 bajty mniej niż druga. A „0” jest także o 2 bajty krótsze niż „255”. Prawdopodobnie jest to coś w rodzaju ASCII, choć nie do końca. Zauważam również, że drugi i trzeci bajt „255” są takie same. Świetnie, to będzie podwójne „5”. Mamy się dobrze! (Musisz od czasu do czasu się zachęcić.) Po zdekodowaniu „0”, „2” i „5” zauważam, że istnieje różnica 2 między kodami dla pierwszych dwóch, a różnica 3 między ostatnimi dwa. I wreszcie zauważam, że 0xC_jest to uzupełnienie 0x3_, które jest wzorem cyfr w ASCII.

stevenvh
źródło
Dzięki za wskazówki, postaram się uchwycić odpowiedni przebieg i zaktualizować moje pytanie.
Sean87
Dzięki, czy mógłbyś oznaczyć zdjęcie jako sposób wyszukiwania tych danych?
Sean87
1
@ Sean87 - To długa historia, dodałem ją do mojej odpowiedzi. To ilustruje mój sposób robienia tego, inni mogą podążać różnymi ścieżkami. Nie martw się, jeśli uważasz, że nie zobaczyłbyś połowy tego; większość to tylko doświadczenie i wyobraźnia. Nie ma w tym żadnej specjalnej inteligencji.
stevenvh
Bardzo fajne odpowiedzi i pytania, ale zastanawiam się, dlaczego powiedziałeś, że Oscyloskop pokazuje odwrotność tego, co faktycznie jest. Wiem, że linia biegu jałowego jest prawie zawsze wysoka, ale czy oscyloskop nie powinien uchwycić dokładnego obrazu rzeczywistości? Z wyjątkiem sytuacji, gdy użytkownik zmienił parametr ustawień oscyloskopu.
Nikos
7

Coś się nie sumuje. Twoje sygnały wydają się być 3.3V od szczytu do szczytu, co oznacza, że ​​są prosto z mikro. Jednak poziomy UART mikrokontrolera są (prawie) zawsze bezczynne, wysokie i aktywne niskie. Twoje sygnały są odwrócone od tego, co nie ma sensu.

Aby ostatecznie przenieść te dane do komputera, należy je przekonwertować na poziomy RS-232. Tego właśnie oczekuje port COM komputera. RS-232 jest w stanie bezczynności niskim i aktywnym wysokim, ale niski jest poniżej -5 V, a wysoki powyżej + 5 V. Na szczęście istnieją układy scalone, które ułatwiają konwersję między typowymi sygnałami UART poziomu logiki mikrokontrolera a RS-232. Te układy zawierają pompy ładujące, które wytwarzają napięcia RS-232 z zasilacza 3,3 V. Czasami te układy są ogólnie nazywane „MAX232”, ponieważ był to numer części wczesnego i popularnego układu tego typu. Potrzebujesz innego wariantu, ponieważ najwyraźniej używasz zasilania 3,3 V, a nie 5 V. Wykonujemy produkt, który jest w zasadzie jednym z tych układów na płycie ze złączami. Wejdź na http://www.embedinc.com/products/rslink2 i spójrz na schemat, aby zobaczyć jeden przykład, jak podłączyć taki układ.

Kolejną rzeczą, która się nie sumuje, jest to, że obie sekwencje wydają się mieć więcej niż jeden bajt, nawet jeśli mówisz, że wysyłasz tylko 0 i 255. Ten typ danych szeregowych jest wysyłany z bitem początkowym, a następnie 8 bitami danych, potem bit stopu. Bit startowy ma zawsze przeciwną biegunowość niż poziom biegu jałowego linii. W większości opisów poziom bezczynności linii jest określany jako „spacja”, a przeciwnie jako „znak”. Tak więc bit startowy jest zawsze na znak. Celem bitu początkowego jest zapewnienie synchronizacji czasu dla pozostałych bitów. Ponieważ obie strony wiedzą, ile to trochę czasu, jedynym pytaniem jest, kiedy zaczyna się bajt. Bit startowy zapewnia tę informację. Odbiornik zasadniczo uruchamia zegar na zboczu początkowym bitu startowego i używa go, aby wiedzieć, kiedy nadejdą bity danych.

Bity danych są wysyłane co najmniej do najbardziej znaczącej kolejności, przy czym znak wynosi 1, a spacja wynosi 0. Dodaje się bit stopu na poziomie przestrzeni, dzięki czemu początek następnego bitu początkowego jest nową krawędzią i pozostawia trochę czasu między bajtami. Pozwala to na mały błąd między nadawcą a odbiorcą. Jeśli odbiornik byłby choć trochę wolniejszy od nadawcy, w przeciwnym razie przegapiłby początek następnego bitu startowego. Odbiornik resetuje się i uruchamia swój zegar od nowa za każdym nowym bitem początkowym, aby błędy synchronizacji nie kumulowały się.

Z tego wszystkiego powinieneś zobaczyć, że pierwszy ślad wydaje się wysyłać co najmniej dwa bajty, a ostatni wygląda na może 5.

Pomoże to, jeśli rozszerzysz skalę czasową śladów. W ten sposób możesz zmierzyć, czym naprawdę jest trochę czasu. Pozwoliłoby to zweryfikować, czy naprawdę masz 9600 bodów (104 µs / bit), i umożliwić dekodowanie poszczególnych bitów przechwytywania. W tej chwili nie ma wystarczającej rozdzielczości, aby zobaczyć, gdzie są bity, i dlatego faktycznie dekoduje to, co jest wysyłane.

Dodany:

Właśnie przyszło mi do głowy, że twój system może wysyłać dane w formacie ASCII zamiast binarnym. Tak się zwykle nie dzieje, ponieważ konwersja do ASCII w małym systemie zajmuje więcej ograniczonych zasobów, słabo zużywa przepustowość i konwersję na PC można łatwo wykonać, jeśli chcesz wyświetlić dane użytkownikowi. Jeśli jednak Twoje transmisje są znakami ASCII, które wyjaśniłyby, dlaczego sekwencje mają więcej niż jeden bajt, dlaczego drugi jest dłuższy („255” to więcej znaków niż „0”) i dlaczego oba wydają się kończyć tym samym bajtem. Ostatni bajt jest prawdopodobnie rodzajem znaku końca linii, który zwykle byłby znakiem powrotu karetki lub znakiem nowej linii.

W każdym razie rozszerz skalę czasową, a my możemy dokładnie zdekodować, co jest wysyłane.

Olin Lathrop
źródło
1
Bit stopu (i przeciwny do bitu startu) wymusza również zbocze na początku nowej transmisji.
stevenvh
@steven: Tak, zdałem sobie sprawę, że zrezygnowałem z tego po ponownym przeczytaniu mojej odpowiedzi i dodałem ją w edycji, prawdopodobnie w tym samym czasie, kiedy pisałeś swój komentarz.
Olin Lathrop
4
Chociaż wysyłanie ASCII jest „nieefektywne”, nadal może być bardzo dobrym wyborem. Większość moich systemów wbudowanych nie tylko wysyła ASCII, ale także odbiera polecenia ASCII, co umożliwia ręczne eksperymentowanie poprzez „rozmowę” z nimi z poziomu programu terminalowego. Standard SCPI (rodzaj ulepszenia GPIB, rozszerzony na inne interfejsy elektryczne) jest bardzo formalną metodą, która działa w tym kierunku.
Chris Stratton
4
Zamiar zdecydowanie nie zgadzam. Ascii pobiera tak niewielką ilość kodu, nawet uruchamiając goły metal na trochę 8-gorzkim. Jasne, możesz napisać własny program, ale co się stanie za 10 lat, gdy zostanie utracony i uruchomienie maszyny wirtualnej zajęłoby nawet, gdyby można go było znaleźć? I oczywiście, każdy programista wart swojej soli może zhakować terminal binarny, aby coś inżynierii wstecznej. Jednak interfejsy czytelne dla ludzi są warte niewielkiego obciążenia w większości, ale w najbardziej poważnych systemach z ograniczoną pamięcią i wydajnością. Dodatkowo, jeśli masz pamięć, możesz osadzić wyjście debugowania za pomocą włączania / wyłączania.
Chris Stratton,
2
Powinienem wspomnieć, że zacząłem korzystać z interfejsów ASCII, ponieważ było to wymaganiem klienta ... ale zachowałem je ze względu na ich przydatność. Mógłbym dodać pomysł jako polecenie w oprogramowaniu układowym, a następnie przetestować go w dowolnym miejscu w obiekcie. Bez konieczności wdrażania aktualizacji na kliencie konfiguracji za każdym razem, gdy publikowałem eksperymentalną wersję oprogramowania układowego z dodatkami umożliwiającymi sprawdzenie problemu, który miał ktoś w skomplikowanym systemie, którego był tylko jeden moduł. Na telefonie z klientem mogę pozwolić im odpalić terminal i przeprowadzić ich przez nieopublikowane funkcje testów fabrycznych.
Chris Stratton
1

Musisz znać wszystkie szczegóły: prędkość, jeśli jest bit startu, liczbę bitów danych, jeśli jest bit stopu i jeśli jest bit parzystości. Powinno to być funkcją konfiguracji UART w mikrokontrolerze.

Jeśli zakres Rigola nie ma opcji szeregowego dekodowania (wiele DSO ma), możesz użyć kursorów X, aby wspomóc dekodowanie. Umieść pierwszy kursor na wiodącej krawędzi danych i przesuń drugi kursor przez strumień bitów. Różnicy między kursorami można użyć do określenia, który „bit” obecnie najeżdżasz myszą za pomocą prostej arytmetyki. Oczywiście zignoruj ​​bity start / stop / parzystość.

Adam Lawrence
źródło
Zawsze jest bit startowy i zawsze przynajmniej jeden bit stopowy. Mogą istnieć dodatkowe bity stopu, ale są one nie do odróżnienia od martwego czasu między bajtami. Stare mechaniczne dekodery czasami wymagały dwóch bitów stopu, aby dać czas na zresetowanie mechanizmu. Obecnie prawie zawsze jest 8 bitów danych i brak bitu parzystości, ale jak mówisz, mogą się one różnić.
Olin Lathrop