- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 7 von 7

Thema: UART Kommunikation, aber wie

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    17.12.2013
    Beiträge
    10

    UART Kommunikation, aber wie

    Anzeige

    Praxistest und DIY Projekte
    Hallo Zusammen

    Ich möchte periodisch einen 2 byte Wert von einem uC an den PC senden. Ich habe vor aus den beiden Bytes eine Checksumme zu berechnen und dann das ganze an den PC zu senden. Nun bin ich zurzeit absolutverwirrt wie und was sinn machen würde... Die beiden Werte liegen in einem uint8_t array, die beiden Checksummenbytes sind allerdings vom typ char.
    Soll ich nun per utoa alles in ein buffer char array schmeissen und dann als string senden? Ich bin gerade etwas verwirrt bezüglich der Datentypen und ascii...

    Irgendsowas habe ich mir vorgestellt, aber mittlerweile seh ich nicht mehr durch... Was würde da in meinem Beispiel am PC ankommen?

    Code:
                                    uint8_t databuffer[10];
    	                        char Sendbuffer[20];
    	                        char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    				int checksum = 0xFF;
    				char checksum1, checksum2;
    				int x = 0;
    
                                    databuffer[0] = 10;
                                    databuffer[1] = 20;
    				
    				//Checksumme berechnen
    				for (i = 2; i>= 1; i--)
    				{
    					checksum ^= databuffer[x];
    					x++;
    				}
    				
    				checksum1 = hex[checksum / 16];
    				checksum2 = hex[checksum % 16];
    				databuffer[x] = checksum1;
    				x++;
    				databuffer[x] = checksum2;
    				
    				utoa(databuffer,Sendbuffer,10);
    				
    				uart_Sendstring(Sendbuffer);
    Wie macht man so was in "wirklichkeit"? Macht mein Code überhaupt sinn??

  2. #2
    RN-Premium User Stammmitglied
    Registriert seit
    26.01.2005
    Ort
    Leipheim / Donau
    Beiträge
    53
    Hallo Quad,
    ich hab bei meiner Übertragung zuerst das Prüfbyte als integer, also zum prüfen ob die Übertragung überhaupt stattfinden soll.
    Und dann den Wert, bei mir wars ein Spannungswert mit 3 Bytes in asscii und Excel hat mir die Werte dargestellt und sauber aufgelistet.
    Ich hab das in VBA so programmiert, dass bei korrektem Prüpfbyte übertragen wird ansonsten kam eine Meldung mit manuellem Abruch.
    Ich weiß ja nicht in welches Programm du die Werte aufnehmen willst, aber ich würde sagen versuchs einfach.

    mfg ihle

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.01.2014
    Beiträge
    7
    Hallo,

    Eine mögliche Variante für die Checksummenberechnung über die zu übertragenden Daten würde ich die, wie bereits in deinem Beispielcode angedacht, XOR-Operation verwenden. Nachfolgend ein Beispiel, wie die Prüfsummenberechnung z.B. bei zwei zu übertragenden Datenbytes aussehen könnte.

    Code:
    uint8_t const data_length = 2; // Konstante um die Anzahl der Nutzdaten anzugeben
    uint8_t data[2]; // Array welches die Nutzdaten (2 Bytes) enthält
    
    // Nutzdaten setzen
    data[0] = 0x0F;
    data[1] = 0xF0;
    
    // Variable für die Prüfsumme anlegen und mit dem Wert der ersten Nutzdatenvariable initialisieren
    uint8_t checksum = data[0];
    // Prüfsumme berechnen
    uint8_t i=1; for(; i<data_length; i++) {
      checksum = checksum ^ data[i];
    }
    Die Variable checksum enthält in diesem Beispiel nach der Berechnung den Wert 0xFF (Weil 0x0F xor 0xF0 = 0xFF ist).

    Für die Übertragung wäre es nun wichtig zu wissen, wie die Funktion uart_Sendstring() intern funktioniert. Aufgrund der Art des verwendeten Datentypes (nämlich char) tippe ich auf eine Implementierung, bei solange Datenbytes aus dem Array Sendbuffer übertragen wird, bis eine sogenanntes Terminierungszeichen, welches bei ASCII-Strings den Wert 0x00 hat, in dem Array vorkommt. Da bei deiner Übertragung der Wert 0x00 aber durchaus vorkommen kann, müsstest du entweder garantieren, dass keine 0 in deinen Werte vorkommen kann (unmöglich), oder aber die Werte in ASCII-Zeichen konvertieren (aufwändig), oder eine Funktion uart_sendBytes(uint8_t *data, uint8_t const length) schreiben. Dies sollte nach Analyse der Funktion uart_Sendstring() kein Problem darstellen, im Zweifelsfall kannst du aber den Quellcode der Funktion hier posten und ich schreibe die Funktion uart_Sendstring dann so um, dass du die Datenbytes über den PC senden kannst.

    Ad Datentypen und ASCII - uint8_t und char sind beides Datentypen, welche jeweils 8 Bit (= 1 Byte) groß sind. Damit lassen sich daher 256 Zahlen (2⁸) darstellen. ASCII wiederum ist eine Kodierung, wie die 256 Werte zu interpretieren sind. Der Zusammenhang, welcher Wert welches Zeichen repräsentiert, ist über eine ASCII-Tabelle gegeben.

    Viel Erfolg

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    17.12.2013
    Beiträge
    10
    Vielen Dank für deine super Antwort. Ich habe es nun so gemacht:

    Code:
    void Makeframe (int Wert, char *Adress)
    {
    	char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    	int data[4];
    	unsigned char datahexchar[4];
    	uint8_t i, checksum = 0xFF;
    	char Check1, Check2, *Startadress = Adress;
    	
    	data[3] = Wert / 4096;
    	Wert = Wert - (data[3] * 4096);
    	data[2] = Wert / 256;
    	Wert = Wert - (data[2] * 256);
    	data[1] = Wert / 16;
    	Wert = Wert - (data[1] * 16);
    	data[0] = Wert;
    	
    	*Adress = '!';
    	Adress++;
    	for(i=4;i>0;i--)
    	{
    		datahexchar[i-1] = hex[data[i-1]];
    		*Adress = datahexchar[i-1];
    		Adress++;
    	}
    	
    	Adress = Startadress;
    	for (i = 5; i >= 1; i--)
    	{
    		checksum ^= *Adress;
    		Adress++;
    	}
    	Check1 = hex[checksum / 16];
    	Check2 = hex[checksum % 16];
    	*Adress = Check1;
    	Adress++;
    	*Adress = Check2;
    	Adress++;
    	*Adress = 0x00;
    }
    Somit habe ich ja das problem mit der Terminierung auch umgangen da 0x00 ja in ascii ja nicht 0 ist sondern NUL. Oder sehe ich das falsch? Zusätzlich habe ich so auch immer die gleiche Framelänge. Was hälts du von diesem Code?

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    01.01.2014
    Beiträge
    7
    Der von die gepostete Code fällt in die zweite von mir angegebene Variante (Konvertieren ind ASCII-Format) und benötigt zwar einige Rechenoperationen, aber er erfüllt seinen Zweck (da der Wert 0x00 nicht mehr auftreten kann) und das ist das Wichtigste Ein paar kleine Möglichkeiten zur Optimierung sind mir noch aufgefallen.

    1) Die Variable datahexchar wird eigentlich gar nicht gebraucht:
    Code:
    for(i=4;i>0;i--)
    {
            datahexchar[i-1] = hex[data[i-1]];
    	*Adress = datahexchar[i-1];
    	Adress++;
    }
    wird zu
    Code:
    for(i=4;i>0;i--)
    {
    	*Adress = hex[data[i-1]];
    	Adress++;
    }
    2) Die aufwendigen Multiplikationen und Divisionen lassen sich, weil durch Zahlen dividiert wird welche ein Vielfaches von 2 darstellen, durch Schiebeoperationen ersetzen:
    Code:
    data[3] = Wert / 4096;
    wird zu
    Code:
    data[3] = Wert >> 12; // 2¹² = 4096
    und
    Code:
    Wert = Wert - (data[3] * 4096);
    wird zu
    Code:
    Wert = Wert - (data[3] << 12);
    Alternativ lässt sich die Operation meiner Meinung nach auch über den Modulus-Operator anschreiben:
    Code:
    Wert = Wert % 4096;
    Das sind aber nur mehr kleine Anregungen, im Grunde funktioniert deine Lösung ja

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    17.12.2013
    Beiträge
    10
    Danke für deine Mühe! Ja, der Code ist noch nicht gerade schön... Ich habe allerdings erst gerade wieder angefangen zu programmieren und da mache ich es gerne sehr übersichtlich und wenns dann funktioniert, versuche ich es zu komprimieren...

    Zu erstens:
    Ich habe das mal genau so gemacht wie du es hier beschrieben hast, dass hat aber nicht funtioniert.. Vielleicht ein Compiler fehler...

    2.) Das werde ich wohl so machen! Ich bin allerdings nicht so Sattelfest mit den schiebeoperationen... Daher habe ich es eben mal so gemacht um zu schauen ob es überhaupt funktioniert! Danke nochmals für deine kompetenten ratschläge!

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    01.01.2014
    Beiträge
    7
    Zitat Zitat von QuadV Beitrag anzeigen
    Zu erstens:
    Ich habe das mal genau so gemacht wie du es hier beschrieben hast, dass hat aber nicht funtioniert.. Vielleicht ein Compiler fehler...
    Interessant. Könnte es eventuell sein, dass du in den Projekteinstellungen die Optimierung eingeschalten hast. Afaik ist bei den AVR-Studio-Projekten immer -Os (Optimierung auf die Programmgröße) eingestellt. Bei dieser Einstellung optimiert der Compiler ziemlich aggressiv und das kann in weiterer Folge zu den widersprüchlichsten Phänomenen führen. Ansonsten freut es mich, dass ich dir helfen konnte Keep up the good work und niemals locker lassen

Ähnliche Themen

  1. Probleme mit UART-Kommunikation
    Von __lissy__ im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 21.05.2013, 08:55
  2. Syntax für UART Kommunikation
    Von spelli2001 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 24.06.2012, 14:51
  3. Elektor RFM12 Code in UART ändern. Aber wie?
    Von Bammel im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 16.09.2009, 19:52
  4. µC Kommunikation via UART?
    Von Killer im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 24.12.2007, 02:22
  5. Uart-Kommunikation zwischen µCs
    Von ProgDom im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 20.04.2006, 00:37

Stichworte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad