-         

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

Thema: Problem mit dem senden von Zeichen per UART

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.08.2007
    Ort
    Delmenhorst
    Alter
    32
    Beiträge
    731

    Problem mit dem senden von Zeichen per UART

    Anzeige

    Hi

    Ich habe das myAVR 2 USB Board.
    Nun möchte ich ein Zeichen vom PC an den Mikrocontroller senden und je nach Zeichen soll reagiert werden.
    Nur kommen die Zeichen leider ganz anders an als sie sollen.
    Die mitgelieferten Beispiel Programme funktionieren auch nicht.

    Mein Testprogramm:

    Code:
    #define F_CPU 3686400
    #include <avr\io.h>
    #include <util\delay.h>
    #include	<avr/io.h>
    void uartPutString(char *buffer);
    //----------------------------------------------------------------------
    void uartInit()
    {
    	UBRRL = 23;       		//9600Baud siehe Baudratentabelle
    	UCSRB = 8 + 16;         //Sender enable, Empfänger enable
    }
    //----------------------------------------------------------------------
    char uartGetChar()
    {
    	char data=0;
    	//warte bis RX-complete
    	while (!(UCSRA&128));
    	//empfangen
    	data=UDR;
    	return data;
    }
    //----------------------------------------------------------------------
    void uartPutChar(char data)
    {
    	//warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
    	while (!(UCSRA&32));
    	//sende
    	UDR=data;
    }
    //----------------------------------------------------------------------
    main ()
    {
    	DDRB = 0xFF;
    	PORTB = 0xFF;
    	_delay_ms(500);	
    	PORTB = 0x00;
    
    	char zeichen;
    
    	uartInit();
    	while (true) // Mainloop
    	{
    		zeichen=uartGetChar();
    
    		PORTB = (1<<PINB1);
    		_delay_ms(500);	
    		PORTB = (0<<PINB1);
    		_delay_ms(500);	
    
    		if(zeichen=='0')
    			PORTB = (0<<PINB0);
    		if(zeichen=='1')
    			PORTB = (1<<PINB0);
    
    		_delay_ms(500);	
    	}
    }
    Durch die LED an PINB1 kann ich sehen das etwas angekommen ist, aber es ist nicht das was es soll.

    Ich habe schon die Baudraten 2400, 9600 und 115200 ausprobiert.
    Zum senden bzw. empfangen benutze ich HTerm.

    Und wie gesagt, mit den mitgelieferten Beispielprogramm welches ein String an den PC senden soll klappt es auch nicht! Es kommt zwar ein String auf dem PC an aber das ist nur Zeichensalat...

    Was kann ich noch probieren?

    gruß

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Am besten, du siehst dir das genau an,
    http://www.roboternetz.de/wissen/ind...RT_mit_avr-gcc
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.08.2007
    Ort
    Delmenhorst
    Alter
    32
    Beiträge
    731
    Werd ich tun.

    Es muss doch aber auch mit den Beispielprogrammen funktionieren!
    Wo kann da der Fehler noch liegen?

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Das ist c-mässig ein Stiefel, auch wenn es scheinbar funktioniert;
    if(zeichen=='0')
    PORTB = (0<<PINB0);

    Ein Bit löschen geht so
    PORTB &= ~(1<<PINB0);


    Du solltest, so wie in der Wikil, für die Register-Bits die korrekten Symbole verwenden

    sowas ist pfui gack:
    UBRRL = 23; //9600Baud siehe Baudratentabelle
    UCSRB = 8 + 16; //Sender enable, Empfänger enable

    Besser:
    Code:
        uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
     
        UBRRH = (uint8_t) (ubrr>>8);
        UBRRL = (uint8_t) (ubrr);
     
        // UART Receiver und Transmitter anschalten 
        // Data mode 8N1, asynchron 
        UCSRB = (1 << RXEN) | (1 << TXEN);
        UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);

    Noch was: Bevor "Hello, world" nicht geht, ist an empfange nicht zu denken

    http://www.roboternetz.de/wissen/ind...lo.2C_world.29
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.08.2007
    Ort
    Delmenhorst
    Alter
    32
    Beiträge
    731
    Nun kommt was anderes an, aber immernoch nicht das richtige...

    Mein Programm:

    Code:
    #define F_CPU 3686400
    #include <avr\io.h>
    //----------------------------------------------------------------------
    void uartInit()
    {
    	uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*9600) - 1); 
      
        UBRRH = (uint8_t) (ubrr>>8); 
        UBRRL = (uint8_t) (ubrr); 
      
        // UART Receiver und Transmitter anschalten 
        // Data mode 8N1, asynchron 
        UCSRB = (1 << RXEN) | (1 << TXEN); 
        UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); 
    }
    //----------------------------------------------------------------------
    void uartPutChar(char data)
    {
    	//warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
    	while (!(UCSRA&32));
    	//sende
    	UDR=(uint8_t)data;
    }
    //----------------------------------------------------------------------
    void print(char buffer[])
    {
    	for (int i=0;buffer[i]!=0;i++)
    		uartPutChar(buffer[i]);
    }
    //======================================================================
    main ()
    {
    	uartInit();
    	while (true) // Mainloop
    	{
    		print("x");
    	}
    }

    Edit:
    Ich habe das Beispiel aus der Wiki übernommen (die ohne Interupts):

    Code:
    #define 	F_CPU 3686400	// Taktferquenz des myAVR-Boards
    #include	<avr\io.h>		// AVR Register und Konstantendefinitionen
    #include	<util\delay.h>
    
    void uart_init()
    {
    	uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*9600) - 1);
    
    	UBRRH = (uint8_t) (ubrr>>8);
    	UBRRL = (uint8_t) (ubrr);
    
    	// UART Receiver und Transmitter anschalten 
    	// Data mode 8N1, asynchron 
    	UCSRB = (1 << RXEN) | (1 << TXEN);
    	UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
    
    	// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) 
    	do
    	{
    		UDR;
    	}
    	while (UCSRA & (1 << RXC));
    }
    
    int	uart_putc (const uint8_t c)
    {
    	// Warten, bis UDR bereit ist für einen neuen Wert 
    	while (!(UCSRA & (1 << UDRE)))
    		;
    
    	// UDR Schreiben startet die Übertragung 
    	UDR = c;
    
    	return 1;
    }
    
    uint8_t	uart_getc_wait()
    {
    	// Warten, bis etwas empfangen wird 
    	while (!(UCSRA & (1 << RXC)))
    		;
    
    	// Das empfangene Zeichen zurückliefern 
    	return UDR;
    }
    
    int	uart_getc_nowait()
    {
    	// Liefer das empfangene Zeichen, falls etwas empfangen wurde; -1 sonst 
    	return (UCSRA & (1 << RXC)) ? (int) UDR : -1;
    }
    
    //----------------------------------------------------------------------
    main ()						// Hauptprogramm, startet bei Power ON und Reset
    {
    	uart_init();
    
    	//...					// hier Init-Code eintragen
    	do 
    	{
    		// Schleifenanfang Mainloop
    		uart_putc('x');
    		_delay_ms(50);
    	}
    	while (true);			// Schleifenende Mainloop
    }
    Aber immernoch das selbe Ergebnis.

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    wie sind die Fusebits gesetzt?

    Gruß

    Jens

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.08.2007
    Ort
    Delmenhorst
    Alter
    32
    Beiträge
    731
    So sind sie gesetzt:
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken fuses_221.jpg  

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    wenn ich das richtig sehe, hast du den internen Oszillator mit 4Mhz aktiviert. Aber rechne ruhig noch einmal mit deinen binären Werten nach.

    FuseCalculator

    Gruß

    Jens

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.08.2007
    Ort
    Delmenhorst
    Alter
    32
    Beiträge
    731
    Hab schon andere ausprobiert
    Bin jetzt auf "Ext Crsytal.... 1k ck+64ms.."

    Die Ausgabe ist nun anders aber immernoch nicht korrekt...
    Auf dem Board sitzt ein 3,6864MHz Oszilator.

    Edit:
    Wenn ich ne Null an den PC sende bekomm ich auch ne 00, wenn ich was anderes sende bekomm ich immer C0

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    es hilft nichts, andere Fusebits zu probieren. Es helfen nur die richtigen.

    Ändere
    Code:
       uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*9600) - 1);
    in

    Code:
       uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*9600UL) - 1);
    Gruß

    Jens

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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