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

Jak poprawnie zainicjować USART w ATmega8535? Rejestry UCSRC i UBRRH

marcinowy 22 Gru 2003 17:06 2752 11
REKLAMA
  • #1 446954
    marcinowy
    Poziom 11  
    Posty: 11
    Odkad uzywam procesora ATmega8535 nie moge prawidlowo zainicjowac USART-a. Obojetne, czy napisze program w BASCOMie czy w ASM (zgodnie z opisem podanym w nocie katalogowej procesora) port RS dziala niezgodnie z moja deklaracja. Problem tkwi w tym, ze po inicjacji w rejestrze UCSRC pozostaje ta sama wartosc co w UBRRH i transmicja odbywa sie w trybie 5-bitowym lub odwrotnie - 8 bitow danych, ale predkosc odpowidnio mniejsza. Jakie dodatkowe warunki trzeba spelnic aby mikrokontroler prawidlowo wystartowal i bylo mozliwe rozgraniczenie wpisow w rejestrach UBRRH i UCSRC tak jak podaje Atmel? Czy ktos mial podobny problem?
  • REKLAMA
  • #2 447086
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    a co na to symulator?
  • #3 447096
    marcinowy
    Poziom 11  
    Posty: 11
    W symulacji program dziala doskonale
  • REKLAMA
  • #4 447107
    marcinowy
    Poziom 11  
    Posty: 11
    W symulacji program dziala, nie mniej jednak symulator pokazuje, ze zawartosc rejestrow jest taka sama.
  • #5 447109
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    jezeli symulator pokazuje ze da sie zaladowac rozne wartosci a rzeczywiscie tak nie jest, to sklanialbym sie ku zrzuceniu winy na proca.
    nic wiecej ci nie doradze, gdyz z mega8535 jeszcze nie pracowalem - nie moglem go dostac :(
  • #6 447131
    marcinowy
    Poziom 11  
    Posty: 11
    W BASCOMie i AVR Studio podczas symulacji programowej nie udalo mi sie uzyskac roznych zawartosci rejestrow UBRRH i UCSRC. Calkiem mozliwe, ze w ogole jest to niemozliwe - nie wiem. Jesli chodzi o procesory to dzisiaj zakupilem nastepny egzemparz i efekt jest ten sam.
  • REKLAMA
  • #7 447177
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    tyle, co wylookałem z datasheet atmela na temat inicjalizacji USART'a:

    [font=Courier New:0b0fdb98ee]USART_Init:
    ; Set baud rate
    out UBRRH, r17
    out UBRRL, r16
    ; Enable Receiver and Transmitter
    ldi r16, (1<<RXEN)|(1<<TXEN)
    out UCSRB,r16
    ; Set frame format: 8data, 2stop bit
    ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)
    out UCSRC,r16
    ret[/font:0b0fdb98ee]
    :!: w asmie na początku musisz włączyć plik .inc, bodajze sie nazywa m8535def.inc, ale nie dam sobie glowy obciąć.
    inaczej nie beda sie zgadzaly adresy rejestrów

    :!: zobacz, czy nie masz poustawianych jakichs bitow, np włączonej kompatybilnosci z 90S8535 (!)
  • REKLAMA
  • #8 447305
    marcinowy
    Poziom 11  
    Posty: 11
    Co do procedury inicjujacej USART_init podanej przez producenta to juz ja stosowalem. Miedzy innymi dlatego prosze o pomoc.
    Z kolei co do bitow kompatybilnosci z 90S8535 nie wiem gdzie ich szukac. Moze przy ustawieniach programatora? No, nie wiem. Mikrokontroler 90S8535 juz stosowalem i to z duzym powodzeniem. Rejestry UARTu w tym procesorku czesciowo sa zgodne z niektorymi rejestrami ATmega8535 - BASCOM w symulacji przypisuje im odpowiednie wartosci jakie sa w rejestrach ATmegi, ale w AVR studio tego zjawiska nie ma.
    Po zaprogramowaniu procesora odczytalem zawartosci jego Flasha, zdebagowalem i otrzymalem ten sam kod zrodlowy jak wczesniej napisalem.
  • #9 447332
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    są to bity programowane w trybie rownoleglym (niektore tez przez SPI).
    powinno sie dac ustawic/skasowac w programie obslugujacym programator.
  • #10 448212
    marcinowy
    Poziom 11  
    Posty: 11
    Uzywam Sample Electronics Programmer pod BASCOM-AVR 1.11.7.4.
    Bit 7 w fuse high byte jest bitem kompatybilnosci z 90S8535 (0). Ustawianie roznych jego wartosci nie powoduje jednak zadnej reakcji. Nadal to samo.
    Moze Ktos ma przykaladowy, prosty programik napisany pod ATmega8535 z obsluga USART-u dzialajacy nalezycie?
  • #11 457065
    marcinowy
    Poziom 11  
    Posty: 11
    Wszystko juz sie wyjasnilo. USART dziala poprawnie, jak z reszta caly procesor pod warunkiem, ze prowidlowo zostanie zdefiniowany Fuse Low Byte. W moim przypadku domyslnie byl ustawiony oscylator wewnetrzny 1MHz, a korzystalem z zewnwtrznego kwarcu 3,6864 MHz - mala wpadka ,a tyle klopotow.
  • #12 892609
    migod
    Poziom 21  
    Posty: 462
    Pomógł: 29
    Ocena: 8
    Hej,
    napisalem cos takiego na ATm8515, fuse_high=0xd9, uP pracuje na 1MHz, transmisja ustawiania na 8N1, bez parzystosći, 19200, 9600 i za każdym razem komputer odbiera od uP przekłamaną w całości transmisję.


    Coś zmaściłem, ale co?? Skończyły mi się pomysły..

    Z góry dzięki,
    migod

    usart.c
    ---------------------------
    static volatile u08* data;

    void usart_init(u16 baud) {
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)(baud);

    UCSRA = (SPEED_MODE << U2X); // speed_mode = (0 | 1)

    UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<RXCIE) | (1<<TXCIE); // enable USART interrupts

    UCSRC = (1<<URSEL) | (DATA_MODE<<UCSZ0) | (STOP_MODE<<USBS); // data_mode = (2 | 3), stop_mode = (0 | 1)

    sei();
    }
    // invoked when sending is completed (ready for a new data)
    SIGNAL(SIG_UART_TRANS) {
    if(data)
    if(++data) {
    UDR = *data;
    }
    }
    // invoked when a new data is waiting in a input buffer
    SIGNAL(SIG_UART_RECV) {
    *data = UDR;
    }
    // send a byte
    void usart_sendb(u08 val) {
    while( !(UCSRA & (1<<UDRE)));
    data = NULL;
    UDR = val;
    }
    // receive a byte from buffer
    u08 usart_recvb(void) {
    while ( !(UCSRA & (1<<RXC)));
    return (*data);
    }
    ------------------------
    usart.h
    typedef unsigned char u08;
    typedef char s08;
    typedef unsigned short u16;
    typedef short s16;

    /* USART Baud rate calculation */
    #define UART_CPU 1000000 /* X Mhz */
    #define UART_BAUD_RATE 19200 /* baud rate*/

    #define _WITH_U2X 1
    #define _WITHOUT_U2X 0

    #define _2bitStop 1
    #define _1bitStop 0

    #define _8Nx 3 // (3 << UCSZ0) in UCSRB
    #define _7Nx 2 // (2 << UCSZ0) in UCSRB

    #define SPEED_MODE _WITHOUT_U2X
    #define DATA_MODE _8Nx
    #define STOP_MODE _1bitStop

    #if SPEED_MODE == _WITH_U2X
    #define UART_BAUD_SELECT (UART_CPU/(UART_BAUD_RATE*8l)-1)
    #endif

    #if SPEED_MODE == _WITHOUT_U2X
    #ifdef UART_BAUD_SELECT
    #error "Misconfiguration with SPEED_MODE!!!"
    #endif

    #define UART_BAUD_SELECT (UART_CPU/(UART_BAUD_RATE*16l)-1)
    #endif

    void usart_init(u16 baud);
    void usart_sendb(u08 val);
    u08 usart_recvb(void);

    --------------------------------------
    main.c

    int main(void) {
    usart_init((u16)UART_BAUD_SELECT);

    while(1) {
    usart_sendb(usart_recvb());
    }
    return (0);
    }

Podsumowanie tematu

✨ Problem dotyczył prawidłowej inicjalizacji interfejsu USART w mikrokontrolerze ATmega8535, a konkretnie rozdzielenia i poprawnego ustawienia rejestrów UCSRC i UBRRH. Po inicjalizacji rejestry te miały identyczną zawartość, co skutkowało błędną konfiguracją transmisji (np. 5-bitowy tryb danych lub nieprawidłowa prędkość). W symulacjach programowych (BASCOM, AVR Studio) obserwowano podobne zachowanie, co sugerowało specyfikę działania rejestrów w tym mikrokontrolerze. Wskazano, że rejestr UCSRC wymaga ustawienia bitu URSEL, aby odróżnić go od UBRRH, a także konieczne jest dołączenie odpowiedniego pliku definicji (.inc) w asemblerze. Dodatkowo zwrócono uwagę na bity konfiguracyjne (fuse bits), zwłaszcza bit kompatybilności z 90S8535 w fuse high byte, który może wpływać na działanie USART. Ostatecznie problem rozwiązało prawidłowe ustawienie fuse low byte, ponieważ domyślnie mikrokontroler pracował na wewnętrznym oscylatorze 1 MHz, podczas gdy użytkownik korzystał z zewnętrznego kwarcu 3,6864 MHz, co powodowało niezgodności w prędkości transmisji. Przykładowy kod inicjalizacji USART w asemblerze i C został podany, podkreślając konieczność ustawienia bitu URSEL przy zapisie do UCSRC oraz poprawnej konfiguracji fuse i taktowania mikrokontrolera.
Wygenerowane przez model językowy.
REKLAMA