logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

AT90PWM3 - Rs-232: Nieprawidłowe dane przy transmisji 38400 Baud, 8MHz oscylator

Emot 30 Sie 2013 23:36 2625 15
  • #1 12686824
    Emot
    Poziom 10  
    Witam,
    chce dorobić do swojego procesora komunikacje po RS-232. Można powiedzieć że udało mi się to w 90%. Transmisja działa, aczkolwiek nie dostaje tego czego mógłbym oczekiwać.
    Skonfigurowałem rejestry:UCSRB i UCSRC. Procesor taktuje wewnętrznym oscylatorem 8MHz ( defaultowe ustawienie fusebitów, sprawdziłem je ), Baud Rate ustawiłem na 38400 ( wpisałem odpowiednią wartość do UBRRH = 0 i UBRRL = 12), ramkę danych ustawiłem w UCSRC na 8 bit danych ,1 bit stopu , bez parzystości. Odblokowałem przerwania globalne jak i te od UARTU. Korzystam ze standardowych funkcji ATMELA
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a mimo to otrzymuje na wyjściu głupoty... Wysyłając np znak 'a' powinienem otrzymać
    Cytat:
    Dec 97 Hex 61 AscII a
    , a otrzymuje
    Cytat:
    Dec 39 0 Hex 27 00 AscII '

    Zauważyłem że przy próbie wykonania poniższego kodu
    [code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    program przyjmuje daną i wysyła odpowiedź, ale za drugim razem tak jakby zawiesza się ( nie przyjmuje nowego znaku ) i wysyła znak który dostał za pierwszym razem. Czy ktoś mógłby nakierować mnie w której części mogłem popełnić błąd ? Mogłem coś pomieszać w obsłudze przerwań ? Byłbym wdzięczny za pomoc.
    Pozdrawiam
  • Pomocny post
    #2 12687230
    BlueDraco
    Specjalista - Mikrokontrolery
    Jaka jest częstotliwość zegara procesora?
    Przelicz rzeczywistą szybkość transmisji i zapewne będziesz miał wyjaśnienie Twojego problemu.

    Poza tym albo pomyliłeś coś wklejając kod, albo masz funkcje Transmit i Receive zadeklarowane wewnątrz innej funkcji o tej nazwie Transmit, co zapewne nie było Twoją intencją.

    Z kolei ten "kod":

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Nie ma prawa się skompilować ani wykonać. Jeśli oczekujesz pomocy, wklej kod, który rzeczywiście skompilowałeś i próbowałeś uruchomić. Zwracaj też uwagę na komunikaty kompilatora. Dobry zwyczaj - to doprowadzenie kodu do takiej postaci, przy której kompilator nie emituje żadnych ostrzeżeń.
  • #3 12688783
    krru
    Poziom 33  
    Po co odblokowałeś przerwania, skoro działasz na pętlach oczekiwania?
    Jeśli używasz wewnętrznego generatorka to mniejsza prędkość będzie pewniejsza.
  • #4 12688883
    Emot
    Poziom 10  
    Dzięki wielkie za zainteresowanie :) Faktycznie popełniłem błąd podczas wklejania, prawidłowy kod znajduje się poniżej. W celach testowych w main została tylko część kodu odpowiadająca komunikacji.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Cytat:
    Jaka jest częstotliwość zegara procesora?
    Przelicz rzeczywistą szybkość transmisji i zapewne będziesz miał wyjaśnienie Twojego problemu.

    Częstotliwość zegara jest ustawiona na 8 MHz, wartości fusebitów znalazłem w programie mkAVR Calculator i kombinowałem z następującymi ustawieniami. Od razu dodam iż używam wewnętrznego sygnału taktującego według danych poniżej. ( używam ostatnią opcje )
    Cytat:
    FUSEBITY "LOW = C2, HIGH = DF, EXTENDED =F9"-> Int. RC Osc. 8MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 0 ms; [CKSEL = 0010 SUT = 00 ]
    FUSEBITY "LOW = D2, HIGH = DF, EXTENDED =F9"-> Int. RC Osc. 8MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 4,1 ms; [CKSEL = 0010 SUT = 01 ]
    FUSEBITY "LOW = E2, HIGH = DF, EXTENDED =F9"-> Int. RC Osc. 8MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 65 ms; [CKSEL = 0010 SUT = 01 ]


    Jeżeli chodzi o prędkość transmisji i o rzeczywistą prędkość transmisji to znalazłem takie wzory
    Cytat:
    (fOSC/(16 · BAUD)) − 1 = Wartosc UBRR
    Rzeczywista szybkość transmisji wynosi
    fOSC/(16(UBRR + 1)) = rzeczywista predkosc transmisji

    Baudrate ustawiłem na 38400 , czyli wartość jaką wpisuje do rejestru to 12, a rzeczywista prędkość wynosi według wzoru 38461. Niestety ustawiłem taką prędkość na odbiorniku i nic nie pomogło ;/ Nadal dostaje zły znak. Czy aby na pewno w prawidłowy sposób ustawiam baudrate w UBRRH i UBRRH oraz bity w rejestrze UCRSC ?
    Na koniec dodam jeszcze, że do komunikacji używam programu Terminal v1.9b oraz konwertera usb<->rs232 ( sprawdzony, działa z innym urządzeniem). Co ciekawe program Terminal zwraca mi komunikat "FRAME ERROR" a mam go ustawionego na "8N1" bez jakiegokolwiek handshakingu, ale profilaktycznie zlutowałem odpowiednie nóżki z gniazda DB9 (lecz to w niczym niepomogło). Tylko gdzie popełniłem błąd przy definiowaniu ramki ? Bo ja go niestety nie widzę...
    Pozdrawiam i z góry dzięki za jakiekolwiek sugestie.
  • Pomocny post
    #5 12688909
    krru
    Poziom 33  
    FRAME ERROR to błąd podczas bitów startu i stopu - najczęsciej transmisja znaku nie zakończyła się (albo zaczęła się następna) w odpowiednim momencie i gdy odbiornik oczekuje bitu stopu (H) dostaje L.
    Jeśli wysyłacz pojedynczy znak to ta druga możliwość (transmisja następnego znaku) nie wchodzi w grę.
    Może spróbuj na krótszych słowach (np. 5-6 bitów) - wtedy jest mniejsza wrażliwość na nierówne zegary.
  • Pomocny post
    #6 12689191
    Konto nie istnieje
    Poziom 1  
  • #7 12690112
    Emot
    Poziom 10  
    Faktycznie kod wklejony na forum miał błąd, ale wcześniej ustawiałem Baudrate przez funkcje. Niemniej jednak poprawiłem to i ... dalej nic. Dokładnie ta sama sytuacja. Pobawiłem się i zmieniłem liczbę bitów danych od 5 do 8. Bawiłem się z parzystością i z bitami stopu. Efekty były takie że czasami dostawałem totalne głupoty, czasami to co normalnie ( czyli dla znaku 'a' wartość 79 ) , a czasami w ogóle nic. Ten procesor może pracować z zewnętrznym zegarem PLL 16 MHz, zmieniłem ustawienie fusebitów i obliczyłem na nowo wartość rejestru BDRR i co ? Dokładnie ta sama sytuacja ( 'a' = 79 )... Macie może jakiś inny pomysł ? Zewnętrzny oscylator mógłby faktycznie pomóc ?
  • #8 12690650
    Konto nie istnieje
    Poziom 1  
  • #9 12690952
    BlueDraco
    Specjalista - Mikrokontrolery
    Zamiast marudzić - pokaż schemat i prawdziwy kod po ostatnich poprawkach. Zdecyduj się w końcu na jakąś częstotliwość zegara - proponuję 8 MHz. Sprawdź ustawienia bitów konfiguracji do tej częstotliwości. Uruchom przerwanie timera, żeby naocznie zweryfikować częstotliwość (np. migaj diodą co sekundę).
  • #10 12691384
    tmf
    VIP Zasłużony dla elektroda
    Podstawowy błąd to taktowanie USART z wewnętrznego generatora. On nie ma wystarczającej stabilności i transmisja po RS jeśli działa to tylko przypadkiem. Zmień na kwarc i problemy znikną.
  • #11 12692813
    Emot
    Poziom 10  
    Dodałem rzutowanie i zmieniłem przsunięcie z 16 na 8 bitów ( chociaż i tak w obu przypadkach powinno być tam wpisywane 0 ). Procesor taktuje nadal wewnętrznym zegarem 8MHz. Baudrate zmniejszyłem do 9600. Poniżej najnowszy kod
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    , a tutaj widok terminala + schemat ideowy.
    AT90PWM3 - Rs-232: Nieprawidłowe dane przy transmisji 38400 Baud, 8MHz oscylator

    Dokładniejszą rozpiskę nóżek można znaleźć tutaj ATAVRMC100 datasheet Jak widać jest to gotowa płytka, a co gorsza nóżka XTAL2 jest na stałe podpięta pod VCC. Gdyby nie to już dawno podpiął bym zewnętrzny oscylator ( nawet w celach testowych ). Jak sądzicie warto spróbować wylutować tą diodę i podpiąć tam zewnętrzny rezonator ? Jeżeli chodzi o Timera i miganie diodą co 1s to postaram się to zrobić jak najszybciej i podzielę się wnioskami. Obawiam się tylko że ludzkie oko może nie być w stanie zaobserwować różnica błędu na poziomie us ;). Z góry dzięki za zainteresowanie.
    Pozdrawiam
  • #12 12692825
    tmf
    VIP Zasłużony dla elektroda
    Wystaw na pin przebieg z timera i zmierz jego szerokość/częstotliwość. Z odchyłki możesz wyliczyć czy mieścisz się w błędzie UART. Wewnętrzny RC można kalibrować, warto spróbować. Stabilność w funkcji napięcia i temperatury ciągle będzie podła, ale jakośtam w stałych warunkach to zadziała.
  • Pomocny post
    #13 12692848
    Konto nie istnieje
    Poziom 1  
  • #14 12692896
    Emot
    Poziom 10  
    Marek_Skalski napisał:
    Powiedz mi, bo chyba się mylę. Podłączyłeś pin TxD procka bezpośrednio do pinu RxD we wtyczce konwertera RS232/USB???

    Tak właśnie zrobiłem, tzn. pin TxD procka idzie na goldpina, a tego podłączyłem do pinu RxD we wtyczce konwertera RS232/USB. Wydaje mi się że koniecznym jest zrobienie krosu na liniach TxD, RxD. Czyżbym był w błędzie ?
  • Pomocny post
    #15 12692930
    Konto nie istnieje
    Poziom 1  
  • #16 12693202
    Emot
    Poziom 10  
    Faktycznie masz racje, wprowadził mnie w błąd opis podłączenia znaleziony w przykładzie z Atmela... Zrobie sobie konwerter z użyciem Max 232 i dam znać co wyszło. Ehh głupi błąd ale tak to jest jak człowiek skupia się tylko na tym żeby nie zrobić błędu w oprogramowaniu. Dzięki wielkie za pomoc. Odezwę się jak uda się coś uskutecznić.
    Pozdrawiam
REKLAMA