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

Problem z USARTem Atmega16+Atmega8 [C]

gamgee1 04 Gru 2009 16:59 1605 8
REKLAMA
  • #1 7344643
    gamgee1
    Poziom 11  
    Męczę się nad tym od jakiegoś czasu i nie mogę sobie z tym poradzić. Próbuję połączyć ze sobą te dwa kontrolery.

    Zacząłem od skonfigurowania Atmegi16 do odbioru i połączenia jej z HyperTerminal. Najgorsze jest to że jakiś rok temu zrobiłem to bez problemu a dziś za żadne skarby mi nie wychodzi.
    Programik raczej prosty:
    
    #include<avr/io.h>
    #include<avr/interrupt.h>
    
    volatile char key;
    volatile char i;
    volatile char w=0;
    
    ////////////////////////////////////////////////////////////////////////////////////////////////
    
    ISR(USART_RXC_vect)  //------------przerwanie dla otrzymania danej odbiorczej (USART)-----------------
    {
    i++;
    key=UDR;  //przypisuje zmiennej 'key' wartosc wcisnietego przycisku
    w=key;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    int main(void)
    {
    DDRA=0;
    PORTA=0xff;
    
    UBRRL=0x33;
    UBRRH=0;     //ustawienie prędkości transmisji dla 9600 bps
    UCSRB=0x90;  //włączenie obsługi przerwań dla odbioru//włączenie odbioru
    UCSRC=0x86;  //tryb pracy asynchronicznej//wyłączenie bitu parzystosci//1 bit stopu/8 bitów danych
    SREG|=1<<SREG_I;  //ustawienie flagi I w ESREG
    
    while (1)
    {
    
    PORTB=w;
    }
    }
    


    Otóż program ma mi wyświetlać na porcie B kod liczby wciśniętej na klawiaturze. Jak z tym sobie poradzi to i dane z innego proca też przyjmie. Częstotliwość CPU=8MHz.
    Problem w tym że zamiast innego kodu dla każdego klawisza wyświetla bez przerwy 0xff.
    To co wiem na pewno to to że program skacze w przerwanie za każdym razem ponieważ dla PORTB=i; inkrementuje wyświetlaną liczbę za każdym razem jak przycisnę klawisz.

    Nie mogę wyciągnąć z przerwania wartości przesyłanej danej.
  • REKLAMA
  • #2 7344845
    Tantalos
    Poziom 18  
    Musisz ustawić PORTB jako wyjście, a nie PORTA :).
  • REKLAMA
  • #3 7353047
    gamgee1
    Poziom 11  
    Nie w tym tkwi problem, ale literówkę poprawiłem. Procesor sam ze sobą się komunikuje ale z Terminalem nie chce, podłączam atmega8 i za każdym resetem pojawia mi się nie to co powinno
  • REKLAMA
  • REKLAMA
  • #6 7354296
    _Robak_
    Poziom 33  
    Po pierwsze to mozesz sobie wpisac tam cokolwiek, jesli wlaczysz odbieranie, zawsze pin jest jako wejscie. No i adruga sprawa, ze i tak pin ma byc wejsciem ;)
  • #8 7356103
    gamgee1
    Poziom 11  
    Ludzie... Poprawiłem ten błąd, to była literówka przy wpisywaniu na forum. W programie było dobrze. Tu poprawiony kod, dalej zachowuje się tak jak opisałem na początku.
    #include<avr/io.h>
    #include<avr/interrupt.h>
    
    volatile int b=20;
    volatile char key;
    
    ////////////////////////////////////////////////////////////////////////////////////////////////
    
    ISR(USART_RXC_vect)  //------------przerwanie dla otrzymania danej odbiorczej (USART)-----------------
    {
    
    key=UDR;  //przypisuje zmiennej 'key' wartosc wcisnietego przycisku
    
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
    
    void send_USART( unsigned char data )
    {
       /* Czeka aż bufor danych będzie pusty */
       while ( !( UCSRA & (1<<UDRE)) )
       ;
       /* Wysyła dane */
       UDR = data;
    }
    
    int main(void)
    {
    
    DDRB=0xff;
    
    UBRRL=0x33;
    UBRRH=0;     //ustawienie prędkości transmisji dla 9600 bps
    UCSRB=0x98;  //włączenie obsługi przerwań dla odbioru//włączenie odbioru/włączenie nadawania
    UCSRC=0x86;  //tryb pracy asynchronicznej//wyłączenie bitu parzystosci//1 bit stopu/8 bitów danych
    SREG|=1<<SREG_I;  //ustawienie flagi I w ESREG
    
    while (1)
    {
    send_USART(b);
    PORTB=key;
    }
    }
    
    

    Zwarłem TXD z RXD i procesor sam sobie dobrze przesyła dane, czyli wyświetla mi liczbę 20. Umieściłem tą część programu
    
    void send_USART( unsigned char data )
    {
       /* Czeka aż bufor danych będzie pusty */
       while ( !( UCSRA & (1<<UDRE)) )
       ;
       /* Wysyła dane */
       UDR = data;
    }
    

    razem z tą konfiguracją
    UBRRL=0x33;
    UBRRH=0;     //ustawienie prędkości transmisji dla 9600 bps
    UCSRB=0x98;  //włączenie obsługi przerwań dla odbioru//włączenie odbioru/włączenie nadawania
    UCSRC=0x86;  //tryb pracy asynchronicznej//wyłączenie bitu parzystosci//1 bit stopu/8 bitów danych
    SREG|=1<<SREG_I;  //ustawienie flagi I w ESREG
    

    w drugim procesorze na drugiej płycie testowej z Atmega8 i połączyłem jej TXD z RXD atmega16 na której chce odbierać dane. Każę wysłać jakąś liczbę a na wyświetlaczu z diód pojawia się coś zupełnie innego, kiedy resetuje procesor który wysyła, za każdym razem pojawia mi się coś innego. (obie płytki zasilam z tego samego źródła)
  • #9 7361058
    wojtek_84
    Poziom 13  
    Ściągnij sobie taki program "Realterm". Bardzo fajny i pomocny w debugowaniu UARTA. Mi wiele razy pomógł. Moim zdaniem HyperTerminal to się do kontrolerów zupełnie nie nadaje.
REKLAMA