Forum: Mikrocontroller und Digitale Elektronik ascii to int


von Christian L. (christianlienen)


Lesenswert?

Guten Abend Kollegen,
ich habe einmal eine Frage, und zwar möchte ich mit einem empfangenen 
char Wert (der ja eigentlich ein ASCII Code sein müsste) einen 
Timerinterrupt auslösen.
Um jedoch die Marke zu definieren, wo der Vergleich erfüllt sein soll, 
brauche ich einen INT Wert, den ich gerne über den UART empfangen 
möchte.
Da der UART ja nur char's empfängt, muss ich diesen Wert in einen int 
Wert umwandeln.
Doch wie mache ich das?
Ich weiß schonmal, dass die 0 zb. dezimal 48 ist.
Reicht da eine einfache Zuweisung wie z.b.
1
char data;
2
int buffer;
3
buffer=getchar(data);
4
buffer=buffer-48;
?
Dann habe ich ja noch das Problem, dass es auch eine zwei- oder 
dreistellige Zahl sein kann. Kann man dann einfach eine for-Schleife 
benutzen, die jedesmal bis 3 zählt?

Irgendwie weiß ich noch nicht so ganz weiter...

Gruß
Christian

von U. K. (rauchendesdope)


Lesenswert?

1
int atoi (const char *__s)

ist in der stdlib.h zu finden.

http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html

von Purzel H. (hacky)


Lesenswert?

Ein uart kann irgendwas empfangen. Es muss nicht ein Char sein. Ein Byte 
ist auch moeglich.

von Klaus W. (mfgkw)


Lesenswert?

Dünner Zitterknilch schrieb:
> Es muss nicht ein Char sein. Ein Byte
> ist auch moeglich.

Könnte auch ein Oktett sein, oder sogar 8 Bit!

von Nippel (Gast)


Lesenswert?

oder zwei Nibble

von ekke (Gast)


Lesenswert?

oder vier Crumb

von Nippel (Gast)


Lesenswert?

oder 1/2 short

von Christian L. (christianlienen)


Lesenswert?

Vielen Dank für die hilfreichen Tipps:D
Leider komme ich wirklich nicht mit mehr weiter. Ich dachte eigentlich, 
jetzt müsste es mit dem atoi befehl klappen - aber denkste!
1
#define F_CPU 16000000UL
2
#include <stdlib.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
// Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
8
#define BAUD 9600L
9
 
10
// Berechnungen
11
// clever runden
12
#define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  
13
// Reale Baudrate
14
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     
15
// Fehler in Promille 
16
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) 
17
18
 
19
// globale Variablen für den UART
20
 
21
// Puffergrösse in Bytes, RX und TX sind gleich gross
22
#define uart_buffer_size 3
23
24
25
26
void uart_init(void)
27
{
28
    UCSR0B |= (1<<RXEN0);                         // UART RX einschalten
29
    UCSR0C |= (1<<USBS0)|(1<<UCSZ00);  // Asynchron 8N1 
30
 
31
    UBRR0H = UBRR_VAL >> 8;
32
    UBRR0L = UBRR_VAL & 0xFF;
33
}
34
35
uint8_t uart_getc(void)
36
{
37
    while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
38
        ;
39
    return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
40
}
41
 
42
void uart_gets( char* Buffer, uint8_t MaxLen )
43
{
44
  uint8_t NextChar;
45
  uint8_t StringLen = 0;
46
 
47
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
48
 
49
                                  // Sammle solange Zeichen, bis:
50
                                  // * entweder das String Ende Zeichen kam
51
                                  // * oder das aufnehmende Array voll ist
52
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
53
    *Buffer++ = NextChar;
54
    StringLen++;
55
    NextChar = uart_getc();
56
  }
57
 
58
                                  // Noch ein '\0' anhängen um einen Standard
59
                                  // C-String daraus zu machen
60
}
61
62
63
int main(void)
64
{
65
volatile char empfangen;
66
volatile int zeit;
67
68
DDRC = 0xff;
69
zeit = 120;
70
uart_init;
71
EIMSK |= (1<<INT0);
72
EICRA |= (1<<ISC01 | 1<<ISC00);//Externen Interrupt erlauben
73
74
TCCR0A = (1<<WGM01); // CTC Modus
75
TCCR0B |= (1<<CS02)|(1<<CS00); // Prescaler 256
76
TIMSK0 |= (1<<OCIE0A);
77
78
79
80
sei();
81
  while(1)
82
{
83
84
uart_gets(empfangen,3);
85
zeit = atoi(empfangen);
86
OCR0A = empfangen;
87
}
88
}
89
90
91
92
93
94
ISR(INT0_vect) {
95
96
TCNT0 = 0;
97
98
}
99
100
ISR(TIMER0_COMPA_vect) {
101
PORTC |= (1 << PC5);
102
_delay_us(200);
103
PORTC &= ~(1 << PC5);
104
}

Der Code sieht mitlerweile so aus und ich weiß echt nicht, wo noch der 
Bock liegt. Der Controller soll halt die Zeit zwischen 0 und 255 ändern 
könne, in der Realität macht er irgendwie nichts.
Einer ne Ahnung?

Gruß
Christian

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian L. schrieb:
> Der Code sieht mitlerweile so aus und ich weiß echt nicht, wo noch der
> Bock liegt.

Auf den schnellen Blick sehe ich, dass Deine Funktion  uart_gets() den 
String nicht terminiert. Das ist böse. Terminierung geht mit
1
 *Buffer = '\0';

am Ende der Funktion. Aber dafür musst Du ein weiteres Zeichen im Buffer 
einplanen, z.B. indem Du schreibst:

Alt:
1
    uint8_t StringLen = 0;

Neu:
1
    uint8_t StringLen = 1;        // minimal len is 1: '\0' as terminator


Zweiter Bock:
1
volatile char empfangen;        // das ist ein einzelnes Zeichen!
2
...
3
uart_gets(empfangen,3);         // hier übergibst Du das Zeichen als Buffer!

Das ist ebenso böse. Hat der Compiler nicht gemeckert? Wenn ja, warum 
ignorierst Du die Meldung?

Warum Du empfangen als volatile deklariert hast, ist mir auch 
schleierhaft.

Also:
1
char empfangen[5];
2
...
3
uart_gets(empfangen,4);

Und dann geht das hier nicht mehr:
1
OCR0A = empfangen;

Das musst Du anders lösen -> Deine Hausaufgabe ;-)

von Karl H. (kbuchegg)


Lesenswert?

Ich denke, der wichtigste Punkt besteht darin, dass du in deinem 
C-Lehrbuch das Kapitel über Strings und Stringverarbeitung durcharbeiten 
müsstest.
Das ist ein umfangreiches Kapitel welches normalerweise einen der ersten 
Stolpersteine jedes C-Neulings darstellt.

einen Abriss der wichtigsten Zusammenhänge, die allerdings ein Lehrbuch 
nicht ersetzen können, findest du hier:

http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

von Klaus W. (mfgkw)


Lesenswert?

Oder mal ins Tutorial schauen, das steht sowas doch drin.

von Christian L. (christianlienen)


Lesenswert?

Guten Morgen,
ja das hört sich alles ziemlich einleuchtend an. Die Änderungen habe ich 
nun auch an meinem Programm durchgeführt. Das steht so ja auch im 
Tutorial. Deshalb frage ich mich auch, wo die einzelnen Schnibsel 
geblieben sind.

Ich habe mir nun gedacht, den String einfach durch den atoi befehl in 
einen int Wert umzubauen und diesen dann direkt dem Register zuzuweisen.
Meines Wissens müsste der int- Wert doch genauso aufgebaut sein oder 
nicht?

Ich habe das ganze jedoch so programmiert und es läuft immernoch nicht. 
Aber wieso nicht?

Grüße und vielen Dank für eure Bemühungen.

Christian

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.