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

[Atmega128][C] USART a terminal...

arikadiusz 28 Lip 2009 07:27 4017 8
REKLAMA
  • #1 6829407
    arikadiusz
    Poziom 12  
    Witam, mecze sie z tym problemem juz od dwoch dni i nie moge znalezc rozwiazania... mam polaczone USB z atmega w ten sposob:
    [Atmega128][C] USART a terminal...

    Terminal ustawiony tak:
    [Atmega128][C] USART a terminal...
    [Atmega128][C] USART a terminal...

    I nic sie nie wyswietla po nacisnieciu polacz... kod ktorego uzywam to jakis zaczerpniety z forum avrfreaks, z tego co tam napisali powinien dzialac...
    
    #include <stdio.h>
    #include <avr/io.h>
    
    #define FOSC 16000000
    #define BAUD 9600
    #define MYUBRR (FOSC/16/(BAUD)-1)
    
    #define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
    #define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
    
    #define STATUS_LED 0
    
    //Define functions
    //======================
    void ioinit(void);      // initializes IO
    static int uart_putchar(char c, FILE *stream);
    uint8_t uart_getchar(void);
    
    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
    
    void delay_ms(uint16_t x); // general purpose delay
    //======================
    
    int main (void)
    {
    	uint8_t key_press;
    	
        ioinit(); //Setup IO pins and defaults
    
    	printf("Waiting for input:\n");
    
        while(1)
        {
    		key_press = uart_getchar();
    		
    		printf("I heard : %c\n", key_press);
    		
        }
       
        return(0);
    }
    
    
    void ioinit (void)
    {
        //1 = output, 0 = input
    	//       76543210
    	DDRA = 0b11101111;
        DDRB = 0b11101111; //PB4 = MISO 
        DDRC = 0b11111111; //
        DDRD = 0b11111011; //PD2 = RX1
    	DDRE = 0b11101110; //PE0 = RX0
    	DDRF = 0b11101111;
    
        //USART Baud rate: 9600
        UBRR1H = MYUBRR >> 8;
        UBRR1L = MYUBRR;
        UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<UDRIE1);
        UCSR1C |= (3<<UCSZ1);
        
        stdout = &mystdout; //Required for printf init
    }
    
    static int uart_putchar(char c, FILE *stream)
    {
        if (c == '\n') uart_putchar('\r', stream);
      
        loop_until_bit_is_set(UCSR1A, UDRE1);
        UDR1 = c;
        
        return 0;
    }
    
    uint8_t uart_getchar(void)
    {
        while( !(UCSR1A & (1<<RXC1)) );
        return(UDR1);
    }
    
    //General short delays
    void delay_ms(uint16_t x)
    {
      uint8_t y, z;
      for ( ; x > 0 ; x--){
        for ( y = 0 ; y < 80 ; y++){
          for ( z = 0 ; z < 40 ; z++){
            asm volatile ("nop");
          }
        }
      }
    }
    

    Pozmienialem nazwy rejestrow i bitow tak zeby pasowalo do dokumentacji atmega128, ale nie jestem co do konca pewien czy to tak ma byc... Na makiecie mam sygnal ze dane "ida" do procka (mryga dioda LED9) i tyle :/. Z gory dziekuje za pomoc!
  • REKLAMA
  • Pomocny post
    #2 6829759
    rmk
    Poziom 12  
    A z jakiego terminalu korzystasz? Bo na obrazkach masz ustawienia portu tylko.
    Kiedy korzystasz z usartu nie musisz ustawiać kierunkowości portu. Po włączeniu RXEN i TXEN piny te automatycznie są wykorzystywane przez usart i procek sam nimi steruje (przynajmniej w usart0). A dlaczego nie korzystasz z usart0? Wykorzystujesz go juz?
    uint8_t uart_getchar(void)
    {
        while( !(UCSR1A & (1<<RXC1)) );
        return(UDR1);
    }
    Czemu tu masz uint8_t? Nie powinno byc char? Ja mam tak:
    unsigned char USART_odbierz(void) 
    { 
    while ( ! ( UCSR0A & ( 1<<RXC0 ) ) ); 
    return UDR0; 
    }
    Z tym że korzystam z usart0. I wykorzystujesz przerwanie od pustego bufora nadawczego? Bo wg mnie to jest zbędne (o ile z tego nie korzystasz). I spróbuj dla pewności sam policzyć wartość rejestru ubrr1l i wpisać ją. Tak dla pewności ;)
    Pozdrawiam!
  • #3 6829900
    arikadiusz
    Poziom 12  
    Dziekuje za odpowiedz. Uzywam windowsowskiego Hyper Terminala :P. Ale dalej mi nie dziala :/. Teraz kod wyglada tak:
    
    #include <stdio.h>
    #include <avr/io.h>
    
    #define FOSC 16000000
    #define BAUD	9600
    #define MYUBRR (FOSC/(16*BAUD)-1)
    
    #define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
    #define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
    
    #define STATUS_LED 0
    
    //Define functions
    //======================
    void ioinit(void);      					// initializes IO
    static int uart_putchar(char c, FILE *stream);
    uint8_t uart_getchar(void);
    
    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
    
    void delay_ms(uint16_t x); 					// general purpose delay
    //======================
    
    int main (void)
    {
    	uint8_t key_press;
    	
        ioinit(); 								//Setup IO pins and defaults
    
    	printf("Waiting for input:\n");
    
        while(1)
        {
    		key_press = uart_getchar();
    		
    		printf("I heard : %c\n", key_press);
    		
        }
       
        return(0);
    }
    
    
    void ioinit (void)
    {
        										//USART Baud rate: 9600
        UBRR1H = MYUBRR >> 8;
        UBRR1L = MYUBRR;
        UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<UDRIE1);
        UCSR1C |= (3<<UCSZ1);
        
        stdout = &mystdout; 					//Required for printf init
    }
    
    static int uart_putchar(char c, FILE *stream)
    {
        if (c == '\n') uart_putchar('\r', stream);
      
        loop_until_bit_is_set(UCSR1A, UDRE1);
        UDR1 = c;
        
        return 0;
    }
    
    unsigned char uart_getchar(void)
    {
    while ( ! ( UCSR1A & ( 1<<RXC1 ) ) );
    return UDR1;
    }
    
    //General short delays
    void delay_ms(uint16_t x)
    {
      uint8_t y, z;
      for ( ; x > 0 ; x--){
        for ( y = 0 ; y < 80 ; y++){
          for ( z = 0 ; z < 40 ; z++){
            asm volatile ("nop");
          }
        }
      }
    }
    


    EDIT.
    Korzystam z "1" a nie z "0" bo tak mam plytke zrobiona (zwiera sie dwie zworki zeby rdx i tdx podpiac.
  • REKLAMA
  • Pomocny post
    #4 6830080
    ddokupil
    Poziom 15  
    każda transmisja jest tak upierdliwa, ze jak coś nie działa to może być tysiąc powodów.
    Po pierwsze sprawdź czy działa transmisja przez max232 aby wykluczyć problem z USB.
    Sprawdź czy przypadkiem RXD i TXD nie są ze sobą zamienione.
    Ale nie pojawia się w terminalu nic czy tylko krzaczki? Jeśli krzaczki to USART jest źle zainicjowany - przelicz jeszcze raz UBRR.
    Zewrzyj ze sobą txd i rxd i sprawdź czy przy naciśnięciu czegoś w terminalu się pojawia znak. Zacznij sprawdzanie jak najbliżej komputera i przesuwaj się w stronę atmegi.
    Teraz mi więcej nic do głowy nie przychodzi. Ale ja u siebie na przykład na płytce miałem zamiast złącza żenskiego męskie.

    ja UBRR liczę z:

    #define UBRR_VAL	((F_CPU/(BAUD_RATE<<4))-1)

    na pewno działa.

    W ogóle masz tutaj moją obsługę usarta dopasowaną do M128, ale do USART0. Różnica taka, że wszystkie rejestry typu UBRR0H czy UCSR0B zmieniasz na UBRR1H i UCSR1B.
    Załączniki:
  • #5 6832146
    arikadiusz
    Poziom 12  
    czy takie cos w main() powinno wysylac znaki do terminala po wcisnieciu "polacz"?
    
    #include <stdio.h>
    #include <avr/io.h> 
    #include "usart.h"
    
    
    int main(void)
    {
    
        init_usart(); 					//inicjalizacja usart
        
        for(;;)
        {		
            send_usart_char('L');
    
        }
        
    }
    
  • REKLAMA
  • #6 6833999
    ddokupil
    Poziom 15  
    no tak.

    Zdecydowanie powinno.

    Jeśli używasz USART0 zewrzyj ze sobą na procesorze piny 2 i 3 (PE0 i PE1) a jeśli USART1 zewrzyj piny 27 i 28 (PD2 i PD3). Jeśli będziesz coś wysyłał wtedy przez terminal z klawiatury to ten znak zwyczajnie z linii RXD przejdzie na TXD i powinien pojawić się w oknie terminala. Jeśli tak się nie stanie to znaczy, że coś na płytce jest skopane albo terminal nie działa. Ja na przykład używam (moim zdaniem) dużo wygodniejszego Docklight zamiast windowsowego terminala. A używasz przejściówki z USB na COM czy złącza COM na płycie głównej? Możesz też podesłać swój cały projekt z avrstudio czy w czym tam piszesz. Może robisz jakiś absurdalny błąd na który patrzyłeś setki razy i go nie widziałeś? Tak też się zdarza.
  • #7 6836300
    arikadiusz
    Poziom 12  
    zwieralem tak jak mowisz, dziala (wyswietla to co sie nacisnie na klawiaturze). Nie uzywam przejsciowki, mam USB(makieta) - USB(komputer) tak jak na schemacie wyzej. W avr studio to jedynie tutaj moge robic blad bo srednio ogarniam te F_CPU i bity na sekunde
    [Atmega128][C] USART a terminal...
    [Atmega128][C] USART a terminal...

    EDIT.
    zainstalowalem tego twojego docklight-a, udalo mi sie polaczyc ale jakies krzaczki mi wyswietla
    
    2009-07-29 22:10:35.962 [RX] - <DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>??ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>??ă<DC2>?<DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă<DC2><DC4>Ł<CAN>ă?
    
  • REKLAMA
  • Pomocny post
    #8 6837612
    ddokupil
    Poziom 15  
    O. To już coś działa. Wygląda na to, że albo masz źle policzoną wartość UBRR albo dobrze policzoną ale błąd jest zbyt duży do poprawnej transmisji.

    Problem polega na tym, że wartością UBRR ustawiamy dzielnik częstotliwości dla USARTa. Można go jednak ustawić tylko z pewną dokładnością. I tak dla niektórych częstotliwości i prędkości USARTa błąd jest zbyt duży aby komputer mógł poprawnie rozpoznawać poszczególne bity. Musisz albo sobie na kartce wyliczyć jak to wychodzi albo próbować z różnymi prędkościami aż będzie dobrze. Więcej na ten temat masz tutaj. Cała strona jest warta uwagi, ale Ciebie teraz najbardziej interesuje to co jest na dole linku.

    F_CPU to częstotliwość taktowania CPU, czyli jak masz 1MHz to F_CPU jest 1000000.

    Bity na sekundę to standardowe wartości takie jak są w docklighcie na przykład 9600, 57600...
  • #9 6864490
    ddokupil
    Poziom 15  
    Cisza w temacie więc chyba zaczęło działać. Warto się podzielić z przyszłymi pokoleniami przyczyną i rozwiązaniem problemu.
    Pozdr.
REKLAMA