Hallo zusammen,
ich stehe gerade irgendwie auf dem Schlauch.
Ein Prüfgerät sendet mir Modbus Telegramme, die ich einlesen will.
Laut Dokumentation erfolgt die Übermittlung mit 9600 baud, 7 Datenbits,
2 Stopp-Bits und Even Parity. So habe ich den UART des ATMEGA328p auch
konfiguriert...
1 | // Enable Receiver, Enable Transmitter, Enable Receive Interrupt
|
2 | UCSR0B |= (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);
|
3 |
|
4 | // 7 Bit 2 Stopp Even Parity
|
5 | UCSR0C = (1<<UCSZ01) | (1 << USBS0) | (1 << UPM01)
|
Der Telegraminhalt soll sein:
1 | [Startzeichen] => ':'
|
2 | [Clientadresse] => 1 Byte
|
3 | [Befehl] => 1 Byte
|
4 | [zu lesendes Register] => 2 Byte
|
5 | [Anzahl Bytes] => 2 Byte
|
6 | [LRC] => 1 Byte
|
7 | [CR] => 1 Byte
|
8 | [LF] => 1 Byte
|
also bspw:
Da die Übertragung als ASCII erfolgt, möchte ich das Telegram zunächst
wieder umrechnen in die entsprechenden Werte, damit ich damit vernünftig
arbeiten kann.
Leider scheitere ich daran irgendwie...
Im RX Interrupt werden die empfangenen ASCII Bytes zunächst mittels
char2val() in ihren korrespondieren Wert umgerechnet.
1 | ISR(USART_RX_vect) {
|
2 |
|
3 | unsigned char rcvdByte = UDR0;
|
4 | // ...
|
5 |
|
6 | uint8_t data[currentTelegramPosition] = chr2val(rcvdByte);
|
7 | }
|
8 |
|
9 | uint8_t chr2val(unsigned char c) {
|
10 |
|
11 | if (c >= '0' && c <= '9')
|
12 | return(c - '0');
|
13 |
|
14 | if (c >= 'A' && c <= 'F')
|
15 | return(10 + c - 'A');
|
16 |
|
17 | return(0);
|
18 | }
|
Wenn das Telegram vollständig ist, setze ich ein Flag und werte es aus.
1 | uint8_t clientAddress = data[1] * 16 + data[2];
|
2 | uint8_t command = data[3] * 16 + data[4];
|
3 | uint8_t startRegister_H = data[5] * 16 + data[6];
|
4 | uint8_t startRegister_L = data[7] * 16 + data[8];
|
5 | uint8_t count_H = data[9] * 16 + data[10];
|
6 | uint8_t count_L = data[11] * 16 + data[12];
|
7 | uint8_t lrc = data[13] * 16 + data[14];
|
Es werden auch Daten empfangen und die Erkennung von Telegram-Start und
das Zählen der empfangenen Bytes klappt ebenfalls wie gewünscht.
Nur haben die umgerechneten Daten hinterher nicht den Wert, den sie laut
ASCII Telegramm eigentlich haben sollten.
Sieht jemand spontan, wo das Problem liegen könnte?
Vermutlich sehe ich den Wald vor lauter Bäumen nicht... aber ich komme
einfach nicht drauf.
Wäre für jede Hilfestellung dankbar.
LG, Mirko