- 12V Akku mit 280 Ah bauen         
Seite 1 von 6 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 53

Thema: USART - WARUM GEHT ES NICHT? - BITTE HELFT MIR

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795

    USART - WARUM GEHT ES NICHT? - BITTE HELFT MIR

    Anzeige

    Powerstation Test
    Hallo,

    Ich bin am verzweifeln!

    Ich will dass mein ATmega8535 signale per USART empfängt.

    Der USART ist ja im prinzip so easy, aber trotzdem bekomm ich es nicht hin, die Signale zu empfangen, ich verstehs nicht warum!

    Zunächst mal zum programm.

    Ich benutze externe c-files um bestimmt Funktionen einfacher in Projekten einzubinden.

    Daher sind auch die USART-Funktionen in der usart.c:





    Code:
    /******************************************************************************/
    /******************************* Kaiser Franz *********************************/
    /******************************************************************************/
    
    #include "usart.h" 
    
    #define F_CPU 7372800
    #define USART_BAUD_RATE 115200 
    #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1) 
    
    
    // USART - FUNKTIONEN
    //===============================================
    
    void USART_init(void){  
    
        UBRRL |= (uint8_t) USART_BAUD_SELECT; 
    	
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    
    
    } 
    
    void USART_transmit(uint8_t c){ 
       while(!(UCSRA & (1<<UDRE)));
       UDR = c; 
    } 
    
    void USART_transmit_string(uint8_t *string){ 
        while(!(UCSRA & (1<<UDRE)));
    	while( *string){ USART_transmit (*string++); }
    }
    
    void USART_transmit_bin(uint8_t c){ 
    
    if( c & (1<<7) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<6) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<5) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<4) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<3) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<2) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<1) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    if( c & (1<<0) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
    
    }

    Wichtig hier ist ja eigentlich nur das USART_init():

    Code:
    void USART_init(void){  
    
        UBRRL |= (uint8_t) USART_BAUD_SELECT; 
    	
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    
    
    }

    Hier noch die main.c:

    Code:
    /****************************************************************************/
    //
    //	   Programmname		   : USART
    //
    //	   Chip type           : ATmega8535
    //	   Clock frequency     : 7,3728 MHz
    //
    //****************************************************************************/
    
    
    // INCLUDE & DEFINE
    //=============================================================================
    
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    
    #include <usart.h> 
    
    
    // HAUPTFUNKTION
    //=============================================================================
    int main (void)
    {
    // D A T E N R I C H T U N G :
    //===============================================
    
    //	PORTA Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRA   = 0b11111111;	//
        PORTA  = 0b00000000;	// 
    
    //	PORTB Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )	
        DDRB   = 0b00000000;	//
    	PORTB  = 0b00000000;	//
    	
    //	PORTC Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRC   = 0b00000000;	//
    	PORTC  = 0b11111111;	//
    	
    //	PORTD Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRD   = 0b00000000;	//
    	PORTD  = 0b00000000;	//
    	
    	
    // Interrupts freigeben:
    //===============================================
    sei();  
     
     
    // Funktionen:
    //===============================================  
    
    
    SIGNAL( SIG_USART_RECV ) 
    { 
       uint8_t data; 
       data = UDR; 
        
       /* echo */ 
       USART_transmit(data); 
    
    } 
    
    
     
    // Initialisieren:
    //=============================================== 
    USART_init();
    USART_transmit_string("USART Init \r");
    
    uint8_t x;
    
    // Hauptschleife
    //=============================================================================
    while (1) { 
    
    
    if (bit_is_clear (PINC, PINC0) & (x == 0)) {
    
    	USART_transmit_string("PIND 0 getippt   ");
    	
    x=1;
    }
    
    if (bit_is_clear (PINC, PINC7)){ x=0; }
    
    
    PORTA = UCSRA;
    }
    }
    mit USART_transmit_string(" BLABLA "); sende ich... da gab es nochnie Probleme damit....

    aber nun will ich Empfangen und habe einfach mal das hier geschrieben:

    Code:
    // Interrupts freigeben:
    //===============================================
    sei();  
     
     
    // Funktionen:
    //===============================================  
    
    
    SIGNAL( SIG_USART_RECV ) 
    { 
       uint8_t data; 
       data = UDR; 
        
       /* echo */ 
       USART_transmit(data); 
    
    }
    Damit sollte er die Daten Empfangen und gleich wieder weitersenden.



    SO, nun zu dem was passiert, (bzw. nicht passiert):

    Ich schalte ein:

    es wird vom MCU gesendet: USART Init.

    UCSRA wird ja an PortA ausgegeben,
    nun Leuchtat da :
    TXC = USART Transmit Complete
    UDRE = USART Data Register Empty



    Jetzt sende ich an den MCU, irgend EIN zeichen:

    an UCSRA sind alle Bits LOW,
    Der MCU reagiert nicht mehr, auch nicht auf meine Tastenbefehle auf PORTC...

    An was kann das liegen? bitte helft mir.

    Ich habe 3 Testboards, an allen ist das Selbe. Leitungsfehler kann man ausschließen....
    Gruß,
    Franz

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.08.2005
    Ort
    49.80248 8.59252
    Alter
    39
    Beiträge
    172
    Dein Problem liegt hier:
    Code:
    SIGNAL( SIG_USART_RECV )
    {
       uint8_t data;
       data = UDR;
       
       /* echo */
       USART_transmit(data);
    
    }
    Du versuchst aus einer INT routine heraus USART_transmit aufzurufen. Diese Funktion wartet auf einen INT bis Platz ist ein Zeichen zu senden. Aber die INTs sind dekativiert wenn du in der Routine bist. Also wartet es ewig.
    Die Loesung waere USART_transmit im normalen Programm aufzurufen.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795
    Hallo kater,

    Vielen Dank für deine Antwort!

    Ich habe deinen Rat befolgt un habe die datei in eine Variable gespeichert.

    Zur übersicht habe ich einen neue main.c File geschrieben in der alles enthalten ist was ich einsetze:

    Code:
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    
    #define F_CPU 7372800 
    #define USART_BAUD_RATE 115200 
    #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1) 
    
    
    
    void USART_init(void){  
    
        UBRRL |= (uint8_t) USART_BAUD_SELECT; 
    	
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    
    
    } 
    
    void USART_transmit(uint8_t c){ 
       while(!(UCSRA & (1<<UDRE)));
       UDR = c; 
    } 
    
    void USART_transmit_string(uint8_t *string){ 
        while(!(UCSRA & (1<<UDRE)));
    	while( *string){ USART_transmit (*string++); }
    }
    
    
    uint8_t data;
    
    SIGNAL( SIG_USART_RECV ) 
    { 
        
       data = UDR;  
    
    } 
    
    
    int main (void)
    {
    // D A T E N R I C H T U N G :
    //===============================================
    
    //	PORTA Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRA   = 0b11111111;	//
        PORTA  = 0b00000000;	// 
    
    //	PORTB Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )	
        DDRB   = 0b00000000;	//
    	PORTB  = 0b00000000;	//
    	
    //	PORTC Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRC   = 0b00000000;	//
    	PORTC  = 0b11111111;	//
    	
    //	PORTD Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRD   = 0b11111111;	//
    	PORTD  = 0b00000000;	//
    	
    	
     sei();
     
    USART_init();
    USART_transmit_string("USART INIT - OK  ");
     
     
    while (1) { 
    
    PORTA = UCSRA;
    PORTD = data;
    
    }
    }
    Leider tritt noch immer das selbe Problem auf.

    Das will einfach nicht [-(

    Ich kann mir das nicht erklären.... Bitte helft mir.
    Gruß,
    Franz

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Du mußt "data" auf jeden Fall volatile definieren
    volatile static uint8_t data;
    Sonst haben die signal-routine und "main" verschiedene "data"
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795
    Hallo,

    Danke für deine Antwort...

    Leider immer noch das selbe Spiel...


    Code:
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    
    #define F_CPU 7372800 
    #define USART_BAUD_RATE 115200 
    #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1) 
    
    
    
    void USART_init(void){  
    
        UBRRL |= (uint8_t) USART_BAUD_SELECT; 
    	
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    
    
    } 
    
    void USART_transmit(uint8_t c){ 
       while(!(UCSRA & (1<<UDRE)));
       UDR = c; 
    } 
    
    void USART_transmit_string(uint8_t *string){ 
        while(!(UCSRA & (1<<UDRE)));
    	while( *string){ USART_transmit (*string++); }
    }
    
    
    volatile static uint8_t data;
    
    SIGNAL( SIG_USART_RECV ) 
    { 
        
       data = UDR;  
    
    } 
    
    
    int main (void)
    {
    // D A T E N R I C H T U N G :
    //===============================================
    
    //	PORTA Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRA   = 0b11111111;	//
        PORTA  = 0b00000000;	// 
    
    //	PORTB Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )	
        DDRB   = 0b00000000;	//
    	PORTB  = 0b00000000;	//
    	
    //	PORTC Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRC   = 0b00000000;	//
    	PORTC  = 0b11111111;	//
    	
    //	PORTD Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRD   = 0b11111111;	//
    	PORTD  = 0b00000000;	//
    	
    	
     sei();
     
    USART_init();
    USART_transmit_string("USART INIT - OK  ");
     
     
    while (1) { 
    
    PORTA = UCSRA;
    PORTD = data;
    
    }
    }
    Gruß,
    Franz

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Du, ich stelle da mal ein zip mit einem gcc-projekt im Entwicklungs-Stadium rein. das tut eigentlich nix, außer daß es jede sekunde mal zum Terminal eine Text schickt, und wenn man dort ein "L" eingibt, brint er den text "left", sonst "right".
    Also absolut geistlos, aber das Uart-Zeugs funktioniert.
    (Senden und Empfangen ist beide gepuffert und mit interrupt)

    Schau die alles an, was irgendwie "usart" heißt, vielleicht fällt dir ja selbst was auf.
    Angehängte Dateien Angehängte Dateien

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Was mit auffällt:
    -1- sei() sollte nach USART_init() stehen.
    -2- UBRRL = (uint8_t)... und nicht |=
    -3- UBRRH = 0; fehlt
    -4- am Ende von USRT_init() UDR auslesen um evtl undefinierten Zustand zu beheben. zB data = UDR.
    Disclaimer: none. Sue me.

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795
    Vielen Dank für die große Hilfe!

    Tatsächlich lag es daran dass "sei();" nach "USART_init();" gehört,

    Also am besten hirekt vor der Hauptschleife "while(1){}"

    EDIT: Das ist mir auch im beispiel von PicNick aufgefallen...


    Code:
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    
    #define F_CPU 7372800 
    #define USART_BAUD_RATE 115200 
    #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1) 
    
    volatile static uint8_t data;
    
    void USART_init(void){  
    
    	UBRRH = 0;
        UBRRL = (uint8_t) USART_BAUD_SELECT; 
    	
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    
    	data = UDR;
    
    } 
    
    void USART_transmit(uint8_t c){ 
       while(!(UCSRA & (1<<UDRE)));
       UDR = c; 
    } 
    
    void USART_transmit_string(uint8_t *string){ 
        while(!(UCSRA & (1<<UDRE)));
    	while( *string){ USART_transmit (*string++); }
    }
    
    
    
    
    SIGNAL( SIG_USART_RECV ) 
    { 
        
       data = UDR;  
    
    } 
    
    
    int main (void)
    {
    // D A T E N R I C H T U N G :
    //===============================================
    
    //	PORTA Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRA   = 0b11111111;	//
        PORTA  = 0b00000000;	// 
    
    //	PORTB Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )	
        DDRB   = 0b00000000;	//
    	PORTB  = 0b00000000;	//
    	
    //	PORTC Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRC   = 0b00000000;	//
    	PORTC  = 0b11111111;	//
    	
    //	PORTD Pin: 76543210	  ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
        DDRD   = 0b11111111;	//
    	PORTD  = 0b00000000;	//
    	
    	
    
     
    USART_init();
    USART_transmit_string("USART INIT - OK  ");
     
     sei();
     
    while (1) { 
    
    PORTA = UCSRA;
    PORTD = data;
    
    }
    }

    An dieser Stelle hätte ich noch eine kurze Frage;

    Wenn ich ein signal empfange, dann führt der MCU die Interruptroutine aus, aber er sendet auch wieder "USART INIT - OK",

    Er führt also die main-Funktion von anfang an wieder aus...

    dachte immer Interrupts "stoppen" das programm an der aktuellen stelle, Frühren die Interruptroutine aus, und machen dort weiter wo sie aufgehört haben....?

    Das ist jetzt mei mir nicht so...

    Könntet ihr mich da kurz aufklehren..?
    Gruß,
    Franz

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    hmmm ist wohl noch die alte Quelle.

    ::Edit::

    sorry, lag an meine Brauser-Cache
    Disclaimer: none. Sue me.

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795
    Wie meinst du das?
    Gruß,
    Franz

Seite 1 von 6 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests