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

Mega8 RS232 dzwne $baud = 34800

Roko 30 Lis 2008 00:22 1557 11
  • #1 5799357
    Roko
    Poziom 11  
    Cześć wszystkim.
    Napisałem parę miesięcy temu programik w BASCOM do urządzenia, które ma możliwość odczytu pamięci EEPROM i wysłania jej zawartości przez RS232 do PC.
    Urządzonko wróciło do mnie niedawno ze względu na pojawiające się nieraz błędy podczas transmisji. Program używa tylko instrukcji PRINT i nie używa przerwań. Przerwania globalne wyłączone. Ze względu na wykorzystanie wszystkich portów musiałem zrezygnować z rezonatora kwarcowego i ATMega8 ustawiona jest na wewnętrzny oscylator 8MHz.
    W pierwszej wersji prędkość transmisji miałem ustawioną na 9600 bodów (0.16%) odchyłki według Bascom'a i postanowiłem zmienić prędkość na 38400.
    Po poprawce układ ładnie wysyłał dane do PC i temat by się zakończył gdyby nie znaleziony prze zemnie błąd, a mianowicie zamiast 38400 wpisałem $Baud = 34800 jak to w życiu bywa. Po zmianie na wartość prawidłową $Baud = 38400 znowu zdarzają się nieprawidłowości w transmisji i tyczy się to wszystkich standardowych ustawień 1200,2400,4800 itd.
    W związku z powyższym mam pytania?

    1. Czy odchyłka (0.16%) to dużo, wydaje się że nie.
    2. Czy wartość 34800 to fuks przy, której to dobrze chodzi.
    3. Jak ta wartość się ma do wzoru zamieszczonego w pomocy Bascom.
    4. Jak prawidłowo wyliczyć wartość $Baund dla oscylatora wewnętrznego 8MHz dla UART'a.

    Załączam kawałek kodu gdzie te dane są wysyłane.



    
    Print "DB"
    Waitms 10
    For B = 0 To 63
       Readeeprom Wart , B
       Print Wart
      Waitms 10
    Next
    

    Może ktoś z kolegów eksperymentował z transmisją przy nietypowej częstotliwości zegara np. 8MHz ?.
    Za wszelkie podpowiedzi będę bardzo wdzięczny.
    Roko.
  • Pomocny post
    #3 5799391
    lelekx
    Poziom 30  
    Jeżeli użyłbyś rezonatora lub generatora o stałej i znanej częstotliwości to nie byłoby problemu. Niestety generator RC wbudowany w M8 nie charakteryzuje się zbyt dużą stabilnością. Używanie UARTa przy niepewnym sygnale zegarowym to błąd.
  • #4 5799464
    Roko
    Poziom 11  
    Cześć.
    Dzięki za szybką reakcję.
    Piwko dla mirekk36 sory zapomniałem i to jest to.
    Co do stabilności wewnętrznego oscylatora to bym polemozował i według mnie jast bardzo stabilny. No czywiście, że kwarc to wyznacznik.
    Oscylator wewnętrzny jest lekko niestabilny przy wachaniu i oscylacjach napięcia zasilającego proc.
    Panowie czy można tę wartość $Baund podawać dowolną czy też kompilator i tak wybierze wartość swoją przybliżoną. Ja jak piasałem
    ustawiłem $Baund = 34800 przez pomyłkę i jest ok z tą wartością. Nie wiem co o tym sądzić.
    Dzięki
    Roko

    Dodano po 34 [minuty]:

    Sory, że post pod postem.
    Trochę za dużo euforii z mojej strony z tym trafieniem w kalibrację oscylatora.
    Przejrzałem dokumentację i w niej podają, żeby kalibrować wtedy, gdy są problemy z FLASH'em lub EEPROM'em. U mnie tego nie ma. Pamięć EEPROM zapisuje i odczytuje bez problemu. Kalibracja może pomoże, ale przypomina to dłubanie w drewnie i można napaskudzić o czym przestrzega dokumentacja.
    Jeżeli nic nie znajdę więcej o $Baud to zostawię taki fajans $Baud=34800 chociaż jestem dociekliwy i tak szybko nie rezygnuję.
    Roko
  • #5 5799505
    lelekx
    Poziom 30  
    Jeżeli koniecznie chcesz zostać przy wbudowanym RC to polecam częstościomierz lub oscyloskop. Za pomocą wbudowanego timera generujesz przebieg prostokątny np. 1/1024 fOsc na jednym z wyjść MCU i mierzysz częstotliwość.
    Masz wówczas dwa wyjścia:
    - skorygować wartość rejestru OSCCAL tak, aby częstotliwość fOsc była równa 8MHz (lub dowolną inną, np. 7,37MHz, optymalną dla UART) i wpisać na początku programu zapis korekty do tego rejestru
    - wpisać wartość XTAL w programie odpowiadającą faktycznej częstotliwości

    Generator RC waha się nie tylko od zmian napięcia - temperatura i starzenie się również wpływa na zmiany częstotliwości.
  • #6 5799531
    Roko
    Poziom 11  
    Cześć.
    Widzę, że jesteś też nocny marek jak ja.
    Ok. Wszystko co napisałeś jest prawdą ale. I właśnie, jeżeli oscylator jest tak niestabilny to po co zmieniać jego częstotliwość. Nawet jeżeli będzie 7.3728MHz to i tak będzie latać w lewo i prawo chyba, że będzie się łapać w zakresie zjadliwym dla UART'a. Z doświadczenia wiem, że odchyłka do 2% i więcej procent od częstotliwości przydzielonej na transmisję nie ma znaczenia. Przy oscylatorze wew. 8MHz jest to około 0.16% pod warunkiem, że ta częstotliwość oscylatora stoi jak drut, ale w przypadku jak lata to już lipa.
    Gdyby był to poważniejszy projekt to można by się tym przejąć. To urządzonko to taki rejestrator w postaci 5 tabel o 8x5 pól na wyświetlaczu graficznym 128x64 do wprowadzania statystyk podczas meczy koszykówki. Nieraz mają jednego dnia do 4 meczy, a urządzenia są dwa dla dwu drużyn. Jest to liga amatorska, a urządzonka są takim społecznym wkładem.
    Muszę się bliżej przyjrzeć rejastrom UART'a, a szszególnie UBRR to tam właśnie wpisany jest podział zegara. Nie wiem tylko czy Bascom tego nie pozmienia przy wywołaniu Print.
    Na razie.
    Dzięki za pomoc i za zainteresowanie.
    P.s.
    Gdybym miał 1 wolny pin to bym doczepił zewnętrzy generator, ale niestety wszystkie są wykorzystane. Myślałem o przeniesieniu przycisków sterujących menu na linie sterujące wyświetlacza, ale obawiam się, że procedura przerwania i inne zajmą trochę więcej niż 300B, a tyle tylko zostało.
  • Pomocny post
    #7 5799551
    lelekx
    Poziom 30  
    Cały problem jest spowodowany tym, że procesor w tej chwili nie jest taktowany 8MHz - w tym przypadku to tak na oko 7,2MHz. Zmiany tej częstotliwości będą raczej niewielkie, w granicach zakładanej tolerancji, jeżeli MCU będzie pracować przy stabilizowanym zasilaniu i przy niewielkich zmianach temperatury.
    Znajomość obecnego taktowania pomoże rozwiązać Twój problem. Jak to zrobić napisałem we wcześniejszym poście.
    Nie musisz grzebać w UBRR - wartość wpisywana do tego rejestru jest obliczana na podstawie $crystal i $baud. Zmieniając jedną z tych dwóch stałych wpływasz bezpośrednio na dzielnik w USART. $crystal wpływa również na obliczenie opóźnienia m. in. w poleceniach "wait" i "waitms".

    Dodano po 6 [minuty]:

    A co do nocnego marka - o tej porze zwykle zaczynam pracę :)
  • #8 5799561
    Roko
    Poziom 11  
    Hej.
    No właśnie fajnie się coś robi o tej porze bo jest cisza i nikt głowy nie zawraca. Ja również nie będę ci zawracał.
    Wszystko co napisałeś to święta racja. Znalazłem trochę o tym wewnętrznym oscylatorze. Żeby było śmieszniej to częstotliwość pracy oscylatora różni się w zależności od roku i serii produkcyjnej i jest to około 8MHz. Jeżeli chodzi o 1MHz to Atmel twierdzi, że są kalibrowane podczas produkcji. Znalazłem starszy temat na forum i 'mirekk33' podaje jak w prosty sposób można skalibrować oscylator. Ta wartość 34800, którą wpisałem przez pomyłkę to poprostu wartość bliższa od 38400 dla zadeklarowanej wartości oscylatora 8MHz. No ale ty to wiesz. Trochę później bo może o 10.00 przekalibruję na próbę i dam znać.
    Bez względu na efekt masz u mnie punkty za cierpliwość.
    Jeszcze raz dzięki dla mirekk33 i lelekx.
    Muszę się kimnąć . Cześć.
    Roko
  • #9 5799782
    mirekk36
    Poziom 42  
    jeszcze raz przypomnę jak można sobie skalibrować ładnie RS232:

    Do
      Osccal = Osccal + 1
      Print "Poprawny tekst w terminalu??? " ; Osccal
      Waitms 300
    Loop


    to kawałek kodu w Bascomie ale chyba widać jak można to sprawdzić w dowolnym innym języku.

    Tak się dziwię troszkę temu, że gdzieś doczytałeś się iż kalibracji dokonuje się tylko gdy są jakieś problemy z zapisem do eeprom itp.

    Kalibrowanie wewn oscylatora ze względu na uzyskanie jak najmnijeszczego błędu przy transmisjach RS232 jest jak najbardziej celowe i wskazane. Jak gdzieś kiedyś opisywałem na elektrodzie, w moim przypadku prawie zawsze gdy biorę ATmega16 to na wewn oscylatorze 8MHz nigdy nie idzie mi RS232 przy prędkości 9600 bez uprzedniej kalibracji. A na ATmega8 prawie nigdy nie muszę kalibrować.

    Wspomniałeś o czynnikach wpływających na niestabilną pracę oscylatora wewn. wymieniając wachania napięcia zasilającego procek. Z tym, że one aż tak bardzo nie wpływają na zbyt duże odchyłki, które potrafiłyby przeszkodzić w transmisji RS232. W przeciwieństwie do do wachań napięcia gorsza jest temperatura o której nie wspomniałeś. Tutaj poprzez zmiany temperatury wachania oscylatora mogą być na tyel duże (gdy układ skalibrowany był np w temperaturze powiedzmy pokojowej) a warunki jego pracy to np temperatura otoczenia 30st i wyżej. Wtedy oscylator pomimo skalibrowania może tak się rozjechać że będą nici.

    Jednak jak praktyka wskazuje, rzadko tak się zdarza i te różnice temperatur muszą być dość znaczne - a wątpię aby w twoim i wielu tego typu przypadkach tak było.

    Napisałeś że zabawą z własną kalibracją można sobie narozrabiać i ostrzegają przed tym w jkimś tam PDFie. Oczywiście, można narozrabiać ale tylko wtedy gdy się nie wie do czego jest bajt kalibracyjny oraz "z czym to się je" . Świadomy użytkownik nie namiesza nic sobie.Powiem nawet więcej - jak wspomniałeś może się zdarzyć, że wewn oscylator przychodzący z fabryki jest np ciut źle skalibrowany (jeśli chodzi o działanie RS232) Wtedy kalibrując go pod kątem działania RS232 doprowadzasz go na pewno do wartości bliższej ideału 8MHz (o ile tak miałeś ustawiony fuskami) i całość może się okazać bardzo skuteczną operacją także dla innych układów procesora. Bo przynajmniej masz jakiś punkt odniesienia - prędkość RS232 - i nie musisz używać nawet jakiegoś częstościomierza itp

    takie jest moje zdanie - a kalibracja - gdy jest potrzeba to chleb codzienny ;) .... aczkolwiek gdy stosuję wewn oscylator 8MHz to też nigdy nie nastawiam się na wyższe prędkości niż 9600 bo ta przy skalibrowaniu bywa najbardziej pewna i stabilna. Przy wyższych może być już różnie bo wtedy i wachania mają większy wpływ na błędy. Tak więc - przyjmuję zasadę, że jeśli wystarczy mi prędkość 9600 to z zamkniętymi oczami pozostaję w większosci wypadków przy oscylatorze wewnętrznym, ale jeśli potrzebuję wyższych prędkości to też nie bawię się w pośrednie tylko korzystam z najwyższej popularnej jak 115200 ale wtedy zawsze projektuję układ z kwarcem lubianym przez RS232 np 11.592.000 Hz lub podobnym. Jak na przyszłość tak będziesz podchodził na etapie projektowania to unikniesz rozczarowań wynikających bądź z niestabilnej transmisji przy różnych prędkościach bądź z braku pinów później do podłączenia kwarca.
  • #10 5800648
    Roko
    Poziom 11  
    Cześć.
    Dzięki mirekk36.
    Znalazłem tą wartość środkową Osccal i wyszła u mnie 182 według twojego przykładu zamieszczonego przy innym temacie na forum.
    Co do pdf'a może źle coś doczytałem, ale jest tam mowa o EEPROM i FLASH.
    Zrobiłem ciekawe doświadczenie odnośnie temperatury, a mianowicie nagrzałem M8 do około 100 stopni i ku mojemu zdziwieniu zakres prawidłowej wartości Osccal przesunął się nieznacznie o dwie wartości 176-198 czyli bezpiecznie jest wartość środkową lekko przesunąć w górę o 2-3 wartośći.
    Z RS232 nigdy nie miałem problemu bo stosowałem kwarc 11.0592 tylko w tym przypadku wyszło co wyszło czyli lekka lipka.
    Po ustawieniu Osccal = 182 wszystko jest ok przy prędkości 38400 bodów.
    Podsumowując kalibracja jest celowa i niezbędna gdy mamy wewnętrzny oscylator, a temperatura ma niewielkie znaczenie. Zasilania nie trenowałem.
    Zamieszczam przykładzik na podstawie, którego to skalibrowałem.
    
    '*************************************************
    '*********** calibracja dla ustawienia ***********
    '********* wartości środkowej oscylatora *********
    '************ wewnętrznego wg.przykładu **********
    '************                           **********
    '******************* mirekk36 ********************
    '*************************************************
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 38400
    
    'Osccal = 182   wartość środkowa dla zakresu 174-191 dla mojego przypadku
    'domyślna - 189 dla innej M8 może się różnić.Można kalibrować podając wartość
    'środkową dla wszystkich $baud 1200,2400,4800 itd.
    
    Print "Osccal = " ; Osccal                                  ' wartość domyślna
    Waitms 10
    
    Do
    Osccal = Osccal + 1
    Print "ok - " ; Osccal
    Waitms 100
    Loop
    
    End
    

    Jeszcze raz wielkie dzięki dla was za pomoc.
    Myślę że można zamknąć.
    Roko.
  • #11 5800716
    klops_mops
    Poziom 17  
    Sam możesz zamknąć temat, klikając taką ikonę kłódki obok przycisku "odpowiedz" ;)
  • #12 5800880
    Roko
    Poziom 11  
    To akurat sie wie.
    Pozdrawiam i zamykam.
REKLAMA