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] PC <-> atmega128 2xRS232 w C

marek-72 21 Sie 2008 13:30 1949 13
REKLAMA
  • #1 5459555
    marek-72
    Poziom 11  
    Witam,

    Probuje sciagnac jakis przyklad dzialajacego kodu na atmedze 128 obslugujacego 2 USARTy ale nie udaje mi sie znalesc zadnego.

    Znalazlem jakies na inne avr'y ale nie na 128.

    Czay moglbym prosic kogos o wklejenie dzialajacego przykladowego kodu w C?

    Czy w AVR studio mam cos ustawic zeby program dzialal?

    Uzywam ICE JTAGa.

    Serdeczne dzieki za pomoc

    Pozdrowienia!
  • REKLAMA
  • #2 5459724
    pubus
    Poziom 30  
    
    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <stdlib.h> 
    #include <math.h>
    #include <avr/io.h>
    
    #define F_CPU  7372800 //20000000 //18432000 //11059200 //3686400 //18432000  //14745600
    #define CYCLES_PER_US (F_CPU/1000000)
    
    /****** Funkcje delay *******************************************/
    void delay(unsigned int us) 
    { 
     unsigned int delay_loops;
     register unsigned int  i;
    
     delay_loops = (us+3)/5*CYCLES_PER_US; 
     for (i=0; i < delay_loops; i++) {};
    } 
    
    void delayms(unsigned int ms)
    {
     unsigned int i;
    
     for (i=0;i<ms;i++) {delay(999); asm volatile ("WDR"::);}
    } 
    /***************************************************************/
    
    /****** Inicjalizacja USART0 *****************************************/
    void USART0_Init( void ) 
    { 
     UBRR0H = 0;
     UBRR0L = 47;      // 9600 bound 
     UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); 
     UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);  
    }
    /*********************************************************************/
    
    /****** Inicjalizacja USART1 *****************************************/
    void USART1_Init( void ) 
    { 
     UBRR1H = 0;
     UBRR1L = 47;      // 9600 bound 
     UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 << TXEN1); 
     UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);  
    }
    /*********************************************************************/
    
    /****** Wyślij bajt przez USART0 *************************************/
    int USART0_Transmit( unsigned char data ) 
    { 
     while ( !( UCSR0A & (1<<UDRE0)) );/* Wait for empty transmit buffer */ 
     UDR0 = data;/* Put data into buffer, sends the data */ 
     return 0; 
    } 
    /*********************************************************************/
    
    
    /****** Wyślij bajt przez USART1 *************************************/
    int USART1_Transmit( unsigned char data ) 
    { 
     while ( !( UCSR1A & (1<<UDRE1)) );/* Wait for empty transmit buffer */ 
     UDR1 = data;/* Put data into buffer, sends the data */ 
     return 0; 
    } 
    /*********************************************************************/
    
    
    int main(void)
    {
    
     USART0_Init();
     USART1_Init();
    
     for(;;)
     {
      USART0_Transmit('A');
      USART1_Transmit('B');
      delayms(100);
     }
    }
    
    
  • REKLAMA
  • #3 5460512
    marek-72
    Poziom 11  
    dziekuje :)
    jeszcze nie testowalem ale w weekend sprobuje!

    pozdrowienia!
  • #4 5463998
    marek-72
    Poziom 11  
    postowalem...
    i prawie chodzi... :)
    ...tyle ze zamiast a lub b dostaje na rs'sie maczki
    a wlasciwie jeden ciag tego samego maczka.
    rs jest napewno dobrze podlaczony

    kod troszke zmodyfikowalem i w calosci jest taki:

    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <stdlib.h> 
    #include <math.h> 
    #include <avr/io.h> 
    
    #define F_CPU 14745660 //20000000 //18432000 //11059200 //3686400 //18432000  //14745600 
    #define CYCLES_PER_US (F_CPU/1000000) 
    
    /****** Funkcje delay *******************************************/ 
    void delay(unsigned int us) 
    { 
     unsigned int delay_loops; 
     register unsigned int  i; 
    
     delay_loops = (us+3)/5*CYCLES_PER_US; 
     for (i=0; i < delay_loops; i++) {}; 
    } 
    
    void delayms(unsigned int ms) 
    { 
     unsigned int i; 
    
     for (i=0;i<ms;i++) {delay(999); asm volatile ("WDR"::);} 
    } 
    /***************************************************************/ 
    
    /****** Inicjalizacja USART0 *****************************************/ 
    void USART0_Init( void ) 
    { 
     UBRR0H = 0; 
     UBRR0L = 47;      // 9600 bound 
     UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); 
     UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);  
    } 
    /*********************************************************************/ 
    
    /****** Inicjalizacja USART1 *****************************************/ 
    void USART1_Init( void ) 
    { 
     UBRR1H = 0; 
     UBRR1L = 47;      						// 9600 bound 
     UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 << TXEN1); 
     UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);  
    } 
    /*********************************************************************/ 
    
    /****** Wyślij bajt przez USART0 *************************************/ 
    int USART0_Transmit( unsigned char data ) 
    { 
     while ( !( UCSR0A & (1<<UDRE0)) );		// Wait for empty transmit buffer 
     UDR0 = data;							// Put data into buffer, sends the data 
     return 0; 
    } 
    /*********************************************************************/ 
    
    
    /****** Wyślij bajt przez USART1 *************************************/ 
    int USART1_Transmit( unsigned char data ) 
    { 
     while ( !( UCSR1A & (1<<UDRE1)) );	   	// Wait for empty transmit buffer 
     UDR1 = data;					   		// Put data into buffer, sends the data 
     return 0; 
    } 
    /*********************************************************************/ 
    
    
    /****** Odbierz bajt przez USART0 ************************************/ 
    int USART0_Receive( unsigned char data ) 
    { 
     while ( !( UCSR0A & (1<<RXC0)) );		// Wait for empty transmit buffer 
     return UDR0; 
    } 
    /*********************************************************************/ 
    
    
    /****** Odbierz bajt przez USART1 ************************************/ 
    int USART1_Receive( unsigned char data ) 
    { 
     while ( !( UCSR1A & (1<<RXC1)) );	   	// Wait for empty transmit buffer 
     return UDR1;
    } 
    /*********************************************************************/ 
    
    
    int main(void) 
    { 
    
     USART0_Init(); 
     USART1_Init(); 
    
     for(;;) 
     { 
      USART0_Transmit('a'); 
      USART1_Transmit('b'); 
      delayms(100); 
     } 
    } 



    w avr studio mam takie ustawienia:
    [Atmega128] PC <-> atmega128 2xRS232 w C

    a dostaje na rs'sie taka sieczke:
    [Atmega128] PC <-> atmega128 2xRS232 w C

    zmienilem ustawienia kwarca (na obudowie jest wytloczone 14745660). czy powinienem cos jeszcze zmienic w innych parametrach?

    Z gory serdecznie dziekuje za wskazowki.
  • #5 5464036
    snow
    Poziom 31  
    Wartość którą wpisujesz do UBBR1 i UBBR0 zmień na 95 albo przestaw prędkość transmisji w komputerze na 19200
  • REKLAMA
  • #6 5464145
    marek-72
    Poziom 11  
    Jestescie wielcy! dziala :)

    Dziekuje za pomoc.

    Milego weekendu wszystkim zycze!
  • #7 5464191
    snow
    Poziom 31  
    Nie my wielcy tylko ty leniwy - w PDF'ie było napisane :P
  • #8 5464742
    bobbyAIR
    Poziom 20  
    Jeszcze przy okazji warto albo obsłużyć przerwania od odbioru, albo je wyłaczyć.
  • #9 5466357
    marek-72
    Poziom 11  
    no tak... jak zwykle macie racje... ;)
    zaczalem sie troche bawic dzis kodem i doszedlem do tych przerwan odczytu... ale utknalem...

    dalem sei(); ale to nic nie zmienialo.

    teraz wszystko wyglada tak:

    
    #include <avr/interrupt.h> 
    #include <inttypes.h> 
    #include <stdlib.h> 
    #include <math.h> 
    #include <avr/io.h> 
    
    #define F_CPU  14745660 //20000000 //18432000 //11059200 //3686400 //18432000  //14745600 
    #define CYCLES_PER_US (F_CPU/1000000) 
    
    /****** Funkcje delay *******************************************/ 
    void delay(unsigned int us) 
    { 
     unsigned int delay_loops; 
     register unsigned int  i; 
    
     delay_loops = (us+3)/5*CYCLES_PER_US; 
     for (i=0; i < delay_loops; i++) {}; 
    } 
    
    void delayms(unsigned int ms) 
    { 
     unsigned int i; 
    
     for (i=0;i<ms;i++) {delay(999); asm volatile ("WDR"::);} 
    } 
    /***************************************************************/ 
    
    /****** Inicjalizacja USART0 *****************************************/ 
    void USART0_Init( void ) 
    { 
     UBRR0H = 0; 
     UBRR0L = 7;      // 115200 bound,  57600 bound - 15
     UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); 
     UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);  
    } 
    /*********************************************************************/ 
    
    /****** Inicjalizacja USART1 *****************************************/ 
    void USART1_Init( void ) 
    { 
     UBRR1H = 0; 
     UBRR1L = 95;      	// 9600 bound 
     UCSR1B = (1 << RXCIE1) | (1 << RXEN1) | (1 << TXEN1); 
     UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);  
    } 
    /*********************************************************************/ 
    
    /****** Wyślij bajt przez USART0 *************************************/ 
    int USART0_Transmit( unsigned char data ) 
    { 
     while ( !( UCSR0A & (1<<UDRE0)) );		// Wait for empty transmit buffer 
     UDR0 = data;							// Put data into buffer, sends the data 
     return 0; 
    } 
    /*********************************************************************/ 
    
    
    /****** Wyślij bajt przez USART1 *************************************/ 
    int USART1_Transmit( unsigned char data ) 
    { 
     while ( !( UCSR1A & (1<<UDRE1)) );	   	// Wait for empty transmit buffer 
     UDR1 = data;					   		// Put data into buffer, sends the data 
     return 0; 
    } 
    /*********************************************************************/ 
    
    
    /****** Odbierz bajt przez USART0 ************************************/ 
    unsigned char USART0_Receive(void) 
    { 
     while ( !( UCSR0A & (1<<RXC0)) );		
     return UDR0; 
    } 
    /*********************************************************************/ 
    
    
    /****** Odbierz bajt przez USART1 ************************************/ 
    unsigned char USART1_Receive(void) 
    { 
     while ( !( UCSR1A & (1<<RXC1)) );	   	 
     return UDR1;
    } 
    /*********************************************************************/ 
    
    
    void USART0_Text_Transmit (char *TXT) 
    { 
    while (*TXT) 
    USART0_Transmit (*TXT++); 
    }
    
    
    int main(void) 
    { 
    
     int i;
    
     USART0_Init(); 
     USART1_Init(); 
    
     sei();
    
     USART0_Text_Transmit("START");
     USART0_Transmit(10);
     USART0_Transmit(13);
    
    
     for(;;) 
     	{ 
    	char a;
    
    	a=USART0_Receive();
    	USART0_Text_Transmit("-->");
    	USART0_Transmit(a);
    	USART0_Transmit(10);
    	USART0_Transmit(13);
    
    	switch (a) 
    		{
    		case 'a':
    			USART0_Text_Transmit("Odczytalem a");
    			USART0_Transmit(10);
    			USART0_Transmit(13);
    			break;
    		case 'b':
    			USART0_Text_Transmit("Odczytalem b");
    			USART0_Transmit(10);
    			USART0_Transmit(13);
    			break;
    		}
    	
    	delayms(1000000); 
     	} 
    } 
    
    
    


    czytalem troche o USART w manualu i poprzerabialem troche funkcje na rozne sposoby ale z odczytem klapa.
    pomimo wlaczenia przerywan... odczyt nie dziala.

    potrzebuje odczytywac tylko USART0.
    UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); jest
    sei(); jest

    Czego nie zrobilem?

    moze jakas drobna wskazowka, please?
  • #10 5466433
    pubus
    Poziom 30  
    Jak już wcześniej kolega bobbyAIR zauważył aktywne jest przerwanie od odebrania danych/bajtu... RXCIE
    Ty uaktywniłeś globalne zezwolenie na przerwania...
    Dokumentację czytałeś ale coś jej nie rozumiesz...
    Dopisałeś funkcję które mają odbierać dane...
    Ale one czekają aż dane pojawią się w buforze...
    Odbieranie danych w przerwaniu z założenia ma przerwać program tylko w momencie gdy coś się pojawiło po czym do niego wrócić...
    Tak więc wypadało by napisać funkcję obsługi przerwania...
    
    ...
    volatile unsigned char byte=0;
    ...
    ISR (USART0_RX_vect) //wektory przerwań do znalezienia w dokumentacji winavr
    {
     byte = UDR0;
    }
    
  • #11 5466809
    marek-72
    Poziom 11  
    hm... cos chyba jest nie tak.
    probowalem usunac obsluge przerwan i odbior nie dzialal.
    przy wlaczonych przerwaniach dodalem dla obu uartow funkcje ktora podales i tez nic.
    dodalem wewnatrz tych funkcji jakies transmity na rs'a ale zadnego efektu nie bylo.

    znalazlem ten post Link i na jego wzor przerobilem kod, ale odbior dalej nie dziala.

    Co ciekawe, kiedy w glownej petli dodalem transmit '>' zeby widziec czy program dziala i kiedy nacisnalem kilka razy klawisz a, program sie zawieszal na kilkanascie sekund.

    Oczywiscie kabelki sprawdzilem;)

    Co jeszcze powinienem sprawdzic?

    Dodano po 3 [godziny] 49 [minuty]:

    dobra... w koncu mam!
    no i... po ewidentych brakach w kodzie ostatnim problemem byla wlaczona HW kontrola w terminalu.
    po wylaczeniu odbior zaczal dzialac prawidlowo.

    uff....

    WIELKIE DZIEKI wszystkim za cierpliwosc i pomoc

    hej!
  • #12 5468299
    bobbyAIR
    Poziom 20  
    Wektorów przerwań szuka sie nie tyle w dokumentacji winavr co w dokumentacji kontrolera, który się programuje. Nazwa wektora to nazwa przerwania ze spacjami zastąpionymi podkreślnikiem i dodanym przyrostkiem _vect np przerwanie od przepełnienia timera 1 w atmega 32:
    w dokumetnacji sekcja Interrupts (str. 42)
    10 $012 TIMER1 OVF Timer/Counter1 Overflow

    nazwa wektora więc brzmi:
    TIMER1_OVF_vect
  • REKLAMA
  • #13 5468329
    pubus
    Poziom 30  
    No tu bym się kłócił...
    Nazwa wektora jest też zależna od wersji winavr...
    W dokumentacji są podane dodatkowo stare nazwy wektorów...
    Radzę zaglądnąć...
  • #14 5469325
    bobbyAIR
    Poziom 20  
    Nie wersji winavr tylko avrlibc - nie każdy musi mieć Wingrozę na PC. Zgadza się, że w starej był bałagan dlatego nowsze wersje (a o takich mówię, chyba, że ktoś woli korzystać ze starych) mają to ujednolicone i zgodne z dokumentacją a nie pomysłowością nazewniczą twórców biblioteki.
REKLAMA