PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Serielle Daten Senden von mehr als 2Byte



xrzr
05.03.2015, 20:08
Hallo,

ich möchte gerne eine Integer Zahl die gröer als 255 spricht mehr als 2Byte hat über UART senden.

Ich Schreibe die Zaheln über eine Varibale und einen Aufruf in das UDR register. Ist der Wert kleiner 256 spricht hat nur zwei Byte kommen die entsprechend beim Empfänger an.
Ist die Zahl größer 255 also 3 Byte so kommen beim Empfänger (HTERM) nur die letzten beiden Stellen Hexadezimal an.

Beispiel:
Sende: 99 (INT) Empfänger: 63 (HEX)
Sende: 255 Empfänger: FF
Sende: 300 Empfänger: 2C statt 12C
Sende: 1222 Empfänger: C6 statt 4C6

Controller: Atmega 1284P





........

int uart_putc (int16_t sende) {
while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{
}

UDR0 = sende; /* sende Zeichen */
return 0;
}

.........

int main (void) {

int16_t s1=0, s2=0, s3=0, s4=0;
uart_init();

while (1){

s1 = 99;

uart_putc (s1);
}
....
}

i_make_it
06.03.2015, 08:50
Und wenn du statt (int16_t sende)
(int8_t sende) nehmen würdest, käme mit ziemlicher Sicherheit nur ein byte raus.

Da eine 16 Bit Integerzahl nun mal nur 2 Byte representieren kann geht halt nicht mehr.
Schau mal ob du (int32_t sende) nehmen kannst oder zerlege den Datenstrom vor dem Senden in kleine Happen (Bytes), die du dann nacheinander sendest und im Ziel natürlich wieder zusammensetzen musst.

xrzr
06.03.2015, 09:17
Die Lösung des Problem habe ich so gelöst, indem ich erst das High-Byte sende und dann das Low-Byte

askazo
06.03.2015, 09:19
Die Uart kann mit einem Sendevorgang - je nach Konfigurationsmöglichkeiten des Controllers - nur maximal 9 Datenbits versenden.
Üblich sind aber 8 Datenbits, also 1 Byte. Das entspricht einem Wertebereich von 0...255.

Wenn Du größere Werte übertragen möchtest, muss der Sender diese zwangsweise in einzelne Bytes aufteilen und der Empfänger muss sie wieder zusammensetzen.
Das Senden für ein Word (also 16 Bit) könnte dann so aussehen:



void uart_putc (int16_t sende)
{
while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{}
UDR0 = (uint8_t)(sende >> 8); /* sende High Byte */

while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{}
UDR0 = (uint8_t)sende; /* sende Low Byte */
}


Gruß,
askazo

xrzr
06.03.2015, 09:23
Habe es wie folgt gelöst:


uart_putc (s1 >> 8 );
uart_putc (s1 & 0xFF);


Nur noch nicht ganz den Hintergrund verstanden.
Kann das jemand bitte Erläutern?

nugglix
06.03.2015, 09:46
Habe es wie folgt gelöst:


uart_putc (s1 >> 8 );
uart_putc (s1 & 0xFF);


Nur noch nicht ganz den Hintergrund verstanden.
Kann das jemand bitte Erläutern?

http://de.wikipedia.org/wiki/Integer_(Datentyp)

Grundlagen werden hier nicht wirklich vermittelt werden können.
Genausowenig wie im mikrocontroller.net.

HaWe
07.03.2015, 13:34
hallo,
du hast bei int16 2 bytes, bestehend aus je 8 bit:

76543210 76543210
(High Byte) (LowByte)

wie hier die Zahlen größer als 255 verschlüsselt werden weißt du aber schon, oder?

Der echte Wert des LowBytes bleibt identisch mit seinem Bytewert,
um das Low-Byte zu maskieren, wird die Integerzahl per AND-Verknüpfung bitweise mit der Zahl 255 verknüpft (255 bitweise = 00000000 11111111).
Dadurch fallen alle Werte >255 raus und das reine LowByte bleibt übrig.

Der echte Wert des HighBytes in der Integerzahl ist der 256-fache reine Bytewert.
Statt / 256 kann man auch 8 bits nach rechts shiften. Dadurch werden schrittweise alle Bits nach rechts verschoben, die 8 unteren Bits 0-7 fliegen raus und die oberen 8 bits 0-7 stehen jetzt quasi alleine da.