-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Probleme mit UART und ATmega168, Dringend!

  1. #1

    Probleme mit UART und ATmega168, Dringend!

    Anzeige

    Hallo
    Ich muss um eine Projektarbeit fertigstellen zu können endlich den ATmega-168 mit meinem PC verbinden und Werte auf den Schirm senden. Also ich habe folgende Software im AVR:

    Code:
    //uart_tx:
    // 	-Bedienen des UART-Hardware Modules
    // 	-Hardware: -UART
    //*********************************************************************************************
    
    #include <avr/io.h>
    #include "uart_tx.h"
    #include "avr/interrupt.h"
    #include "stdlib.h"
    
    #define F_CPU 8000000L
    #define BAUD 9600L
    
    // Berechnungen
    #define UART_UBRR_CALC ((F_CPU)/((BAUD)*16L)-1) 
    
    //local
    volatile uint8_t data;
    
    //uart_init, Initialisiere UART
    
    void uart_tx_init(){
    	
        UCSR0B |= (1<<TXEN0) | (1 << TXCIE0);                // UART TX einschalten
        UCSR0C |= (1<<UMSEL00)|(0<<UMSEL01);    // Asynchron 8N1 
        
     
     	UBRR0H =(uint8_t)(UART_UBRR_CALC>>8); //set baudrate
     	UBRR0L = UART_UBRR_CALC & 0xFF; 
    
    
    }
    
    /* SENDEN*/
    
    //uart_tx sendet ein Zeichen, uart_txs ein String, uart_txs_var einen ASCII Zeichensatz
    
    void uart_tx(uint8_t c) {
        
        SREG |= (0 << 7);
        data=c ;
        SREG |= (1 << 7);
     
        
    }
    
    
    
    
    //String senden
    void uart_txs(uint8_t *s) {
       	while (*s)
       	{   // so lange *s != '\0' also ungleich dem "String-Endezeichen" 
       	    uart_tx(*s);
       	    s++;
       	}
       	
    }
    
    
    //Integer zu ASCII (Zeichen)
    void uart_txs_var(uint16_t i){
      char s[7];
      	i = -12345;
    
       	itoa( i, s, 10 ); // 10 fuer radix -> Dezimalsystem
       	uart_tx(*s);
       	
    }
    
    ISR(USART_TX_vect){
    	UDR0 = data ;
    }
    Das Headerfile:

    Code:
    #ifndef uart_tx_H_
    #define uart_tx_H_
    
    void uart_tx_init();
    void uart_tx(uint8_t c);
    void uart_txs (uint8_t *s);
    void uart_txs_var(uint16_t i);
    
    #endif /*uart_tx_H_*/
    Und im Main sieht das ganze mit dm Befehl so aus:

    Code:
    #include <avr/io.h>
    #include "uart_tx.h"
    #include "alog_digi.h"
    #include "send.h"
    
    
    
    int main(void) {
    	
    	
    //Init	
    	void ir_mod_init();
    	void uart_tx_init();
    	void alog_digi_init();
    	
    //Hauptschleife
    	while(1) {
    	uart_tx('v');
    		//send();
    
    	return 0;	
    	}
    }

    Auf dem Pc verwende ich Linux, angezeigt wird mit dem Minicom, die Baud ist korrekt auf 9600 eingestellt und der Port ttyS0 (RS232 Serieller Port) ist freigeschaltet. langsam verzweifle ich, da es Partout nicht funktionieren will. (Soll heissen ich habe auf dem Minicom keinerlei Reaktion.

    Hat irgendwer ne Idee?

    Danke
    Gruss Nils Wenzler

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.186
    Ich würde sagen dein UCSRC Register stimmt nicht
    UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01); sollte das nicht so aussehen

  3. #3
    Danke viel mals!!!
    Das ist ein Anfang!
    Allerdings bekomme ich jetzt erst "Rubish" auf den Schirm...
    Gibt es einen Fehler beim Senden, beim umrechnen in ASCII Zeichen oder so?
    Probiert habe ich zb folgenden Befehl:
    uart_tx('v');
    uart_txs_var('v');
    und das ganze noch mit 8-bit integern. Es kommt immer nur "Datenmüll auf dem Schirm an.)
    (Irgendwas mit der Baud-Berechnung falsch o.ä?
    Gruss Nils

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Uh, das stimmt aber einiges nicht....
    Das UCSRC-Register brauchst Du gar nicht anzupacken. Das steht in der Grundeinstellung schon auf Asynchron 8N1

    Dein schlimmster Fehler ist es, das Senden über einen Interrupt machen zu wollen.
    Deine uart_tx() kann so nicht funktionieren.

    SREG |= (0 << 7);
    Diese Zeile macht gar nix. Du veroderst das Global Interrupt Enable Bit mit 0 - völlig nutzlos. Wieso willst Du hier das Bit überhaupt anpacken?

    Die Interruptroutine, in der Du das UDR-Register beschreibst, wird erst dann ausgeführt, wenn ein Byte gesendet wurde. Du beißt Dir hier also in den eigenen Schwanz. Der Interrut ist nicht dazu gedacht, eine Senderoutine aufzubauen, sondern um eine Reaktion auf ein gesendetes Byte zu generieren.

    Kurz und bündig: Um Deine Sendung zum laufen zu bringen, müsste Deine uart_tx() einfach so aussehen:
    Code:
    void uart_tx(uint8_t c) {
        UDR0 = c ;
    }
    Und lass die Interrupts ausgeschaltet - zum Senden brauchst Du die nicht.

    askazo

  5. #5
    ok gemacht... allerdings kommt immer noch nur Datenmüll

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Dann müsstest Du noch mal Deine Baudratenberechnung überprüfen - obwohl die eigentlich korrekt aussieht. Arbeitest Du mit internem Takt? Der kann durchaus schon mal ein ganzes Stück daneben liegen. Dann müsstest Du mal versuchen, den Wert für das UBRR0 Register manuell anzupassen und ein paar Werte nach oben bzw. unten korrigieren. Wenn Du ein Oszilloskop zu Hand hast, kannst Du das ganze auch mal nachmessen - würde die Sache sehr vereinfachen.

    Eins habe ich noch vergessen: Ganz korrekt müsste die Senderoutine so aussehen. Eventuell ist das schon der Grund für Deinen Datenmüll:
    Code:
    void uart_tx(uint8_t c) {
    while ( !(UCSR0A & (1<<UDRE0)) ) //warte, bis Senderegister leer ist
        UDR0 = c ; //senden
    }
    askazo

  7. #7
    Also:
    Der Code müsste jetzt korrekt sein. Ein Kollege hat ihn so getestet.
    Allerdings habe och wohl noch n Hardware Problem! Das ganze sendet nur (Datenmüll) wenn ich den Pin mit dem Stecker des RS232 Kabels Berühre...
    Ich bin echt am Verzweifeln...
    Nun dachte ich das es an einem ungenauen internen Oszi liegt (8mhz), un dbin mittlerweile auf 1200 Baud runter, wo es auch mit dem gehen sollte...?
    Gruss nils

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    33
    Beiträge
    240
    Hallo

    Also ich hatte auch immer das Problem mit dem Datenmüll... bei mir lag es nach einigen anderen Fehlern auch noch an der Einstellung der Fusebits. Also der Einstellung des Taktes. Versuch erstmal die definitiv richtig zu stellen bevor Du die Baudrate runter drehst. 9600B sollten kein Problem sein. Was verwendest Du denn für einen Takt? Würde Dir empfehlen einen externen zu verwenden. Geht aber normal auch mit den internen.

    Grüße!!

    Bean

  9. #9
    Im datenblatt ist angegeben das er mit 8mhz internem Takt ausgeliefert wird. Damit betriebe ich ihn auch... Also ich habe nichts verstellt.
    Auf was deutet denn das " Senden nur wenn man sozusagen einen Wackelkontakt am Pin generiert (immer wieder berühren)" hin?
    Gruss Nils

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    Im datenblatt ist angegeben das er mit 8mhz internem Takt ausgeliefert wird.
    Es steht aber noch da, daß er mit einem /8 Teiler ausgeliefert wird
    Software is like s e x: its better when its free.
    Linus Torvald

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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