2016-05-22 2 views
0

Ich arbeite Rahmen von 8 Bytes Micro-Controller Xmega128a1 (via RS232) senden sieht der Rahmen wie diese {header1,header2,CMD,D1,D2,D3,D4,CRC}, zum Beispiel {0x55,0xaa,0xFF,0x59,0xfd,0x64,0x68,0x32}, Micro Der Controller muss den Frame an den PC zurücksenden, wenn er korrekt ist. Ich baute GUI in QT Creator Ich definierte die Header (header0 = 0x55, header1 = 0xaa) und CMD = 01 berechnet auch die CRC, der Benutzer muss das Datenfeld in der Line_Edit, die Wert in RPM (Real-Wert) eingeben Der Micro-Controller Empfangen Sie das Frame-Byte-Byte und erneut den Vollbild, so dass ich den Rahmen in Form von Bytes senden muss, wenn ich den Rahmen senden, empfange ich die Header, Befehl und CRC korrekt, aber Datenfeld Empfangen nicht richtig so wie in der Abbildung unten, ist mein Problem mit der Umwandlung der Eingabewert in der Zeile_Edit in Bytes innerhalb des Rahmens gesendet werden, wenn ich versuchte, den Wert 1265 RPM zu senden, empfing ich den Rahmen {55aa0100209e44fb}, aber ich möchte den Rahmen erhalten sehe so aus {55aa014F109e44fb}, wobei: (1265) DC = (4F1) HEX, ich konnte nicht herausfinden, was das Problem mit meinem Code ist: die Art, wie ich Daten von der seriellen Schnittstelle lese:recieving Rahmen von 8 Bytes in QT Creator GUI über die serielle Schnittstelle

void MainWindow::read() 
{ 
    uint64_t size = serial->bytesAvailable(); 
    if (size > 0) 
    { 
     QByteArray data; 
     data.append(serial->readAll()); 
     ui->termial_textEdit->append(data.toHex()); 
    } 
} 

der Sendewert in RPM-Code:

#define CMD_SPEED_REF2 0x01 
void MainWindow::on_speed_ref2_lineEdit_returnPressed() 
{ 
    uint8_t frame2[8]; 
    frame2[0] = 0x55; 
    frame2[1] = 0xAA; 
    frame2[2] = CMD_SPEED_REF2; 

    float fdata2 = 0.0f; 

    fdata2 = ui->speed_ref2_lineEdit->text().toFloat(); 

    uint8_t *data2 = new uint8_t(); 
    data2 = (uint8_t*)&fdata2; 

    frame2[3] = data2[0]; 
    frame2[4] = data2[1]; 
    frame2[5] = data2[2]; 
    frame2[6] = data2[3]; 

    frame2[7] = frame2[2]^frame2[3]^frame2[4]^frame2[5]^frame2[6]; 

    serial->write((char*)frame2, 8); 

} 

dieses Bild Illustrieren, was passiert: recived frame

+0

brauchen Sie wirklich zu schicken 'float' Zahlen Sie können Ihre Array wie folgt neu bauen? 'float's ** sind ** nicht ** gespeichert wie du redest, siehe [this] (https://en.wikipedia.org/wiki/Single-precision_floating-point_format). Sie sollten entscheiden, welches Format gesendet werden soll, abhängig von dem Gerät, mit dem Sie kommunizieren. – Mike

+0

Ich verstehe nicht, wenn Ihre RPM-Variable wirklich ein IEEE-Float ist. Wenn dies der Fall ist und die Kodierung/Byte-Reihenfolge "Little Endian" ist, dann ist die HEX-Darstellung tatsächlich "00 20 9E 44". (Ich bestätigte dies mit unserem Docklight-Konvertierungs-Makro DL.AddComment DL.ConvertSequenceData ("fromSingle", "1265", "H", false).) –

+0

Wenn RPM eine Integer32-Variable ist, sollte die hexadezimale Darstellung " F1 04 00 00 "in Little Endian. –

Antwort

0

Ich denke, Ihr Code meist ok aussieht. Der eine Bereich, der sehr verdächtig aussieht, ist die Umwandlung des Textes/der Zeichenkette in eine Binärdatei.

Da Sie Ihre binären in einen String konvertieren mit:

ui->termial_textEdit->append(data.toHex()); 

Sie sollten die folgenden konvertieren können, verwenden, um es in der Theorie zurück:

// Convert back... 
QByteArray binaryData = QByteArray::fromHex(ui->speed_ref2_lineEdit->text().toLatin1()); 
// Print to debug to check it... 
qDebug("d1: %02x, d2: %02x...etc...\n", binaryData[0], binaryData[1]); 
// or just 
qDebug() << "data:" << binaryData.toHex() << endl; 

Nicht auf meinem qt PC bis Montag also kann ich diesen Code nicht überprüfen, also könnte irgendwo ein Fehler drin sein ... Ich werde es am Montag überprüfen! Für serielle Kommunikation verwende ich immer QByteArray anstelle von char/uint8_t Arrays (wenn Qt verwendet wird), weil sie so einfach zu benutzen sind.

QByteArray frame2; 
frame2.append((char) 0x55); // not sure you need to cast it here 
frame2.append((char) 0xAA); 
frame2.append((char) CMD_SPEED_REF2); 
    : 
    etc 
    : 

Wenn Sie als char senden MÜSSEN * Sie dann nur:

serial->write(frame2.data(), 8); 
//or 
serial->write(frame2.data(), frame2.size()); // if you want to send the whole thing