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

Atmega8 i RS232 - błędna transmisja znaków w terminalu (C, AVR Studio 4)

Slice 08 Mar 2006 11:39 3200 3
REKLAMA
  • #1 2389226
    Slice
    Poziom 11  
    Posty: 31
    Witam.
    Próbuję uruchomić atmege8 + max232 do komunikacji z kompem. Kabel do komunikacj jest z przeplotem 1,8m. Gdy w uc wystawiam cały czas jeden znak na rsa to w terminalu leci ciąg takich samych znaków np. dla wystawianego 'a' (hex 61) terminal odczytuje <0>rr , obydwa r z akcentami (hex 00 E0 E0). Pełna powtarzalność zjawiska.
    Przy transmisji uc -> komputer wychodzą krzaki. Problem jest najprawdopodbniej w programie. Sprawdzałem na 2 atmegach(to samo). Max232 podłączony poprawnie - po zwarciu rx-tx (od strony procesora, ttl) tekst wpisany w terminalu na PC wraca do terminala.
    Czytałem specyfikacje atmela. Może coś przeoczyłem. Treść programu jest po części zaczerpnięta z niej. Będę wdzięczny za pomoc.

    Pozdarawiam,
    Robert

    Terminal v1.9b by Br@y++ (baud rate 1200, 8bitów danych, parzystosc - none, 2bity stopu, handshaking - none)

    Program w C (AVR Studio 4):
    
    #include <avr/io.h>
    #define BAUD 1200//115200
    #define MYUBRR 11059200/16/BAUD-1
    
    int main(void)
    {
    DDRC=0xff;
    char znak[20]="abcdefghijklmnopqrst";
    unsigned char i;
    
    // inicjalizacja portu rs
    unsigned int ubrr;
    ubrr = MYUBRR;
    while (!(UCSRA & (1<<UDRE)));
    UBRRH = (unsigned char)(ubrr >> 8); // ustawienie UBRR
    UBRRL = (unsigned char) ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN); // uruchomienie RX TX
    UCSRC = (1<<USBS)|(3<<UCSZ0); // 8 bitow danych, 2 bity stopu 
    while (1)
    {
    for(i=0; i<20; i++) // wyslanie tablicy
    {
    	while (!(UCSRA & (1<<UDRE))); 
    	UDR=znak[i];
    }
    }
    /*
    }
    while(1) // nieskonczone odbieranie
    {
    	while ( !(UCSRA & (1<<RXC)) );
    	PORTC=UDR;	
    	UCSRA=0;
    }*/
    while(1);
    return 0;
    }
    


    Na schemacie LED przy pinach dla stk200 jest w odwrotnej polaryzacji, tak samo jak kondensator przy max232N przy V-. W biblotekach eagel nie znalazłem 7805 wiec wstawiłem goldpiny 3x1. Nie montowałem kondensatora przy resecie. Rezystory podciągające 2,7k, resetu 8k, kwarc 11,0592MHz. Kondensatory przy max232 1uF elektrolityczne, przy 7805 100uF elektrolityczne.
    Załączniki:
    • Atmega8 i RS232 - błędna transmisja znaków w terminalu (C, AVR Studio 4) board.jpg (36.64 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • REKLAMA
  • Pomocny post
    #2 2389543
    hunterhouse
    Poziom 26  
    Posty: 893
    Pomógł: 84
    Ocena: 3
    twój przypadek wygląda tak jakby procesor używał innego bauda jak mu każesz.
    po pierwsze sprawdz czy ATmega kożysta z zewnętrznego kwarcu (chodzi o fusebity) bo standardowo jak wyjeżdza z fabryki to chodzi wewnętrznym 1MHz.

    po drógie sprawdz konfigóracje uarta
    są w necie takie programiki do obilczania wartość rejstrów na różnych kwarcach.
  • REKLAMA
  • #3 2389977
    Slice
    Poziom 11  
    Posty: 31
    No dobra, problem chyba na pewno tkwi w zapisie do UBRRH i UCSRC. Chodzi o flagę URSEL.
    When the function writes to the UCSRC
    Register, the URSEL bit (MSB) must be set due to the sharing of I/O location by UBRRH
    and UCSRC.)
    (strona 138 ze specyfikacji).
    Tyle tylko, że poniższa modyfikacja problemu nie usuwa(choć teraz 'a' jest odbierane jako <0>r)
    
    UCSRC = 0; // flaga URSEL = 0
    UBRRH = (unsigned char)(ubrr >> 8); // ustawienie UBRR
    UBRRL = (unsigned char) ubrr;
    
    UCSRC = UCSRC|(1<<URSEL); // flaga URSEL=1 tak by nie zmienic UBRRH
    UCSRC = (1<<USBS)|(3<<UCSZ0); // 8 bitow danych, 2 bity stopu 
    UCSRB = (1<<RXEN)|(1<<TXEN); // uruchomienie RX TX
    


    Może coś źle zrozumiałem?!?
    Oscylator działa, zauważyłem zmianę w funkcji opóźnienia. Fusebity:
    Załączniki:
    • Atmega8 i RS232 - błędna transmisja znaków w terminalu (C, AVR Studio 4) Fuse&LockBits.jpeg (19.91 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #4 2390891
    Slice
    Poziom 11  
    Posty: 31
    Już sobie poradziłem. Poprawna inicjalizacja usart dla atmega, może się komuś przyda:

    
    #define BAUD 1200
    #define MYUBRR 11059200/16/BAUD-1
    .
    .
    .
    unsigned int ubrr;
    ubrr = MYUBRR;
    while (!(UCSRA & (1<<UDRE)));
    UBRRL = (unsigned char) ubrr;       // ustawienie UBRRL
    UBRRH = (unsigned char)(ubrr >> 8); // ustawienie UBRRH
    UCSRC = (1<<URSEL)|(3<<UCSZ0);  // 8b danych, brak parzystosci, 1b stopu.
    UCSRB = (1<<RXEN)|(1<<TXEN); // uruchomienie RX TX
    


    Ważna kolejność UBRRH, UCSRC !!!

    Dzięki za pomoc
    Pozdrawiam,
    Robert.
REKLAMA