Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

ATmega128 - Timer - tajemniczy odczyt

trynitor 04 Paź 2016 11:50 870 6
  • #1 04 Paź 2016 11:50
    trynitor
    Poziom 3  

    Cześć,

    Napisałem program, który uruchamia 16-bitowy Timer (TCNT1 w ATmedze 128). W moim programie Timer zlicza przez 128ms (dolicza w tym czasie do wartości 1000). Następnie wyświetla młodszy i starszy bajt Timera na wyświetlaczu alfanumerycznym (odpowiednio wartości dziesiętne 232 oraz 3). Do tej pory wszystko działa, ale gdy chcę wysłać odczyt każdego z bajtów Timera na port szeregowy, muszę najpierw wysłać młodszy bajt, a następnie starszy. Gdy wysyłałem najpierw starszy bajt, na porcie szeregowym w jego miejsce pojawiała się liczba 0 (zamiast liczby 3). Bajt młodszy przesyła się prawidłowo bez znaczenia czy wysyłam go w pierwszej kolejności czy w drugiej.
    Oto kody:
    1) Wersja z niepoprawną transmisją szeregową starszego bajtu (dochodzi liczba 0, zamiast liczby 3), młodszy bajt w porządku:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Starszy bajt ma poprawną wartość tylko wtedy kiedy w funkcji 'send_rs' napiszę tak (młdoszy ciagle jest poprawny):
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nurtuje mnie pytanie dlaczego kolejność wysłania bajtów na port szeregowy ma znaczenie? Dlaczego w pierwszym przypadku na porcie szeregowym pojawia się zerowa wartość starszego bajtu zamiast wartości trzy.
    Nadmieniam, że druga wersja funkcji 'send_rs' pozwala na bezbłędną transmisję danych.

    0 6
  • #2 04 Paź 2016 12:03
    JacekCz
    Poziom 36  

    Mam wrażenie nie odróżniasz bajtu od znaku (może nie rozumiem, źle mi się czyta). Wprawdzie na AVR to ma 8bit i tamto też, ale koncepcyjnie są różne, inaczej sie obługuje.
    Ciąg bajtów to nie jest ciąg znaków, wysłanie wartości znakowej bajtu to nie wysłanie bajtu, itd... nie jestem również pewien Twojej oceny sytuacji.
    Obrazowo znak (lub zmienną złożoną w postaci znakowej) się drukuje (print()), bajt się wysyła (dajmy na to send() )

    Na marginesie języki które od początku mocno wychowywały bajt!=znak fajnie to w głowach porządkują. Ja po poznaniu Javy czy C# innymi oczami patrzę na C/C++.

    0
  • #3 04 Paź 2016 12:28
    trynitor
    Poziom 3  

    Poprawcie mnie jeśli się mylę, ale przecież char to po prostu typ zmiennej 8-bitowej. Nie ma różnicy co prześlę w ramach tych 8 bitów. Lecą sobie zera i jedynki i chodzi tylko o to, żeby programista wiedział jak je później zinterpretować. Innymi słowy czy paczka 8-bitów (typu znakowego 'char') to część jakiejś liczby, którą później programista złoży w inny typ, czy znak w kodzie ASCII, który wyświetli na jakimś ekranie.
    Char to po prostu typ zmiennej jednobajtowej. Czy schowam tam znak w kodzie ASCII, czy połowę shortinta (tak jak w moim przypadku) dla maszyny nie robi różnicy. Ważne, żebym później wiedział jak to razem poskładać.

    0
  • Pomocny post
    #4 04 Paź 2016 12:34
    krzysiek_krm
    Poziom 34  

    Witam,
    słabo znam te procesory, musisz więc sprawdzić w dokumentacji, moim zdaniem problem nie bierze się z kolejności wysyłania ale z kolejności odczytu.

    Generalnie, ośmiobitowe procesory przy dostępie (odczycie i zapisie) do szesnastobitowych timerów wykorzystują (dla zagwarantowania jednoczesności obu bajtów) specyficzny mechanizm. Starszy bajt nie jest natywnym rejestrem timera ale rejestrem buforowym, którego odczyt lub zapis jest wyzwalany odpowiednio odczytem lub zapisem młodszego bajtu, który jest natywnym rejestrem timera.

    Jeżeli czytasz najpierw starszy bajt to jest to odczyt rejestru buforowego a nie fizycznego rejestru timera. Odczytanie najpierw młodszego bajtu powoduje skopiowanie rejestru timera do bufora i odczyt jest prawidłowy.

    Tak czy owak, trzeba sprawdzić w dokumentacji procesora.

    Pozdrawiam

    0
  • Pomocny post
    #5 04 Paź 2016 12:53
    simon71
    Poziom 19  

    Krzysiek_krm ma rację.
    Fragment z dokumentacji ATmega128:
    "For a 16-bit read, the low byte must be read before the high byte."

    0
  • Pomocny post
    #6 04 Paź 2016 13:03
    JacekCz
    Poziom 36  

    trynitor napisał:
    Poprawcie mnie jeśli się mylę, ale przecież char to po prostu typ zmiennej 8-bitowej. Nie ma różnicy co prześlę w ramach tych 8 bitów. Lecą sobie zera i jedynki i chodzi tylko o to, żeby programista wiedział jak je później zinterpretować. Innymi słowy czy paczka 8-bitów (typu znakowego 'char') to część jakiejś liczby, którą później programista złoży w inny typ, czy znak w kodzie ASCII, który wyświetli na jakimś ekranie.
    Char to po prostu typ zmiennej jednobajtowej. Czy schowam tam znak w kodzie ASCII, czy połowę shortinta (tak jak w moim przypadku) dla maszyny nie robi różnicy. Ważne, żebym później wiedział jak to razem poskładać.


    Nie zda się żadnemu z tych zdań pojedynczo zaprzeczyć.

    Rzecz w tym, że programista też człowiek, i może się pomylić, zapomnieć itd ... nawet w odniesieniu do pojedynczych bajtów.

    A już "paczka" .... hoho to długa opowieść ... paczka znaków zakończona '\0' to tzw C-string (w tym używanie funkcji nastawionych na C-string, co jest obecne w Twoim kodzie) , a "paczka bajtów" to coś zupełnie innego, wysyłanie paczki bajtów interfejsem znakowym to 'gwarantowane ryzyko' błędu.

    Ja w tym punkcie, gdzie jestem uważam za ZBAWIENNE każde API które to odróżnia (można by, ale to nie temat wątku, przytoczyć dziesiątki opowieści z "dużej" informatyki) . Choć w C/8bit może to mieć tylko charakter 'miękki' tzn prośby a nie przymusu. Np (proponuję) print -> znaki, send -> bajty

    filozofowie mówią, ze jak używasz nieprawidłowego (nieprecyzyjnego) języka, to zaczniesz robić tak jak mówić.

    EDIT: popieram to o kolejności odczytu rejestru, tym niemniej kod nie jest klarowny.

    0
  • #7 04 Paź 2016 14:06
    trynitor
    Poziom 3  

    Co do kodu to w 100% zgadzam się, że klarowny nie jest. Stąd temat założony w dziale "dla początkujących". Staram się jak mogę, ale liczę że klarowność kodu przyjdzie z czasem.

    Co do tematu - dziękuję za rozwianie wątpliwości. Problem uważam za rozwiązany.

    0