mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ascii to int


Autor: Christian L. (christianlienen)
Datum:

Bewertung
0 lesenswert
nicht 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.
char data;
int buffer;
buffer=getchar(data);
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

Autor: U. K. (rauchendesdope)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int atoi (const char *__s)

ist in der stdlib.h zu finden.

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

Autor: Zwölf Mal Acht (hacky)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Nippel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder zwei Nibble

Autor: ekke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder vier Crumb

Autor: Nippel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder 1/2 short

Autor: Christian L. (christianlienen)
Datum:

Bewertung
0 lesenswert
nicht 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!
#define F_CPU 16000000UL
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
#define BAUD 9600L
 
// Berechnungen
// clever runden
#define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  
// Reale Baudrate
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     
// Fehler in Promille 
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) 

 
// globale Variablen für den UART
 
// Puffergrösse in Bytes, RX und TX sind gleich gross
#define uart_buffer_size 3



void uart_init(void)
{
    UCSR0B |= (1<<RXEN0);                         // UART RX einschalten
    UCSR0C |= (1<<USBS0)|(1<<UCSZ00);  // Asynchron 8N1 
 
    UBRR0H = UBRR_VAL >> 8;
    UBRR0L = UBRR_VAL & 0xFF;
}

uint8_t uart_getc(void)
{
    while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
        ;
    return UDR0;                   // Zeichen aus UDR an Aufrufer zurueckgeben
}
 
void uart_gets( char* Buffer, uint8_t MaxLen )
{
  uint8_t NextChar;
  uint8_t StringLen = 0;
 
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
 
                                  // Sammle solange Zeichen, bis:
                                  // * entweder das String Ende Zeichen kam
                                  // * oder das aufnehmende Array voll ist
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
    *Buffer++ = NextChar;
    StringLen++;
    NextChar = uart_getc();
  }
 
                                  // Noch ein '\0' anhängen um einen Standard
                                  // C-String daraus zu machen
}


int main(void)
{
volatile char empfangen;
volatile int zeit;

DDRC = 0xff;
zeit = 120;
uart_init;
EIMSK |= (1<<INT0);
EICRA |= (1<<ISC01 | 1<<ISC00);//Externen Interrupt erlauben

TCCR0A = (1<<WGM01); // CTC Modus
TCCR0B |= (1<<CS02)|(1<<CS00); // Prescaler 256
TIMSK0 |= (1<<OCIE0A);



sei();
  while(1)
{

uart_gets(empfangen,3);
zeit = atoi(empfangen);
OCR0A = empfangen;
}
}





ISR(INT0_vect) {

TCNT0 = 0;

}

ISR(TIMER0_COMPA_vect) {
PORTC |= (1 << PC5);
_delay_us(200);
PORTC &= ~(1 << PC5);
}

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

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
 *Buffer = '\0';

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

Alt:
    uint8_t StringLen = 0;

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


Zweiter Bock:
volatile char empfangen;        // das ist ein einzelnes Zeichen!
...
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:
char empfangen[5];
...
uart_gets(empfangen,4);

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

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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_fu...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder mal ins Tutorial schauen, das steht sowas doch drin.

Autor: Christian L. (christianlienen)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.