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

Atmega 8 - UART, flaga RXC nie zeruje się po odczycie UDR, co robić?

Geron 18 Wrz 2006 00:26 2045 5
REKLAMA
  • #1 3030865
    Geron
    Poziom 12  
    Posty: 71
    Pomógł: 3
    Ocena: 2
    Witam!

    Jak powinna zachowywać się flaga RXC w tym uC? Według specyfikacji powinna wyzerować się, gdy nowe dane zostaną odczytane z rejestru UDR. W tym momencie głupieje :).

    Program:

    int main(void)
    { //sei();
    UBRRL=0x33; // BaudRate
    UCSRB =0x18; // RXEN TXEN
    // UCSRB |=0x80;


    while(1)
    {
    if (RXC)
    {
    znak = UDR;
    znak++;
    while(!UDRE);
    UDR=znak;
    }
    }
    }

    Powyższy kod (tak sądzę) powinien działać w ten sposób, że układ ogólnie nic nie robi (poza sprawdzeniem flagi RXC), a w momencie nadejścia nowych danych odsyła znak o jeden numer wyższy...... Kicha.

    Non stop coś wysyła (konkretnie "1", chyba że ja coś wyślę, wtedy rzeczywiście odbierze, inkrementuje i odeśle) tak jakby flaga RXC była cały czas "1" -> cały czas nowe dane? Żeby było zabawniej, gdy wykorzystuje przerwanie wszystko jest OK, sęk w tym, że w większym projekcie (to jest tylko test UART`a nie mogę wykorzystać tego przerwania):

    Próbowałem zerować tą flagę softwearowo, czyścić bufor UART`a

    while(!RXC)
    { dummy=UDR;
    } (tu program się zapętla)

    nie wiem co jeszcze można zrobić...

    Pozdr.
  • REKLAMA
  • Pomocny post
    #2 3031014
    przemek20
    Poziom 21  
    Posty: 328
    Pomógł: 41
    Ocena: 25
    A jakiego kompilatora używasz?
    Jesteś pewien że on łyka zapis typu RXC?
    Bo np w Code vision musze zrobić tak:
    
    if(UCSRA.7) ...
    


    za to w winavr czy innym gcc żeby wytestować bit to trzeba użyć lepszych myczków :)

    Pozdrawiam.
  • REKLAMA
  • #3 3031296
    Geron
    Poziom 12  
    Posty: 71
    Pomógł: 3
    Ocena: 2
    witam.

    Powiem szczerze.... Byłem przekonany że mój kompilator akceptuje bezpośrednie odniesienie do flag.. (często używam odniesienia np. while(!UDRE) i jest wszystko OK) i już chciałem odpisać, że RXC też akceptuje, ale zanim to, sprawdziłem zapis while(USRCA&0x80) i....
    działa. Cały dzień nad tym siedziałem (pół dnia żeby wyłuskać błąd z większego kodu :| )

    Dzięki.
    Pozdr.

    używam Visual Micro Lab 3.12 for AVR. Jest naprawdę fajny (oprócz tej wpadki). Polecam.

    Dodano po 4 [godziny] 8 [minuty]:

    Sorki. błąd.
    Wcześniejszy post był tak na szybko sprawdzenie też :). Sprawdziłem wówczas zapis:

    if (UCSRA&0x80)
    {......
    }

    i rzeczywiście kod w zawiasach wykonuje się po odebraniu nowych danych, ale w projekcie muszę chwilkę poczekać na dane, więc używam komendy

    while(!UCSRA&0x80);
    {...
    }

    kod ... powinien wykonać się po otrzymaniu nowych danych (wcześniej na nie czekając). Zamiast tego kod leci do przodu nie czekając na dane (jakby UCSRA&0x80 zawsze było "1")
    Dopiero taka konstrukcja działa poprawnie:

    while(1)
    if (UCSRA&0x80)
    {........
    break;
    }

    Troszkę tego nie rozumiem, ale cóż......

    Obecny kod (z tą działającą konstrukcją) chodzi, więc temat mogę zamknąć, ale jakby ktoś może potrafił to wyjaśnić (co jest grane) byłbym wdzięczny:).

    Czy może być coś skopsane w kompilacji komendy "while" w kompilatorze?

    Pozdr.
  • REKLAMA
  • #4 3032719
    Dexter77
    Poziom 28  
    Posty: 889
    Pomógł: 134
    Ocena: 19
    Dlatego warto znac asembler i poprostu sprawdzic co kompilator wygenerowal. Bledy byly i beda, tego nawet geniusz informatyczny nie uniknie ;)
    Pozdrawiam
    Dexter
  • REKLAMA
  • #5 3032999
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Geron napisał:
    ...Czy może być coś skopsane w kompilacji komendy "while" w kompilatorze?
    Pozdr.

    Skopsany jest zapis instrukcji , a nie kompilator :)
    Ponieważ kompilator złożone instrukcje wykonuje w pewnej kolejności , to zapisu jakiego użyłeś , chyba nie potrafi zinterpretować. A ponieważ ta instrukcja jest poprawna składniowo , to nie ostrzega o błędzie , choć moim zdaniem powinien.
    Zrozumiałym dla kompilatora zapisem będzie:
    
    while(!(UCSRA&0x80)); //lub czytelniej while(!(UCSRA&(1<<RXC)));
    

    Jeśli zaś chodzie o flagi ...
    
    while(!RXC) ; // równoznaczne z while(!7);
    //lub
    while(!UDRE); // równoznaczne z while(!5);
    

    ... to wystarczy zajrzeć do plików nagłówkowych , co jest zdefiniowane pod etykietami UDRE , RXC , itd. , a wtedy będzie wiadomo co kompilator na takie dictum ;) Po stwierdzeniu , że to "żdana" pętla , nie wygeneruje kodu , tak samo jak w przypadku while(1<2); , czy coś w tym guście :D
    Np. dla ...
    
    while(1>2)
       {
        //instrukcja
        //instrukcja
       }
    

    ... wszystko co jest w takiej pętli , zostanie pominięte w procesie kompilacji.I można by tak jeszcze paplać dość długo ;)
    Lekarstwem no takie "przypadki" jest to , o czym wspomniał Dexter77


    Piotrek
  • #6 3033361
    Geron
    Poziom 12  
    Posty: 71
    Pomógł: 3
    Ocena: 2
    Ok. OK :). Dzięki. Już zajarzyłem.

    Rzeczywiście while(!(UCSRA&0x80)).

    Pliki nagłówkowe sprawdzam (przynajmniej obejrzałem jak zabrałem się za Atmegę 8) i głupio utrwaliłem się w przekonaniu że tam są praktycznie wszystkie nazwy z dokumentacji wytrawione na stałe :) ... jednak niedokońca. Trzeba uważać.
    Asemblera znam, ale niejestem z nim w najlepszych stosunkach ostatnio :). Będę musiał odświerzyć tą znajomość.
    Dziękuję za uwagi.
    Pozdr.

    Temat uważam za zamknięty
REKLAMA