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

[MEGA8][C] Błędy w transmisji PC<->AVR przez RS232

16 Wrz 2010 20:19 3454 16
  • Poziom 12  
    Witam

    Program jaki w zasadzie skopiowałem z katalogu atmegi8:
    Code:


    void USART_Init( unsigned int baud )
    {
    /* Set baud rate */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    /* Enable Receiver and Transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }

    void USART_Transmit( unsigned char data )
    {
    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) )
    ;
    /* Put data into buffer, sends the data */
    UDR = data;
    }

    unsigned char USART_Receive( void )
    {
    /* Wait for data to be received */
    while ( !(UCSRA & (1<<RXC)) )
    ;
    /* Get and return received data from buffer */
    return UDR;
    }

    int main()
    {
    DDRB = 0xFF;
    DDRD = 0xFF;
    lcd_init();
    USART_Init(600);

    //unsigned char wynik[1];

    while(1)
    {
       USART_Transmit(USART_Receive());
    }
    }



    Jedynie przy transmisji 300bps literki wciskane na klawiaturze jako tako pokrywają się z tymi wyświetlonymi w hyperterminalu win xp. Inne prędkości to krzaki albo przypadkowe litery. uC pracuje na wewnętrznym oscylatorze 8MHz. Jeśli zewrę linie nadajnika i odbiornika na wyjściu z MAX232 wszystko się zgadza więc coś sam uC miesza tylko nie wiem co.... W ustawieniach portu ustawiam prędkość taką jaka jest w inicjalizacji UARTa, bity danych: 8, sterowanie przepływem: brak.

    Z góry dzięki za pomoc.
  • Poziom 38  
    Podłącz kwarc, najlepiej do współpracy z uartem np 11,0592MHz
  • Poziom 12  
    Jeśli Ci chodzi o to, że trzeba podłączyć zewnętrzny kwarc żeby nie było błędów to to nie pomaga. Dałem kwarc 16MHz i jest nawet gorzej... Ale takiego kwarcu jaki Ty piszesz nie mam, kupię jutro i sprawdzę jaki jest efekt.
  • Poziom 38  
    poza tym to 600 to odrobinkę za dużo.
  • Poziom 17  
    Code:
    UBRRH=0;
    
    UBRRL=51;

    Użyj takiego wprowadzenia do tych rejestrów. to są wartości dla 9600 przy taktowaniu 8MHz. A jeśli używasz innego kwarcu, to w nocie masz tabelkę z wartościami jakie należy załadować do tych rejestrów dla danego kwarcu.
  • Poziom 12  
    Dawid_20 napisał:
    Code:
    UBRRH=0;
    
    UBRRL=51;

    Użyj takiego wprowadzenia do tych rejestrów. to są wartości dla 9600 przy taktowaniu 8MHz. A jeśli używasz innego kwarcu, to w nocie masz tabelkę z wartościami jakie należy załadować do tych rejestrów dla danego kwarcu.


    To co napisałeś działa idealnie. Widziałem te tabelki i wydawało mi się, że takie wprowadzanie prędkości transmisji jakie jest w funkcji inicjalizującej w katalogu jest ok. Czyli przez przekazanie do funkcji prędkości. Ale widać nie, ciekawe czemu...

    To w takim razie mam jeszcze jedno pytanie odnośnie wpisywania wartości do tych dwóch rejestrów. Jeśli w tabelce jest napisana wartość UBRR = 416 to rozdzielając tą liczbę na dwa rejestry będzie tak:
    UBRRH = 0x01;
    UBRRL = 0xA0;
  • Poziom 17  
    Cytat:
    To w takim razie mam jeszcze jedno pytanie odnośnie wpisywania wartości do tych dwóch rejestrów. Jeśli w tabelce jest napisana wartość UBRR = 416 to rozdzielając tą liczbę na dwa rejestry będzie tak:
    UBRRH = 0x01;
    UBRRL = 0xA0;

    Dokładnie tak, w Win7 kalkulatorek to prawdziwe liczydło :)
  • Poziom 42  
    maciek_nh napisał:

    To w takim razie mam jeszcze jedno pytanie odnośnie wpisywania wartości do tych dwóch rejestrów. Jeśli w tabelce jest napisana wartość UBRR = 416 to rozdzielając tą liczbę na dwa rejestry będzie tak:
    UBRRH = 0x01;
    UBRRL = 0xA0;


    Panie kochany toż kod masz napisany poprawnie a w miejsca baud musisz podać odpowiednią wartość z tabeli i zapewniam cię, że nic a nic nie musisz przeliczać sobie na kalkulatorze oraz ręcznie wpisywać w ten sposób wartości do tych rejestrów. To niestety powrót do czasów króla ćwieczka.

    Nie chciałbyś wygodnie posługiwać się po prostu prędkością w bodach ??? np zdefiniować sobie 9600 albo 19200 albo 38400 ??? no a od czego masz preprocesor kochanieńki ;) ?

    Code:

    #define UART_BAUD 9600
    //#define UART_BAUD 19200
    //#define UART_BAUD 38400

    #define __UBRR (F_CPU/16/UART_BAUD-1)


    Odkomentowujesz sobie odpowiednią linijkę albo ustawiasz ją na stałe, a później :

    Code:
    USART_Init( __UBRR );


    i przeanalizuj sobie jak to działa, zrozum a nie tylko żeby tego używać na zasadzie "copy&paste"

    I nie słuchaj bajek tadzika85 o tym, że do transmisji UART dla takich prędkości jak 9600, 19200 czy nawet 38400 trzeba zaraz kwarca podłączać i to jeszcze takiego z serii "przyjaznych dla RS232"

    Zajrzyj sobie w tabelki i jeśli dla danej prędkości RS232 oraz danego taktowania (może być wewn. oscylem) procent błędów nie przekracza 1-2% to spokojnie możesz taką prędkość sobie stosować a do testów to ci i na upartego 57600 pójdzie przy ustawionym U2X ale nawet i 115200 ;)
  • Poziom 12  
    Ok, już ogarniam ten zapis. Tyle że jeśli w katalogu pisze błąd ~0.2% to nie do końca to działa dobrze. Na przykład dla kwarcu 16MHz i prędkości 38,4bps, do PC wracają krzaki...
  • Poziom 42  
    maciek_nh napisał:
    Na przykład dla kwarcu 16MHz i prędkości 38,4bps, do PC wracają krzaki...


    Niestety to niemożliwe szczególnie jeśli korzystasz z zewnętrznego kwarca żeby przy tej prędkości wracały ci krzaki. Zdecydowanie coś źle robisz jeśli chodzi o samo podejście do wysyłania danych do PC, echa itp

    Można by to było zrozumieć w przypadku taktowania z wewnętrznego oscylatora ale nie dlatego, że on jest do d.... tylko dlatego, że nie wiesz jeszcze o jednej rzeczy. Możliwości jego prostej kalibracji za pomocą rejetru OSCCAL. Było to wielokrotnie opisywane na elektrodzie i dzięki temu można wręcz ustalić idelaną transmisję 115200 dla 8MHz z wewn. oscylatora mając jednak świadomość, że zwiększamy odchyłkę taktowania od 8MHz. No ale zależy co jest priorytetem w projekcie.

    Masz tu przykład kalibracji wewn. oscylatora i przykład jak wysyłać znaki, teksty itp:



    Code:
    int main(void) {
    

       USART_Init( __UBRR );         // inicjalizacja UART

       sei();                     // globalne odblokowanie przerwań

       uint8_t licznik,  pm = licznik = OSCCAL-20;   // zmienne pomocnicze do wizualizacji OSCCAL

       // pętla nieskończona
       while(1) {

          uart_puts("Test UART, wartosc OSCCAL = ");   // wyślij tekst
          uart_putint(licznik, 10);   // wyślij liczbę
          uart_putc('\r');         // wyślij znak CR (enter)
          uart_putc('\n');         // wyślij znak LF (nowa linia)
          _delay_ms(500);            // odczekaj 0,5 sekundy
          OSCCAL = licznik++;         // zwiększ wartość bajtu kalibracyjnego o 1

          // badamy kalibrację tylko w granicach +- 20 w stosunku do
          // tej jaka była ustawiona fabrycznie
          if(licznik > pm+40) licznik=pm;
       }
    }

    void uart_puts(char *s)      // wysyła łańcuch z pamięci RAM na UART
    {
      register char c;
      while ((c = *s++)) uart_putc(c);         // dopóki nie napotkasz 0 wysyłaj znak
    }



    a funkcję do wysyłania pojedynczego znaku już masz tylko dopasuj sobie nazwę. To MUSI działać i to bez żadnych krzaków, a jeśli nadal będziesz miał krzaki to sprawdź wszystkie połączenia lub ustawienia transmisji w PC, bo tam będzie leżał pies pogrzebany.... no chyba że kwarc podłączasz całkiem inny ;) .... ale jak mówiłem wypróbuj to na wewn oscylatorze 8MHz i zobaczysz co to znaczy jego kalibracja.
  • Poziom 12  
    Przy większej prędkości zwarłem linie nadajnika i odbiornika MAX232 i się okazało że to ten układ źle działa. Złożyłem układ według tego schematu:
    http://www.dioda.com.pl/forum/upload_img/obrazki/IMG_4b901eea25afb2736.png
    Wydaje mi się, że jest ok, może to kwestia kondensatorów ?

    W każdym razie zrobiłem połączenie na dwóch NANDach i wszystko działa ładnie :D
    Mam jeszcze pytanie odnośnie HyperTerminala. W opcjach połączenia są tylko niektóre prędkości wymienione w katalogu Atmegi. Czy to jest ograniczenie wynikające z programu czy po prostu tylko przy takich prędkościach można się komunikować ?
    I ostatnia rzecz. Takie same ustawienia jak w HyperTerminalu są w menedżerze urządzeń. Tyle że jeśli tam cokolwiek zmieniłem to to nie miało wpływu na komunikację, czyli te ustawienia można olać ?
  • Poziom 38  
    maciek_nh napisał:

    Wydaje mi się, że jest ok, może to kwestia kondensatorów ?


    Wcześniej ich nie dałeś ??

    W 90% przypadków w nocie aplikacyjnej kostki masz narysowany zalecany schemat połączeń.
  • Poziom 12  
    Kondensatory były. Chodzi mi o to czy nogi 2 i 6 i do nich kondensatory są dobrze połączone na schemacie. A inna rzecz to chyba tylko to że kondensatory mogłyby być złe.

  • Poziom 29  
    Witam.
    Różne max'y i inne kopie max232 mają różne wartości kondensatorów.
    Kilka razy spotkałem się także z błędami transmisji spowodowanymi np. brakiem rezystora podciągającego po stronie ATMEGI ... proszę nie pytać dlaczego ale bez rezystora lub bez diody LED sygnalizującej RX/TX po prostu nic nie działało jak powinno.
    Wymiana np. ST232 na MAX232 rozwiązywała kłopot :-)

    Do tej pory nie uporałem się z tym kłopotem. Zacząłem stosować oryginalne MAX232 w wersji dip lub ST232 w wersji SMD ... i od tej pory nie mam kłopotów.
    Na wewnętrznym oscylatorze RC (8MHz ATMEGA32) uzyskuję transmisje do 64k.
    Kwarc 11.059MHz uzywam tylko do 115kbps.

    Pozdrawiam
    Marek
  • Poziom 27  
    W mojej praktyce wysyłałem i odbierałem dane uP-PC przy zegarze 16MHz z prędkością 115k a poziom błędów nie był na tyle duży aby były przekłamania w transmisji. Może mój PC jest jakiś elastyczny. Ja wiem że to nie powinno mieć związku ale jakie są początkowe ustawienia portów odpowiedzialnych za linie Rxd i Txd?
  • Poziom 15  
    maciek_nh napisał:
    I ostatnia rzecz. Takie same ustawienia jak w HyperTerminalu są w menedżerze urządzeń. Tyle że jeśli tam cokolwiek zmieniłem to to nie miało wpływu na komunikację, czyli te ustawienia można olać ?

    Przedewszystkim zmien hyperterminala na "Realterm", bedziesz widzial dokladnie co sie dzieje i od reki zmienisz wszystko w trakcie pracy..hyperterminal nie wyswietla wszystkiego,ogranicza predkosci.. itd. Realterm vs hyperterminal to jak oscyloskow vs miernik analogowy.

    Podaj oznaczenie ukladu max232 jaki masz. Dla max232 jest inny schemat, dla max232n jest tez inny. Sprawdz note katalogowa swojego max'a tam na 100% jest dzialajacy uklad.
    Ja mam na scalaka max232n i idealnie działa ten układ:
    http://hades.mech.northwestern.edu/images/2/26/Max232n-06.gif
    Zwroc uwage na sytulacje nogi numer dwa.

    Sciagnij note katalogowa swojej atmegi i w dziale USART bedziesz mial dzialajace przyklady usart_init oraz transmit i recive. Przeczytaj dokladnie jakie ustawienia rejestrow powinienes wprowadzic do usart_init. Zobacz sobie jaki jest wzor na obliczednie wartosci rejestru ubrr.
    Zanim cokolwiek zrobisz czytaj dokladnie notki katalogowe, wszyscy mysla ze to zrobiles i daja porady typu zewnetrzne kwarce albo kalibracja.

    Dodano po 4 [minuty]:

    rpal napisał:
    Ja wiem że to nie powinno mieć związku ale jakie są początkowe ustawienia portów odpowiedzialnych za linie Rxd i Txd?
    Sciagnij note katalogowa atmegi i w dziale USART, podpunkcie Register description bedizesz mial defaultowe ustawienia
  • Poziom 11  
    Czym się różnią schematy od MAX232 i MAX232N ?