www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmel 8051 per Terminal in Array schreiben


Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, bin ziemlicher Neueinsteiger im Bereich uController, und momentan 
am experimentieren, wie ich im Hyperterminal eingegebene Zeichen in ein 
Array abspeicheren kann.

Der Controller ist ein AT89C51CC03.

Also was momentan schon klappt, ist die Initialisierung mit der 
passenden Baudrate (9600) und die Ausgabe eines Arrays im Hyperterminal.

Was jedoch nicht klappt, jedoch komm ich momentan noch nicht dahinter 
wie ich es anstellen soll das ich die eingegebenen Zeichen nacheinander 
aus dem Buffer hole und dann ins Array speichern kann.

Es sollte so sein, das ich etwas eingebe, dann RETURN drücke und das 
dann das fertige Array in die nächste Funktion übergeben wird.
Wenn alles mal fertig ist, solls zur Datenwort-Übergabe für einen AD9833 
Frequenzgenerator dienen.

Hier mein Code:
//Teilweise was weggelassen

void Warte10Us(int);
void SerialInit();
void GebeDatenAus(unsigned char*);

int main(void)
{
   int i=0, anzahl=0;
   unsigned char array[30];
   
   SerialInit();
   while(strcmp(array,'\0')!= 0)
   {
      if (RI==1)
      {
         array[i]=SBUF;
         i++;
         RI=0;
      }
   }
   GebeDatenAus(array);
   return 0;
}
void SerialInit() //8-Bit Auto-Reload 9600 Baud
{
   EA=0;          //Alle Interrupts deaktivieren
   TH1=0xFD;   //FD=253, Wert gültig für 9600 Baud bei 11,059 Mhz
   SCON=0x50;   //01010000 ins SCON-Register laden -> 8Bit Auto-Reload
   TR1=1;   //Counter starten
   RI=0;     //Receive Interrupt = 0
   TI=0;    //Transmit Interrupt = 0
   ES=1;          //Serielle Interrupts einschalten
   TMOD=0x26;  //00100110 ins TMOD-Register laden
   EA=1;          //Alle Interrupts aktivieren
}

void GebeDatenAus(unsigned char *array)
{
  int lauf, x=0;
  x=strlen(array);
  
  for(lauf=0;lauf<=x;lauf++)
  {
     SBUF=array[lauf];
     Warte10Us(200);
  }
}
Wäre nett wenn sich das mal jemand anschauen könnte, und evtl nen 
Hinweis für mich hat wieso das ganze nicht läuft ;)

Schonma danke und noch ein schönes Wochenende!
MfG Derdiek

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine "while(strcmp(array,'\0')!= 0)" Schleife funktioniert so nicht, da 
diese Bedingung immer true zurückliefert. Du solltest die Schleife 
lieber so in der Art aufbauen, wenn du die Return Taste (\r) als 
Abschlußzeichen benutzen willst:

unsigned char i = 0;
unsigned char array[30];
unsigned char temp = 0;

SerialInit();
while(temp != '\r')
{
  if (RI == 1)
  {
    temp = SBUF;
    if (temp != '\r')
      array[i] = temp;
    i++;
    RI = 0;
  }
}

"i" kann auch ein char sein, da es ja nie größer wird als die Arraygröße 
(30), was Ram und Rechenzeit spart. Und in deiner GebeDatenAus Methode 
brauchst du "x" auch nicht mit 0 vorzubelegen, da du "x" sowieso als 
erstes gleich mit dem Rückgabewert von strlen() überschreibst. 
Grundsätzlich solltest du das Senden auch per TI Flag steuern und nicht 
per Wartezeit.

Ciao,
     Rainer

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, damit kann ich was anfangen.

Habs jetzt, um andere Fehler auszuschließen, mit ner Int-Variablen 
probiert, ob er überhaupt aufs RI reagiert, und das hat soweit geklappt.
Werd das ganze dann mal so wie von dir gepostet aufs Array übertragen.
Dann solls wohl klappen ;)

Danke, derdiek

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

Bewertung
0 lesenswert
nicht lesenswert
Und wenn du mit Strings hantierst, nicht vergessen den String mit einem 
\0 Zeichen abzuschliessen. Erst dann ist es ein korrekter String.

Autor: Bernhard Spitzer (b_spitzer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach dem Senden (SBUF=Zeichen;) sollte auf das TI-Flag gewartet werden, 
danach TI löschen. Nicht einfach mit einer Wartezeit von 2ms hantieren, 
das geht bei anderen Baudraten schnell schief. Also:
SBUF = Zeichen;
while(!TI);
TI=0;

Der Vergleich auf Stringende (0-Zeichen) geht leichter mit einer 
Do...while-Schleife.
do{
 if (RI)
  { RI=0;
    array[i]=SBUF
    i++;
  }
}while (SBUF !=0);
i=0; // Array-Zähler wieder auf Anfang!

>  return 0;
An wen gibtst Du denn beim beenden von main() was zurück? Läuft bei Dir 
ein Betriebssystem auf dem Controller?? Normalerweise hat main auf einem 
Controller immer eine Endslosschleife!

tschuessle
Bernhard

Autor: Bernhard Spitzer (b_spitzer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> x=strlen(array);
> for(lauf=0;lauf<=x;lauf++)

Noch'n Gedicht: x ist ja die Anzahl Zeichen in dem Array. Die ist in C 
aber statisch, also hier x=30. Danach läuft die FOR-Schleife von 0 bis 
30, also über 31(!!!) Elemente. Damit wird über die Grenzen des Arrays 
gelesen.

unn tschuess
Bernhard

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.