www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik char Buffer[7] Resetten, löschen.


Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ein Programm das empfängt über ein Terminal Zeichen vom PC. Das 
wird in einen char Buffer[7] geschrieben.

Soweit so gut.

Wenn jetzt nur 3 Zeichen übertragen werden, dann bleiben 4 Plätze übrig.

Ich mach mal ein Beispiel:
Anzeige        Terminal

1|2|3|||||     Terminal sendet 123
1|2|3|4|5|6||  Terminal sendet 456
8|||||||       Terminal sendet 78     

Ich hab jetzt schon vieles Versucht, aber nix fruchtet. In Java würde 
ich array[] = new Array() schreiben und das wäre gelöst. Wie löse ich 
sowas in C?

int len = strlen(Buffer);  
  unsigned int ibuff = atoi(Buffer);    
  if(ibuff< 100)
    {
  lcd_clrscr();
  lcd_puts(Buffer);
    lcd_puts("\n");
     lcd_puts("Kleiner 100");

  Buffer[len]='\0';
  getch(Buffer);
  

    } else {
  lcd_clrscr();
  lcd_puts(Buffer);
    lcd_puts("\n");
        lcd_puts("Bigger 100");
  Buffer[len]='\0';

    }

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
einfach ein

> Buffer[0]= '\0';

und schon ist der String 0 byte lang. Aber damit wird der Speicher nicht 
freigebenen, es wird noch die der String abgeschlossen.

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:

> Ich hab jetzt schon vieles Versucht, aber nix fruchtet. In Java würde
> ich array[] = new Array() schreiben und das wäre gelöst. Wie löse ich
> sowas in C?

Indem du das Array überhaupt nicht löscht, und dich daran erinnerst, das 
in C ein String dort aufhört, wo das '\0' Zeichen ist.

http://www.mikrocontroller.net/articles/FAQ#Wie_fu...

hast du also in C ein Array

char Buffer[200];

und willst du ausdrücken, dass dort drinnen ein String mit 0 Zeichen 
Länge beheimatet ist, dann platzierst du das \0 Zeichen so, dass sich 
ein String mit 0 Zeichen Länge ergibt

  Buffer[0] = '\0';

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das funktioniert nicht.

Wenn ich diese zeile in die IfElse Abfrage oder danach setze, dann wird 
nix im LCD geschrieben und die Abfrage landet immer bei "Kleiner 100"

Autor: Jean Player (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Oder er benutzt "malloc" und "free".

Gruß

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:
> Das funktioniert nicht.

Doch, das funktioniert.
Siehe deinen Originalthread.

Dein Problem ist, dass du ein massives Verständnisproblem bei ganz 
anderen Dingen hast.

Autor: Link zu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:
> Wenn ich diese zeile in die IfElse Abfrage oder danach setze, dann wird
> nix im LCD geschrieben und die Abfrage landet immer bei "Kleiner 100"
Du hast den Quellcode vergessen. ;-)
Wo kommt eigentlich lcd_puts() her?
Reagieren deine LCD-Funktionen wirklich auf \n?

Karl heinz Buchegger schrieb:
> Siehe deinen Originalthread.
Wie? Habe ich mal wieder was verpasst?

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

Bewertung
0 lesenswert
nicht lesenswert
Link zu schrieb:

>> Siehe deinen Originalthread.
> Wie? Habe ich mal wieder was verpasst?

Beitrag "Atmega644 UART - Komische Ausgabe"

aber auch dort schlägt man sich laufend mit unvollständigem Code herum 
:-)

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Doch, das funktioniert.
> Siehe deinen Originalthread.
>
> Dein Problem ist, dass du ein massives Verständnisproblem bei ganz
> anderen Dingen hast.

Das will ich nicht bestreiten, wobei ich meine es so in etwa zu 
verstehen. Nur wie soll man lernen, wenn man nicht anhand von Beispielen 
sich voranhangelt.
ich verstehe auch was bei   Buffer[0] = '\0'; passiert.

Die verständnisfragen werden immer weniger, wenn auch noch genug übrig 
sind. Wobei ich mir eigentlich recht sicher bin, bei dem was ich da 
fabriziert habe.


Nur hier an der Stelle sehe ich absolut keine Lösung. Direkt nach dem 
Einschalten des Boards klappt ja auch alles einwadnfrei. Eben aber nur 
beim ersten Mal, danach fehlt besagter reset.

Autor: Link zu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Link zu schrieb:
>>> Siehe deinen Originalthread.
>> Wie? Habe ich mal wieder was verpasst?
> Beitrag "Atmega644 UART - Komische Ausgabe"
Ach so.
Reagiert die Fleury-Lib wirklich auf '\n' wie man so erwarten würde? 
In der Online-Doku finde ich nichts dazu...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich mache das einfach so:
uint8_t data = UDR;
switch( data ){
  case '\n':
  case '\r': data = 0;
             command_received = 1;
  default: *data_ptr++ = data;
}
und dann ist der String immer richtig.


Peter

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

Bewertung
0 lesenswert
nicht lesenswert
Link zu schrieb:

> Reagiert die Fleury-Lib wirklich auf '\n' wie man so erwarten würde?
> In der Online-Doku finde ich nichts dazu...

Sein Problem ist erst mal nicht das LCD an sich, sondern das 
Verständnis, dass über die UART erst mal nur einzelne Zeichen 
eintrudeln, die er zu einem String zusammensetzen muss, ehe er dann 
irgendetwas sinnvolles damit anstellen kann.

Es wäre schon viel gewonnen, wenn er sich endlich einmal mit sich selbst 
einigen könnte, wie er nun die UART bedienen will.
Mit eigenem Code oder mit der Fleury Library.

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:

> Nur hier an der Stelle sehe ich absolut keine Lösung. Direkt nach dem
> Einschalten des Boards klappt ja auch alles einwadnfrei. Eben aber nur
> beim ersten Mal, danach fehlt besagter reset.

Dann frag dich doch mal, woher deine Add Funktion, genauer gesagt die 
Variable LastCharInBuffer, wissen soll, dass es jetzt wieder von vorne 
im Buffer losgeht.

Im übrigen:
Von deinem Code schwirren mitlerweile mindestens 3 grundverschiedene 
Versionen durchs Forum. Kein Mensch weiß mitlerweile mehr, wie dein Code 
zur Zeit in seiner vollen Pracht aussieht, ob du die Fleury Lib noch 
benutzt, etc.
Es ist schwierig, auf Fehler im Code hinzuweisen, bzw. auf 
Verständnisprobleme einzugehen, wenn der zugrundeliegende Code nicht 
bekannt ist.

Das sollte dir einen kleinen Denkanstoss geben.

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich danke Euch.... ich habe extra einen neuen post aufgemacht, da der 
alte Thread doch schon sehr gewachsen war.

Ich glaube geschrieben zu haben, dass ich verstanden habe wie Uart Daten 
sendet. Zuerst hat es mich irritiert, aber als ich wusste, das es Ascii 
ist, war es mir klar.

Ich verwende im Moment die Libary von Fleury, da mein eigener Ansatz 
zwar an sich funktioniert, aber eben dort ein Fehler steckt, den ich 
nicht finde.
Aber lassen wir das mal weg.


Dein Einwand mit der Add Funktion ist natürlich absolut berechtigt, und 
ist mir absolut nicht aufgefallen. Wie eigentlich immer wenn man 
Stundenlang davor sitzt.


Ich entschuldige mich mal für die Verwirrung die ich gestiftet habe, 
obwohl ich mich eigentlich bemüht habe immer übersichtlich zu posten. 
Das heisst auch das wegzulassen was weiter oben schon stand. Aber war 
wohl der falsche Weg :)

Der Hund liegt tatsächlich in der Add Methode begraben. Werde mir das 
jetzt mal anscheun und versuchen das Problem zu lösen.

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:

> Ich verwende im Moment die Libary von Fleury, da mein eigener Ansatz
> zwar an sich funktioniert, aber eben dort ein Fehler steckt, den ich
> nicht finde.
> Aber lassen wir das mal weg.

Nein.
Das können wir nicht weg lassen.

Falls du es immer noch nicht begriffen hast. Hier nochmal. Diesmal in 
aller Deutlichkeit:

  P O S T E     D E I N E N     A K T U E L L E N     C O D E  !

      U N D    Z W A R     K O M P L E T T  !

Jetzt verstanden?

> Der Hund liegt tatsächlich in der Add Methode begraben.

Der Hund ist auch dort begraben, dass dir Stringverabreitung an sich 
noch nicht klar ist. Im anderen Thread hast du einen Code gepostet, der 
von der Fleury Lib weggegangen ist. Die Teile die du geklaut hast, sind 
alle korrekt. Aber in den Teilen, die du dazugeschrieben hast, wimmelt 
es nur so von String-Verständnisfehlern. Daher die Aufforderung: Poste 
kompletten Code!

Deine Probleme lassen sich nicht an einer Stelle dingfest machen. Deine 
Probleme ziehen sich über deinen ganzen Code hin.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nur wie soll man lernen, wenn man nicht anhand von Beispielen
> sich voranhangelt.

Nein.  Beispiele sind gut, um zu Lernendes zu illustrieren, aber nicht, 
um sich daran entlang zu hangeln.  Entlang hangeln solltest Du Dich an 
den Grundlagen und die Beispiele zu deren Verdeutlichung nehmen.  Sonst 
landest Du bloß bei der Herumprobiererei, die wir gerade sehen.

Dann wüsstest Du, dass ein C-String an \0 endet und alles, was danach 
kommt, völlig egal ist - auch wenn es vom Speicherplatz her noch zum 
String-Array gehört.  Wenn der erste Platz im String-Array, also 
string[0], '\0' enthält, ist der String also 0 Zeichen lang.

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MainKlasse: Unverändert nutze ich die LCD Libary und UART Libary von 
Peter Fleury.
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <string.h>

#include "lcd.h"
#include "uart.h"


/* define CPU frequency in Mhz here if not defined in Makefile */

#define F_CPU 3686000UL


/* 9600 baud */
#define UART_BAUD_RATE      9600

unsigned char Buffer[7];

unsigned char LastCharInBuffer;
        
void Add( char Neu )
{
      Buffer[LastCharInBuffer++] = Neu;
      Buffer[LastCharInBuffer] = '\0';
}


int main(void)
{
    unsigned int c;
    char buffer[7];
 

     lcd_init(LCD_DISP_ON);

    /*
     *  Initialize UART library, pass baudrate and AVR cpu clock
     *  with the macro 
     *  UART_BAUD_SELECT() (normal speed mode )
     *  or 
     *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
     */
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 

    /*
     * now enable interrupt, since UART library is interrupt controlled
     */
    sei();
    
    for(;;)
    {
        /*
         * Get received character from ringbuffer
         * uart_getc() returns in the lower byte the received character and 
         * in the higher byte (bitmask) the last receive error
         * UART_NO_DATA is returned when no data is available.
         *
         */
        c = uart_getc();
    
        if ( c & UART_NO_DATA )
        {
            /* 
             * no data available from UART 
             */
        }
        else
        {
            /*
             * new data available from UART
             * check for Frame or Overrun error
             */
            if ( c & UART_FRAME_ERROR )
            {
                /* Framing Error detected, i.e no stop bit detected */
                uart_puts_P("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR )
            {
                /* 
                 * Overrun, a character already present in the UART UDR register was 
                 * not read by the interrupt handler before the next character arrived,
                 * one or more received characters have been dropped
                 */
                uart_puts_P("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW )
            {
                /* 
                 * We are not reading the receive buffer fast enough,
                 * one or more received character have been dropped 
                 */
                uart_puts_P("Buffer overflow error: ");
            }
  
      uart_putc((c & 0x00ff));

      Add((c & 0x00ff));

      unsigned int ibuff = atoi(Buffer);    
      if(ibuff< 100)
        {
        lcd_clrscr();
        lcd_puts(Buffer);
        lcd_puts("\n");
         lcd_puts("Kleiner 100");
        } else {
        lcd_clrscr();
        lcd_puts(Buffer);
        lcd_puts("\n");
          lcd_puts("Bigger 100");
        }
        //Buffer[0]='\0';
      
     }//end else
     
    }//end for
    
}//End main





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

Bewertung
0 lesenswert
nicht lesenswert
OK.

Als erstes bauen wir da gleich mal eine Funktion, die einen String von 
der UART empfängt. Als Konvention soll gelten: Die Übertragung, und 
damit der String, soll dann beendet sein, wenn von der Gegenstelle ein 
'\n' daherkommt.
Irgend so eine Konvention muss es geben, weil dein Programm ja nicht 
wissen kann, ob die Übertragung '1' '8' schon alles war (und du 18 
getippt hast) oder ob da noch was kommt (und du zb 183 getippt hast).

Die UART Library ist so aufgebaut, dass uart_getc nicht darauf wartet, 
dass ein Zeichen reinkommt. Das erleichtert den Einsatz, wenn asynchron 
noch andere Dinge passieren sollen. Fürs erste will ich aber genau die 
Umkehrung haben: Eine Funktion, die auf ein Zeichen wartet, falls keines 
vorhanden ist (die Lib speichert zwischenzeitlich eingehende Zeichen 
selbst zwischen).

Fehlerbehandlung wie Frame Fehler u. dgl. lass ich erst mal weg.
char uart_getc_wait()
{
  unsigned int c;

  do {
    c = uart_getc();
  } while( c & UART_NO_DATA );

  uart_putc( (c & 0x00ff) );

  return c;
}


void uart_gets( char * Buffer )
{
  char c;
  int  nextCharPos = 0;

  c = uart_getc_wait();
  while( c != '\n' ) {
    Buffer[ nextCharPos++ ] = c;
    c = uart_getc_wait();
  }

  Buffer[ nextCharPos ] = '\0';
}

Die Funktion uart_gets bekommt einen Buffer (ein char Array) übergeben, 
in dem sie die einzelnen Zeichen ablegen soll. Auch hier wieder eine 
Vereinfachung: Der Buffer muss vom Aufrufer gross genug zur Verfügung 
gestellt werden! Der Code sollte hier noch geändert werden, in dem man 
der Funktion die Größe des Buffers mitgibt und die Funktion in die Lage 
versetzt, sich davor zu schützen ausserhalb des zulässigen Speichers zu 
schreiben. Das verkompliziert allerdings den Code und lenkt von den 
wesentlichen Dingen ab. Daher hab ich es erst mal weg gelassen.

Mit der Funktion uart_gets() ist es nun möglich ein Hauptprogramm zu 
schreieben, welches auf einen kompletten String wartet, diesen String in 
einen int umwandelt und abhängig vom Zahlenwert etwas auf dem LCD zu 
machen
int main(void)
{
  char buffer[30];    // nicht kleckern, klotzen!
  char temp[20];
  int  Zahl; 

  lcd_init(LCD_DISP_ON);
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 

  sei();

  while( 1 ) {
    uart_gets( buffer );

    Zahl = atoi( buffer );

    lcd_clrscr();
    lcd_puts( "Als String: *" );
    lcd_puts( buffer );
    lcd_puts( "*\n");

    lcd_puts( "Als Zahl: " );
    itoa( Zahl, temp, 10 );
    lcd_puts( temp );

    if( Zahl > 100 )
      lcd_puts( " gross" );
  }
}

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Dir... ich werds mal testen.

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

Bewertung
0 lesenswert
nicht lesenswert
Ich muss allerdings sagen.
Ich habs hier im Editor direkt getippt und noch nicht durch einen 
Compiler gejagt. Da mag noch der eine oder andere kleine Fehler drinnen 
sein. Das Grundprinzip ist aber ok.

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was schonmal funktioniert: Das Programm reagiert auf die Eingabe im 
terminal... musste da LF(\n) als Endsymbol einstellen.

Aber der buffer ist leer, und damit die Zahl 0.
Auch wird nix ans Terminal zurückgegeben.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber der buffer ist leer, und damit die Zahl 0.
> Auch wird nix ans Terminal zurückgegeben.

Du hattest mal ein Programm vorgezeigt, in dem sowohl eine ISR für den 
UART drin war als auch eine direkte Abholung außerhalb.  Da das wohl 
Dein allerkleinstes Problem zu dieser Zeit war, habe ich auf einen 
Kommentar verzichtet.  Nun hast Du uns zwar das angeblich komplette 
Programm gezeigt -- aber uart_init() war nicht dabei.

Daher: ist darin immer noch diejenige uart_init(), die RXCIE setzt und 
bei der eventuell sogar noch die ISR für den Empfangsinterrupt dabei 
ist?

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#elif defined(__AVR_ATmega644__)
 /* ATmega with one USART */
 #define ATMEGA_USART0
 #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
/*************************************************************************
Function: uart_init()
Purpose:  initialize UART and set baudrate
Input:    baudrate using macro UART_BAUD_SELECT()
Returns:  none
**************************************************************************/
void uart_init(unsigned int baudrate)
{
    UART_TxHead = 0;
    UART_TxTail = 0;
    UART_RxHead = 0;
    UART_RxTail = 0;
    
#if defined( AT90_UART )
    /* set baud rate */
    UBRR = (unsigned char)baudrate; 

    /* enable UART receiver and transmmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);

#elif defined (ATMEGA_USART)
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
       UART0_STATUS = (1<<U2X);  //Enable 2x speed 
       baudrate &= ~0x8000;
    }
    UBRRH = (unsigned char)(baudrate>>8);
    UBRRL = (unsigned char) baudrate;
   
    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
    #else
    UCSRC = (3<<UCSZ0);
    #endif 
    
#elif defined (ATMEGA_USART0 )
    /* Set baud rate */
    if ( baudrate & 0x8000 ) 
    {
       UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
       baudrate &= ~0x8000;
     }
    UBRR0H = (unsigned char)(baudrate>>8);
    UBRR0L = (unsigned char) baudrate;

    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
    
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL0
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
    #else
    UCSR0C = (3<<UCSZ00);
    #endif 

#elif defined ( ATMEGA_UART )
    /* set baud rate */
    if ( baudrate & 0x8000 ) 
    {
      UART0_STATUS = (1<<U2X);  //Enable 2x speed 
      baudrate &= ~0x8000;
    }
    UBRRHI = (unsigned char)(baudrate>>8);
    UBRR   = (unsigned char) baudrate;

    /* Enable UART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);

#endif

}/* uart_init */

Hier meine init Methode... direkt aus der Fleury Libary...

Ich will jetzt nicht in meinem eigenen versuch kruschteln, um keine 
Verwirrung, speziell bei mir hervorzurufen :)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das ist genau das, was ich meinte.  Das kommt davon, wenn man sich 
aus verschiedenen Quellen Beispiele zusammenstoppelt, ohne die 
Grundlagen zu haben, sie zu verstehen.

Mach aus
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
neu
    UART0_CONTROL = _BV(RXEN)|_BV(TXEN);

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wiso verschiedene Quellen.... kommt doch alles aus der Hand von Herrn 
Fleury...

Wie gesagt das was mein erster Anstz.... später hab ichs dann selbst 
versucht. Hier in diesem thread oben der Code basiert komplett auf der 
Libary. Die kommunikation klappt auch, nur mit der Verarbeitung der 
empfangenen Daten habe ich Schwierigkeiten.

Aber da ich dort nicht weiterkomme, und ich seit Tagen versuche eine 
Lösung zu erstellen, versuche ich es nochmals mit dem Ansatz von Karl 
heinz Buchegger.
Es war aber sehr lehrreich, da ich in den letzen 2 Tagen mehr über C 
gelernt habe, als in den 2 Monaten zuvor.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.  Karl Heinz hat Dir eine Empfangsroutine vorgeschlagen, die mit 
einer Interrupt-erlaubenden Initialisierung nicht zusammenarbeitet.  Da 
Du aber trotz Aufforderung, den KOMPLETTEN Code zu posten, diese 
Initialisierung nicht gezeigt hast, konnte er davon nichts wissen.

Es war Zufall, dass mir das ein paar Stunden vorher schon aufgefallen 
war.  Und es wäre Deine Verantwortung als Zusammensteller gewesen, 
Konflikte mit Teilen, die Du zufügst, zu erkennen.

> Die kommunikation klappt auch

Oooch komm.  Du setzt RXCIE, holst aber die Rx-Daten nicht 
interruptgesteuert ab, und willst mir erzählen, dass die Kommunikation 
klappt?  Gut möglich, dass es trotz Wegnehmen von RXCIE immer noch nicht 
klappt.  Das liegt aber dann nicht daran, dass RXCIE gar kein Fehler 
gewesen wäre, sondern daran, dass Du noch andere solche Würmer drin hast 
(was mich gar nicht wundern würde).

Autor: Null Ahnung von Nichts (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man anfängt zu programmieren ist es ohnehin nicht ratsam, auf eine 
Unmenge an Libraries zurückzugreifen. Zuerst ist es mal wichtig, sein 
eigenes Geschreibsel richtig zu verstehen.
Du hast in deinem Code Libs für LCD und Uart eingefügt. Während LCD 
sicher etwas fortgeschrittener ist, ist der UART sehr einfach zu 
initialisieren und konfigurieren. Wenn du dies selber machst, lernst du 
auch den Umgang mit den diesbezüglichen Registern und kannst so 
obgenannte Fehler ausschließen.
Auch wenn du nun zig Libraries zusammenwürfelst und das Programm am Ende 
sogar noch funktioniert, hast du trotzdem keine wirkliche Ahnung was da 
eingelicht abläuft.

"Learning by doing" ist absolut ok. Aber "Learning by looking other 
people doing" eben nicht

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

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:

> war.  Und es wäre Deine Verantwortung als Zusammensteller gewesen,
> Konflikte mit Teilen, die Du zufügst, zu erkennen.

Moment.
Ich geh davon aus, dass die Fleury Lib unverändert benutzt wird.
Und soweit ich mich erinnern kann, klappt die auch problemlos 
interruptgesteuert.

> Oooch komm.  Du setzt RXCIE, holst aber die Rx-Daten nicht
> interruptgesteuert ab

Wovon sprichst du?
DIe Fleury Funktionen enthalten die ISR. Von der ISR werden die Daten in 
einen Ringbuffer gestellt, von wo sie wiederrum uart_getc abholt.

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich den gesamten Code gepostet hätte, dann hätte ich hier mehr als 
2000 Zeilen Code gepostet.
Nunja es liegt mir sehr fern mich hier zu streiten, auch kann ich nicht 
für alles geradestehen, was in meinem Code stand. Ich bin nunmal noch 
kein Spezialist im µC Bereich und in der C Welt.

Ich habe einige Jahre Java, Phython, Scheme, ... Erfahrung. In die 
Embedded Welt stürzte ich mich erst seit kurzem. Ich finde das alles 
sehr Spannend, und bin denjenigen sehr Dankbar, die sich die Zeit 
nehmen, mich auf meine Fehler hinzuweisen und mir Tipps geben.
C-Bücher habe ich hier liegen, aber bringen mich nur bedingt weiter. 
Heute und gestern bin ich an meine Grenzen gestoßen, was die logik 
hinter C angeht. Aber aus Fehlern lernt man.

Jedenfalls back on Topic:

Ich hab den Fehler gefunden im Code von Karl Heinz:
Aber wie ich sehe, hat er es schon reineditiert... :)

Naja wenigstens weiss ich worauf zu achten ist :)

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:
> Was schonmal funktioniert: Das Programm reagiert auf die Eingabe im
> terminal... musste da LF(\n) als Endsymbol einstellen.
>
> Aber der buffer ist leer, und damit die Zahl 0.

OK.

> Auch wird nix ans Terminal zurückgegeben.

Den sntsprechenden putc hab ich nachträglich noch ergänzt.
char uart_getc_wait()
{
  unsigned int c;

  do {
    c = uart_getc();
  } while( c & UART_NO_DATA );

  uart_putc( (c & 0x00ff) );

  return c;
}


Zum ersten Problem:
Ich hatte tatsächlich nach dem Absenden des Codes noch einen 
'Problemfall', ein vergessenens ++
Hast du das so
void uart_gets( char * Buffer )
{
  char c;
  int  nextCharPos = 0;

  c = uart_getc_wait();
  while( c != '\n' ) {
    Buffer[ nextCharPos++ ] = c;
    c = uart_getc_wait();
  }

  Buffer[ nextCharPos ] = '\0';
}

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Null Ahnung von Nichts schrieb:
> "Learning by doing" ist absolut ok. Aber "Learning by looking other
> people doing" eben nicht

Nunja kommt ja ganz auf die Person an, und wie sie damit umgeht.
Als ich angefangen habe UART zu nutzen, wusste ich nicht was es war. Da 
kam mir die libary vom Fleury gelegen, da ich gute Erfahrungen mit der 
LCD Libary gemacht hatte.
Die Uart Schnittstelle ist leider eine last Minute Anforderung, die ich 
noch einbauen musste.

Aber generell arbeite ich auf, was ich so hernehme. Und das Datenblatt 
liegt sowieso immer neben mir aufm Tisch.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
[Karl Heinz]
> Wovon sprichst du?

Karl Heinz, da muss ich Dir Abbitte tun.  Ich habe beim Drübergucken 
Dein uart_getc_wait() für eine direkte Abholroutine gehalten, die 
außerhalb des Interrupts arbeitet.  Erst jetzt habe ich gesehen, dass Du 
Fleurys Buffer-Abholroutine darin verwendest.  Sorry.

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

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> [Karl Heinz]
>> Wovon sprichst du?
>
> Karl Heinz, da muss ich Dir Abbitte tun.

Kein Problem.
Solange wir das Misverständnis ausräumen können.

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jep ... Danke Dir...
Die Feinheiten werde ich noch einbauen, wobei Die Schnittstelle sehr 
einfach gehalten werden soll... Irgendwann muss ich sie Ausbauen, aber 
momentan tut sie genau das was ich brauche.
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <string.h>
#include "lcd.h"
#include "uart.h"


/* define CPU frequency in Mhz here if not defined in Makefile */

#define F_CPU 3686000UL


/* 9600 baud */
#define UART_BAUD_RATE      9600

char uart_getc_wait()
{
  unsigned int c;

  do {
    c = uart_getc();
  } while( c & UART_NO_DATA );

  return c;
}

void uart_gets( char * Buffer )
{
  char c;
  int  nextCharPos = 0;

  c = uart_getc_wait();
  uart_putc(c);
  while( c != '\n' ) {
    Buffer[ nextCharPos++ ] = c;
  c = uart_getc_wait();
  uart_putc(c);
    
  }

  Buffer[ nextCharPos ] = '\0';
}



int main(void)
{
char buffer[30];    // nicht kleckern, klotzen!
  char temp[7];
  int  Zahl; 

  lcd_init(LCD_DISP_ON);
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 


  sei();

  while( 1 ) {
    uart_gets( buffer );

    Zahl = atoi( buffer );

    lcd_clrscr();
    lcd_puts( "String: *" );
    lcd_puts( buffer );
    lcd_puts( "*\n");

    lcd_puts( "Zahl: " );
    itoa( Zahl, temp, 10 );
    lcd_puts( temp );

  if( Zahl > 100 )
      lcd_puts( " gross" );

  }

    
}//End main

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:

> Als ich angefangen habe UART zu nutzen, wusste ich nicht was es war. Da
> kam mir die libary vom Fleury gelegen, da ich gute Erfahrungen mit der
> LCD Libary gemacht hatte.

Ich habe zwar die UART LIb von ihm auch noch nie irgendwo eingesetzt. 
Ich schätze sie aber trotzdem, weil sie grundsätzlich delay-freies 
arbeiten erlaubt. Man muss nicht zwangsweise auf ein Zeichen warten, 
kann das aber leicht 'umrüsten'. Anders rum ist das nicht so einfach 
möglich.

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

Bewertung
0 lesenswert
nicht lesenswert
mcnanuk schrieb:

> void uart_gets( char * Buffer )
> {
>   char c;
>   int  nextCharPos = 0;
>
>   c = uart_getc_wait();
>   uart_putc(c);
>   while( c != '\n' ) {
>     Buffer[ nextCharPos++ ] = c;
>   c = uart_getc_wait();
>   uart_putc(c);
>
>   }
>
>   Buffer[ nextCharPos ] = '\0';
> }


Normalerweise mach ich solche Sachen ungern mit Index-Variablen. Lieber 
direkt mit Pointermanipulation. Dann muss man keineen Datentyp für die 
Indexvariable festlegen. Reichen 8 Bit, oder sollen es doch 16 Bit sein. 
Mit Pointern stellt sich die Frage nicht.

Da die Funktion allerdings sowieso noch ausgebaut werden müsste
void uart_gets( char * Buffer, int BufferSize )

um der Funktion die Möglichkeit der Verhinderung eines Bufferüberlaufs 
zu geben, kommt dieser Index dann sehr gelegen.

> jep ... Danke Dir...
> Die Feinheiten werde ich noch einbauen, wobei Die Schnittstelle sehr
> einfach gehalten werden soll...

Wer sitzt am anderen Ende?
Ein Mensch oder ein anderes Programm?

Für einen Menschen solltest du noch zumindest eine rudimentäre 
Editiermöglichkeit über 'Backspace' (die große Pfeil Links Taste über 
Return) einbauen. Das geht ziemlich trivial: du kriegst ein '\b' Zeichen 
über die Schnittstelle und wenn du selber eines wegschickst, dann 
schiebt das Terminal den Cursor ein Zeichen nach links.
void uart_gets( char * Buffer )
{
  char c;
  int  nextCharPos = 0;
 
  while( ( c = uart_getc_wait() ) != '\n' ) {

    if( c == '\b' ) {
      if( nextCharPos > 0 ) {
        nextCharPos--;
        uart_putc( '\b' );
        uart_putc( ' ' );
        uart_putc( '\b' );
      }
    }

    else {
      uart_putc( c );
      Buffer[ nextCharPos++ ] = c;
    }
  }
 
  Buffer[ nextCharPos ] = '\0';

  uart_putc( '\n' );
}

Autor: mcnanuk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Wer sitzt am anderen Ende?
> Ein Mensch oder ein anderes Programm?

Hehe die Frage ist einfach: Ich ! :)
Es soll auch nur eine Zahl eingegeben werden. 0-40 000. Das \n übernimmt 
Hterm für mich :)

Aber ich werde in der Zukunft das ganze Ausbauen, und wie du sagtest es 
Userproof machen.

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Wer sitzt am anderen Ende?
>> Ein Mensch oder ein anderes Programm?
>
> Hehe die Frage ist einfach: Ich ! :)

Nun, das ist unter Umständen keine erschöpfende Auskunft ;)

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.