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

[ATMega16][C] Prawidłowa konfiguracja USART-a

MarcinBarowski 11 Lut 2009 16:54 1872 11
  • #1 6135000
    MarcinBarowski
    Poziom 15  
    Witam,

    na początku chciałbym zaznaczyć ze moja przygoda z tymi procesorami dopiero co sie rozpoczęła, dlatego prosiłbym o wyrozumiałość.

    Mój problem dla wielu z was może okazać sie banalny jednak ja sobie z nim nie radze. Chodzi o konfigurację USARTa w Atmega16.
    Poniżej znajduje sie część kodu konfigurującego procesor. Problem w tym ze UCSRC nie chce mi sie ustawi, cały czas jest zero.
    Co może być nie tak?

    Kod:
    
    void ustaw_usart(void) 
       { 
       UBRRH=0; 
       UBRRL=103;
       UCSRB =_BV(RXEN)|_BV(TXEN);
       UCSRC =_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0);
       }
    

    Pozdrawiam

    Marcin Barowski
    Poprawiłem tytuł - regulamin p.11.1
    Dodałem znaczniki [code] - proszę ich używać w treści wiadomości
    [zumek]
  • #2 6135129
    marenc
    Poziom 24  
    A na jakiej podstawie stwierdzasz, że Ci się nie ustawia? Po czym to wnioskujesz?
  • #3 6137595
    MarcinBarowski
    Poziom 15  
    Widzę to w AVRStudio. Do programowania używam JTAGa i przy debugowaniu jedynie ten Rejestr zostaje nie zmieniony.
  • #4 6138318
    marenc
    Poziom 24  
    ... pytałem, ponieważ gdy się debuguje krok po kroku, to po ustawieniu rejestru jeżeli program wpada w martwą pętlę, to program nie pokaże zmiany wizualnie, ale sprzętowo będzie istniała.

    Zobacz w pliku definicji stałych dla ATmega16, czy rejestry UBRRH i UCSRC mają jednakowy adres. Podaj dokładną nazwę mikrokontrolera(ostatnio wyszły nowe wersja ATmega16A, które być może mają inne te adresy, a masz źle zdefiniowane). Możesz spróbować zapisać wartość bezpośrednio do adresu. Daj schemat zasilania układu. Podaj jakim kompilatorem dla C się posługujesz.

    W ostateczności napisz to samo inaczej:
    UCSRC =((1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0));
  • #5 6138491
    MarcinBarowski
    Poziom 15  
    Witam,

    tak obydwa rejestry maja ten sam adres. Gdy zmieniam UCSRC to zmienia sie również UBRRH. Wpisałem również twoją propozycje co do ustawień UCSRC, jednak to również nic nie zmieniło :/
    Kompilator to AVRStudio z wgranym WinAVRem. O co chodzi z zasilaniem bo nie rozumiem? Wszystko testuje na zestawie startowym, także zasialanie jest raczej dobrze zrobione.
    pozdrawiam

    Marcin Barowski
  • #6 6138505
    marenc
    Poziom 24  
    Jeżeli adresy są jednakowe, to wyboru dokonuje się za pomocą bitu URSEL. Zapisz do zmiennej wartość "((1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0))" i zobacz czy będzie w niej ustawiony bit 7(zobacz też czy w pliku definicji URSEL ma wartość 7). Wartość w tej zmiennej powinna być wyższa od 0x80.
  • #7 6138514
    MarcinBarowski
    Poziom 15  
    No właśnie że nic sie nie ustawia, wszystkie bity sa wyzerowane.Czy może mieć to jakiś związek z UBRRH? Tzn czy przy deklaracji UBRRH można było tak ustawić bity że teraz zmiana UCSRC nic nie powoduje?
  • #8 6138533
    marenc
    Poziom 24  
    No i chyba proste będzie rozwiązanie. Nie masz żadnej wartości w UBRRH, a gdy zapiszesz cokolwiek do UCSRC najprawdopodobniej w prawidłowy sposób będzie tam zapisane. Program wyświetla daną z pod adresu, a więc wyświetla UBRRH, ale UCSRC jest tak jakby pod nim, więc program tam zapisał wartość, ale jej nie pokazuje.

    Sprawdź po prostu czy transmisja działa ;)
  • #9 6138545
    MarcinBarowski
    Poziom 15  
    Nie niedziała :(

    Cały czas odbieram albo 0xC0 albo 0xFF... Raz tylko zdarzyło się że odebrałem wartość taką jaką wysłałem.
    Czy może być to związane tym że procka z układem RS485 mam podpiętego na kabelkach (takie jest rozwiązanie zestawu)?
  • Pomocny post
    #10 6138555
    marenc
    Poziom 24  
    0xFF, to brak transmisji, ale 0xC0 świadczy o pewnym przesyle. Było by miło, gdybyś podłączył oscyloskop, bo mogli byśmy wyeliminować błędy transmisji. Połącz RxD z TxD mikrokontrolera i zobacz czy odbierasz to co wysłałeś.
  • #11 6138591
    MarcinBarowski
    Poziom 15  
    ok, działa.
    Tzn. gdy podłącze ze sobą txd i rxd układ nadaje i odbiera to samo.
    Chyba mi trzaśniętego Rs485 sprzedano :/
    dzięki marenc za pomoc... myślę że temat można zakończyć.

    pozdrawiam i przesyłam zasłużone 3pkt.
  • #12 6269774
    herszt
    Poziom 18  
    To ja podepnę się do tematu :)
    Otóż napisałem sobie wg. datasheeta taki programik co to ma na celu czytanie znaku z terminala i odsyłanie go :)

    
    #include <avr\io.h>
    
    #define xtal 11000000L
    #define baud 9600
    
    int main()
    {
       // Calculate UBRR correctly using large temp variables
          uint32_t temp;
    	  unsigned char x ;
          temp = xtal/16/baud-1;
          UBRRH = (temp >> 8);
          UBRRL = (temp & 0xFF);
    
       // Initialize UCSRB
          UCSRB= (1 << RXEN | 1 << TXEN );
       
       // Initialize UCSRC correctly
          UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
       
       while(1)
       {
       	  // Wait for data to be received
    	  	 while ((UCSRA & (1<<RXC)) == 0) ;
    
    	  // Get received data from buffer
    	  	 x = UDR ;
    
          // Loop until UDR register is empty
             while ((UCSRA & (1 <<UDRE)) == 0);
          	
          // Transmit letter
             UDR = x;
       };
    return 0;
    } 
    


    No i tak nie bardzo to chce działać ;) Jak pominę część odpowiedzialną za czytanie i na sztywno przypiszę x jakąś wartość to wysyła co trzeba :)
    Może ktoś ma jakieś pomocne uwagi? Być może nie dokładnie doczytałem datasheeta i coś pominąłem ;)

    z góry dzięki za pomoc
    pozdrawiam
    herszt
REKLAMA