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


von M. D. (derdiek)


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:
1
//Teilweise was weggelassen
2
3
void Warte10Us(int);
4
void SerialInit();
5
void GebeDatenAus(unsigned char*);
6
7
int main(void)
8
{
9
   int i=0, anzahl=0;
10
   unsigned char array[30];
11
   
12
   SerialInit();
13
   while(strcmp(array,'\0')!= 0)
14
   {
15
      if (RI==1)
16
      {
17
         array[i]=SBUF;
18
         i++;
19
         RI=0;
20
      }
21
   }
22
   GebeDatenAus(array);
23
   return 0;
24
}
25
void SerialInit() //8-Bit Auto-Reload 9600 Baud
26
{
27
   EA=0;          //Alle Interrupts deaktivieren
28
   TH1=0xFD;   //FD=253, Wert gültig für 9600 Baud bei 11,059 Mhz
29
   SCON=0x50;   //01010000 ins SCON-Register laden -> 8Bit Auto-Reload
30
   TR1=1;   //Counter starten
31
   RI=0;     //Receive Interrupt = 0
32
   TI=0;    //Transmit Interrupt = 0
33
   ES=1;          //Serielle Interrupts einschalten
34
   TMOD=0x26;  //00100110 ins TMOD-Register laden
35
   EA=1;          //Alle Interrupts aktivieren
36
}
37
38
void GebeDatenAus(unsigned char *array)
39
{
40
  int lauf, x=0;
41
  x=strlen(array);
42
  
43
  for(lauf=0;lauf<=x;lauf++)
44
  {
45
     SBUF=array[lauf];
46
     Warte10Us(200);
47
  }
48
}
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

von R. W. (quakeman)


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:

1
unsigned char i = 0;
2
unsigned char array[30];
3
unsigned char temp = 0;
4
5
SerialInit();
6
while(temp != '\r')
7
{
8
  if (RI == 1)
9
  {
10
    temp = SBUF;
11
    if (temp != '\r')
12
      array[i] = temp;
13
    i++;
14
    RI = 0;
15
  }
16
}

"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

von M. D. (derdiek)


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

von Karl H. (kbuchegg)


Lesenswert?

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

von Bernhard S. (b_spitzer)


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

von Bernhard S. (b_spitzer)


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

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.