- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Zahlen > 8bit über UART senden und enpfangen?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    16.12.2006
    Beiträge
    10

    Zahlen > 8bit über UART senden und enpfangen?

    Hallo zusammen!

    Hab schon einige Beträge hier zu UART gelesen, mein Problem hab ich aber noch nicht gefunden:
    Ich habe zwei Atmegas über UART verbunden was auch funktioniert, wenn ich Zahlen <255 verschicke.
    Wie kann ich jetzt am geschicktesten eine 16 oder 32 bit Zahl senden und vom anderen Contoller empfangen?
    Die UDR Register können nur 8bit aufnehmen, oder? und erwarten als Variablentyp ein unsigned char.

    Grüße

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2004
    Ort
    Karlsruhe
    Beiträge
    223
    du musst halt die Zahl in einzelne Bytes zerlegen. Wie du das dann genau aufbaust bleibt dir überlassen -- es muss schließlich nur auf beiden Seiten die gleiche Form haben.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    16.12.2006
    Beiträge
    10
    kannst du mir nen kleinen Einstieg / Beispiel geben wie man das in C macht?

    Und wie kann ich beim Empfangen unterscheiden welches Byte wohin gehört?

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    25.03.2006
    Ort
    Darmstadt
    Alter
    33
    Beiträge
    522
    Zitat Zitat von Karl Napf
    Und wie kann ich beim Empfangen unterscheiden welches Byte wohin gehört?
    In dem Du ein Übertragungsprotokoll festlegst. Am einfachste geht das so:
    zuerst schickst Du ein bestimmtes byte, an dem der Empfänger erkennt, dass gleich eine Zahl übertragen wird. Das byte kann z.b. eine 0x02 sein. Danach überträgst Du die Variable als ein Hex-Wert mit ASCI-Zeichen. Da die einzelnen Zeichen alle einen Wert über 0x02 haben, ist eine Verwechselung mit dem Startbyte 0x02 ausgeschlossen. Danach sendest Du ein Abschlussbyte, z.b. 0x04, was das Ende der Übertragung signalisiert. Letzteres kann aber auch wegfallen. Der Empfänger muss jetzt warten, bis das Startbyte bei ihm ankommt. Dann weiss er, dass die nächsten 4 bzw 8 Bytes eine Zahl sind, empfängt diese und wandelt sie in einen 16/32bit wert um.

    MfG Mark

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    16.12.2006
    Beiträge
    10
    Ich will z.B eine Zahl wie 43692 übertragen.
    Das mit dem Zerlegen in Bytes hab ich hingekriegt
    könnte so ausehen:

    int16_t Value
    ((Value >> 8) & 0xFF);
    ((Value >> 0) & 0xFF);

    Aber wie kann ich die 2 Bytes beim Empfangen wieder zu ordnen. Muss ich ein Bit von dem jeweiligen Byte für die Zuordnung reservieren und das dann abfragen?
    Geht's nicht irgendwie einfacher oder gibt's was fertiges?

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2004
    Ort
    Karlsruhe
    Beiträge
    223
    du hast eine serielle Verbindung die auf 8 bit Werten basiert. Du wirst also immer irgendein Protokoll machen müssen -- z.b. könnstest du über eine GPIO-Verbindung ein Handshaking machen und dann einfach n Werte in festgelegter Reihenfolge und Form übertragen. Oder du nimmst 7 bit und das 8. bit also Statusbit (z.b. um die Zahl als solche zu markieren, oder in einen Kommandomodus umzuschalten).

    Was du jetzt genau mit dem "zuordnen" am Empfänger meinst ist mir aber nicht wirklich klar ... du musst halt dein Protokoll dekodieren.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    16.12.2006
    Beiträge
    10
    mit zuordnen mein ich wenn mein UART zwei 8bit Werte nacheinader empfängt und ich sie danach zu einer 16bit Zahl zusammen fügen will muss ich doch wissen welches das high Byte und welches das low Byte ist.
    Kannst du mir die zweite Möglichkeit ein bißchen genauer erklären, hab von "Bussystemen" leider wenig Ahnung und wie man das in C implementiert ist mir auch nicht.

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2004
    Ort
    Karlsruhe
    Beiträge
    223
    na ja, du kannst z.b. zwei GPIOs miteinander verbinden. Auf dem Sender ist das dann ein Ausgang, beim Empfänger ein Eingang. Wenn du jetzt beispielsweise eben den Pin auf 1 ziehst bedeutet das "jetzt kommt ein 16bit Wert" und hast vorher verbindlich festgelegt dass das MSB zuerst kommt. Dann sendest du die zwei Bytes und macht den Pin wieder aus.

    Wenn du ohne sowas auskommen willst kannst du eben einfach erst 7 bit schicken und verbindlihc vereinbaren dass wenn das 8. bit aus ist dass das MSB ist. Dann schickst du das LSB und machst das 8. bit an. Allerdings verlierst du damit 2 bit aus deiner 16bit Zahl, d.h. du kannst so nur 14 bit übertragen.

    Aber ich versteh dein Problem sowieso nicht ganz: du musst einfach nur _vorher_ verbindlich für _beide_ Seiten festlegen wie die Reihenfolge ist. Du musst halt darauf achten dass beide Controller synchronisiert sind. Wie z.b. mit der GPIO-Methode, oder du musst das über eine Startup condition machen. Oder du schickst nach dem Einschalten einfach mal 20 Nullbytes und vereinbarst dass nach mehr 20 Nullbytes mit einem darauffolgenden 0xff die Synchronisation anfängt.

    Es gibt da quasi beliebig viele Möglichkeiten.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    16.12.2006
    Beiträge
    10
    ich hab's jetzt mal so probiert:
    hab außer RXD und TXD noch eine Verbindung zwischen den beiden Contoller hergestellt.
    Jetzt setze ich den einen Pin high und der Sender soll das erste Byte schicken. Danach wieder low und beim 2. high soll er das 2. Byte schicken (der Sender zählt die Anzahl der highs/ Impulse mit).
    Das funktioniert so aber nicht, mein Display zeigt die beiden Werte abwechseln an.

    Code vom Sender:

    Code:
    void uart_putc(unsigned char zahl)
    {
        while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
        {
        }
        UDR = zahl;                      /* sende Zeichen */
    }
    int main(void)
    {
    		//Steuerleitung
    		DDRA  &= ~(1<<DDA6);		//Eingang
    		
    		//init UART
    		UBRRH  = 0;                             // Highbyte ist 0
    		UBRRL  = 3;                            // Lowbyte ist 51
    		UCSRB |= (1<<TXEN);		//auf senden gestellt
    		UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); 
    		
    		unsigned char Bsp1 = 43;
    		unsigned char Bsp2 = 78;
    		int i = 0;
    		
    	for( ; ; )
    	{	
    		if(i==0)
    		{
    			if (PINA & (1<<PINA6))
    			{
    				uart_putc(Bsp1);
    				i=1;
    			}
    		}
    		else if (i==1)
    		{
    			if (PINA & (1<<PINA6))
    			{
    				uart_putc(Bsp2);
    				i=0;
    			}
    		}
    	}
    	return 0;
    }
    hier der Code vom Empfänger:

    Code:
    unsigned char uart_getc(void)
    {
        while (!(UCSRA & (1<<RXC)))
    	{
    	} 								// warten bis Zeichen verfügbar
        return UDR;                    // Zeichen aus UDR zurueckgeben
    }
    int main(void)
    {
    	lcd_init(LCD_DISP_ON);	//Display
    	lcd_clrscr();
    	
    	//init UART
    	UBRRH  = 0;                             // Highbyte ist 0
    	UBRRL  = 3;                            	// Lowbyte ist 51
    	UCSRB |= (1<<RXEN);					//auf empfangen gestellt
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    	
    	//Steuerleitung
    	DDRD |= (1<<PD2);		//Ausgang
    	
    	
    	char buffer1[6];
    	char buffer2[6];
    	int a;
    	int b;
    	
    	while(1)
    	{
    		
    		PORTD |= (1<<PD2);
    		a = uart_getc();
    		PORTD &= ~(1<<PD2);
    		
    		
    		PORTD |= (1<<PD2);
    		b = uart_getc();
    		PORTD &= ~(1<<PD2);
    		
    		itoa( a, buffer1, 10 );
    		lcd_gotoxy(0, 0);
    		lcd_puts(buffer1);
    		
    		itoa( b, buffer2, 10 );
    		lcd_gotoxy(0, 1);
    		lcd_puts(buffer2);
    		
    		
    	}
    	return 0;
    }

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2004
    Ort
    Karlsruhe
    Beiträge
    223
    Zitat Zitat von Karl Napf
    Das funktioniert so aber nicht, mein Display zeigt die beiden Werte abwechseln an.
    Ähm ... das sieht doch so richtig aus. Wenn der Wert 16 bit sein soll musst du auf Empfängerseite beide Werte natürlich noch zusammensetzen. Also val = byte1 | (byte2<<

    Oder überseh ich gerade was?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

12V Akku bauen