Hallo,
mache gerade meine ersten Gehversuche mit einem Atmel und dem Microchip
Studio. Habe einen ATMega88 per serieller Schnittstelle und USB Wandler
am PC hängen und möchte darüber mit dem uC "sprechen", also Befehle
übermitteln. Nutze dafür die Lib von Andy Gock
(<https://github.com/andygock/avr-uart>) und das klappt auch soweit ganz
gut.
Hänge allerdings an einer Typumwandlung, bzw. stehe da auf dem
Schlauch... Ich würde gerne ein char in einen int umwandlen mit Hilfe
der atoi funktion, aber daran scheitere ich immer. Folgendes Konstrukt
habe ich (könnt auch alles haben, aber sind sind zig Seiten Code):
1 | char str[16];
|
2 | // Zaehler der die Laenge des aktuell empfangenen Kommandos vom USART enthaelt
|
3 | unsigned char command_count;
|
4 | // Puffer fuer einen Befehl der ueber die USART Schnittstelle empfangen wird anlegen
|
5 | unsigned char command_from_uart[MAX_UART_CMD_LENGTH];
|
6 | // LED(Nr.) auf den sich das aktuelle Kommando bezieht
|
7 | int cmd_led;
|
8 |
|
9 | while-Schleife/main
|
10 | {
|
11 | // lese ein Zeichen ein
|
12 | c = uart_getc();
|
13 | // speichere das aktuell empfangene Zeichen ab und haenge es an das Ende des empfangenen Strings/Kommandos an
|
14 | command_from_uart[command_count] = c;
|
15 | // pruefe ob ein ENTER empfangen wurde oder die max. erlaubte Laenge erreicht wurde
|
16 | if ((command_from_uart[command_count] == CHAR_NEWLINE) || (command_count == MAX_UART_CMD_LENGTH))
|
17 | {
|
18 | // Kommandos und Rueckgaben sind wie folgt aufgebaut:
|
19 | // $LxP=y "Power"-Kommando um die LED x [1...4] entweder aus (y=0) oder an (y=1) zu schalten
|
20 | // $LxD=zzz "duty-cycle"-Kommando um fuer LED x [1...4] den duty cycle auf zzz [0...100] Prozent zu setzen
|
21 | // teste ob der Beginn fuer ein gueltiges Kommando empfangen wurde
|
22 | if ((command_from_uart[0] == '$') && (command_from_uart[1] == 'L'))
|
23 | {
|
24 | // teste ob das "Power"-Kommando empfangen wurde
|
25 | if ((command_from_uart[3] == 'P') && (command_from_uart[4] == '='))
|
26 | {
|
27 | // Debugging
|
28 | uart_puts("cmd:");
|
29 | uart_puts(command_from_uart);
|
30 | uart_puts("\r\n");
|
31 |
|
32 | // waehle die LED aus
|
33 | cmd_led = atoi(command_from_uart[2]);
|
34 |
|
35 | // Debugging
|
36 | itoa (cmd_led, str, 10);
|
37 | uart_puts("str1:");
|
38 | uart_puts(str);
|
39 | uart_puts("\r\n");
|
40 | }
|
41 | }
|
42 | }
|
Wenn ich nun via hterm (oder auch putty) die Zeichen
eingebe, so erhalte ich die folgende Ausgabe:
1 | cmd:$L3P=1<\n><\r><\n>
|
2 | str1:0<\r><\n>
|
3 | 63 6D 64 3A 24 4C 33 50 3D 31 0A 0D 0A 73 74 72 31 3A 30 0D 0A
|
Frage ich innerhalb des Codes die Variable cmd_led ab, so schlägt ein
Vergleich auf 3 fehl. Prüfe ich command_from_uart[2] auf '3', so ist das
erfolgreich. Da ich später aber gerne auch benachbarte LEDs schalten
möchte, würde ich gerne einen int haben (um einfach cmd_led++ o.ä.
nutzen zu können und nicht mit chars hantieren zu müssen). Hätte aber
gedacht, dass die atoi Funktion mir den char 0x33 (also die '3') in
einen 0x03 (also 3) umwandelt. Wo ist mein Denkfehler, bzw. wie macht
man es richtig? Könnte auch "einfach" von command_from_uart[2] immer
0x30 abziehen und hätte dann meinen Zahlenwert, aber das würde weniger
Fehler abfangen (also wenn da Buchstaben stehen würden o.ä.). Von daher
würde mich interessieren warum atoi so nicht funktioniert.
Danke und Gruß, Dirk