Speichermanagement

Gast #285138
Lesenswert?
• ▲
▼
Hallo Leute!

ICh habe das Prob das mein Atmeg32 keine Zeichenkette länger als 4
Zeichen (3Buchstaben + \0) speichert. Ab dem vierten Zeichen fehlt ihm
das Schlusszeichen, was zu einem Wirrwarr am Display führt. Dass es die
SPeicherung ist habe ich herausgefunden indem ich eine Funktion
geschrieben habe die eine STring zerstückelt und jedes Zeichen extra
ausgibt. DAs funktoiniert auch nicht.

Könnt ihr mir helfen?!

Ps: Atmeg32 3,6864 Mhz
Gast #285140
Lesenswert?
• ▲
▼
Man sollte dazu sagen, dass das Programm einfach nur einen gespeicherten
String auf dem Display ausgeben sollte

Das steht im main file

char text[]="Keb";
print(text);

im header File steht folgendes:

void print(char buffer [])
{
for ( int i = 0; buffer [i] !='\0'; i++)
    data(buffer[i]);
}

void data(unsigned char data)
{
buisy();
unsigned char data1 = data;           // daten geseichert
portx = (0x1f & (data>>4)|(1 << rs));           // rechtschieben
enable();
portx = (0x1f & ((data1))|(1 << rs));             // ausgabe sicherung
enable();
}

der Befehl busy ist einfach nur dazu da, um zu warten, genau wie enable
;)

MfG

Saschisch
Gast #285141
Lesenswert?
• ▲
▼
void print(char buffer [])
{
for ( int i = 0; buffer [i] !='\0'; i++)
    data(buffer[i]);
}
^... mach mal anstatt '\0' einfach "\0" (oder 0x00 oder so^^).
Ich weiß zwar nicht, ob Single- und Doublequotes so gesondert behandelt
werden, aber n Versuch ist es ja wert.
Gast #285147
Lesenswert?
• ▲
▼
Wie hast du festgestellt, dass du nur 3 Zeichen lange Strings speichern
kann?
Compilierst Du jedes mal neu oder änderst Du die Zeichenkette in text[]
im Laufe des Programms?
Falls letzteres, Das Feld text[] ist nur 4 Bytes lang ( entspricht 3
Zeichen + \0).
Gast #285149
Lesenswert?
• ▲
▼
Ich bin bei den Compiler Geschichten eher schwach auf der Brust muss ich
zugeben...

Was ist ein avr-objcpy??

Ich habe das herausgefunden indem ich versucht habe vor dem compilieren
4 Zeichen bzw 5 auszugeben und es geht einfach nicht er zeigt nur
unwillkürliche Zeichenfolgen am Display an

MFG

Saschisch
Gast #285153
Lesenswert?
• ▲
▼
@Birger:

Nein, data ist ein char (das dann auf unsigned gecastet wird).


@Matthias: Das ist für char text[]="Keb"; richtig. Wenn ich das aber
richtig verstanden habe, wird danach versucht sowas wie

text[4] = 'b';
text[5] = 'l';
text[6] = 'a';
text[7] = '\0';

zu machen. Und das geht dann schief.

Oder hab' ich das was falsch verstanden?
#285156
Lesenswert?
• ▲
▼
Saschisch

Ich hab mir nochmal Deinen anderen Thread angesehen.

Du schreibst darin, dass Du den Text "Servas"
ausgeben moechtest und am Display aber der
Text
  evs!$%"&/&_

kommt.

Gilt das noch?
Bei Vergleich der beiden Strings fallt naemlich
auf, dass da nicht wie du hier behauptest, die
ersten 3 Zeichen ausgegeben werden, sondern immer
jeder 2.te. Das ist aber eine andere Diagnose und
man muss damit nach anderen Ursachen suchen.

Bitte bestaetige!
#285157
Lesenswert?
• ▲
▼
Poste auch noch mal den kompletten Code.
Speck ihn aber ab, so dass nur noch die tatsaechlich
gebrauchten Funktionen drin vorkommen (inklusive aller
Hilfsfunktionen). Allerdings wichtig: bitte vollstaendigen
Code. Theoretisch muss jemand anders in der Lage sein, Deinen
Code von hier zu kopieren, ihn in seinen Compiler zu stecken
und das ganze dann ausfuehren koennen.
Gast #285158
Lesenswert?
• ▲
▼
Danke nochmal!

Hier die main.c:

#include<avr/io.h>
#include<avr/delay.h>
#include "lcd.h"           // eigene lcd lib getester mit atm16 alle
ports



int main (void)
{
char text[]="Keb";

init();



pos(1,1);
print(text);          // ausgabe string
pos(2,1);
run(20);
print("Servas Text")            // ausgabe string
run(20);


for(;;){ }                            //endlosschleife

}

hier die lcd.c:

#include<avr/io.h>
#include<avr/delay.h>
#include<string.h>

#define ddrx DDRA
#define portx PORTA
#define db4 PINA0
#define db5 PINA1
#define db6 PINA2
#define db7 PINA3
#define rs  PINA4
#define rw  PINA5
#define en   PINA6
#define led PINA7


void delay(void);                   // 3 takte verzvgerung
void delay5ms(void);                 // 5 ms verzögerung
void enable(void);                  // erzeugen des enable puls
void buisy(void);                   // warten bis bereit(nur durch
zeitverzvgerung)
void comm(unsigned char comm);            // schreibt commando
void data(unsigned char data);            // schreibt daten
void init(void);                    // initialisiert display
void clear(void);                   // löscht display
void pos(unsigned char l,unsigned char p);       // zeile spalte   1/2
1-24
void print(char buffer []);                      // gibt string aus
void drucken(char buffer2 [],int x,int y);
void boot(unsigned char zeichen,unsigned char  zahl
    ,unsigned char  zeile,unsigned char  sp);
     //zeichen anzahl durchgänge  zeile / spalte)
void run(char ms100);


// drei takte warten
void delay(void)
{
asm volatile(  "nop\n\t"
        "nop\n\t"
               "nop\n\t"::);}

//enable ein aus
void enable(void)
{
portx |= (1 << en);        // setzt bit
delay();
portx &= ~(1 << en);         // lvscht Bit
}


void delay5ms(void)
{
// inline asm warteschleife
asm volatile(

                                    "push R16"            "\n\t"
                                    "push R17"            "\n\t"
                  "ldi  R16, 0x25"      "\n\t"
        "WGLOOP0:""\n\t"    "ldi  R17, 0xA5"      "\n\t"
        "WGLOOP1:""\n\t"     "dec  R17"            "\n\t"
                        "brne WGLOOP1"        "\n\t"
                        "dec  R16"            "\n\t"
                        "brne WGLOOP0"        "\n\t"

                        "pop R16"              "\n\t"
                                    "pop R17"
    "\n\t"::);}





// wartet bis lcd bereit
void buisy(void)
{
_delay_ms(15);

}


// sendet comando --- rs nicht gesetzt

void comm(unsigned char comm)
{
buisy();
unsigned char comm1 = comm;
portx = (0x0f & (comm>>4));
enable();
portx = (0x0f & (comm1));
enable();

}



// sendet daten    -- rs gesetzt


void data(unsigned char data)
{
buisy();
unsigned char data1 = data;           // daten geseichert
portx = (0x1f & (data>>4)|(1 << rs));           // rechtschieben
enable();
portx = (0x1f & ((data1))|(1 << rs));             // ausgabe sicherung
enable();
}

void init(void){

ddrx  = 0xff;
portx = 0xff;

// 15 ms warten

unsigned char d= 10;
do{ --d;
  delay5ms();

  }while(d  != 0 );


// drei mal 8 bit initialisieren
portx = (0b00000011);
enable();
delay5ms();
enable();
delay5ms();
enable();

// 4 bit modus aktivieren
delay5ms();
portx = (0b00000010);
enable();
delay5ms();

// sachen einstellen
comm(0b00101000);          //2zeilig 5*8
delay();
comm(0b00001000);
delay();
comm(0b00000001);
delay();
comm(0b00000010);
delay();
comm(0b00001100);
// display lvschen
}



void clear(void)
{
comm(0b00000001);
pos(1,1);
}


void pos(unsigned char l,unsigned char p)
{
unsigned char pos = 0b10000000;
if(l==1){
    pos |= p-1;
      }
if(l==2){
        p =+40;
    pos |= p;
      }
comm(pos);


}



//
void print(char buffer [])
{
for ( int i = 0; buffer [i] !='\0'; i++)
    data(buffer[i]);
}

void boot(  unsigned char zeichen,unsigned char  zahl,
      unsigned char  zeile,unsigned char  sp)
{
do{
unsigned char spalte= sp;
zahl = zahl-1;
_delay_ms(100);
pos(zeile, spalte);
print("      ");
pos(zeile,spalte);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);
_delay_ms(100);
data(zeichen);

  }while(zahl != 0);

}

void drucken(char buffer2 [],int x,int y)
{
pos(x,y);
int i=0;
while(i<=strlen(buffer2))
{

print(buffer2[i]);
y=y+1;
pos(x,y);
i=i+1;
}
}


/*void drucken(unsigned char *p)
{
  do
    {
    data(*p);
    p++;
    }
    while (*p!='\0');

}
*/

void run(char ms100)
{
unsigned char d= ms100;
do{ --d;
  _delay_ms(100);

  }while(d  != 0 );
  portx |= (1 << led);        // setzt bit
  d= ms100;
do{ --d;
  _delay_ms(100);

  }while(d  != 0 );
     portx &= ~(1 << led);         // löscht Bit

}


Das sollte so wie es ist keinen Compiler Fehler auswerfen bzw. gibt es
bei mir keinen aus:)

MfG

Saschisch
Gast #285159
Lesenswert?
• ▲
▼
Deine Funktion "print(char buffer [])" erwartet die Adresse einer
Zeichenkette. Beim zweiten Aufruf hilft Du ihr aber eine
Zeichenkettenkonstante über.
Stichwort: Übergabe eines Feldes als Parameter an eine Funktion.
kbuchegg oder Matthias kennen sich mit diesen feinheiten sicher besser
aus als ich.
#285161
Lesenswert?
• ▲
▼
Das passt schon.

Ich hab den Code mitlerweile im Simulator mit
Hapsim am laufen und kann das geschilderte Verhalten
so nicht beobachten.

Der Text kommt wie erwartet mit einer kleinen
Feinheit:
Nach dem Pos(2,1) wird das erste 'S' von
"Servus Text" nicht richtig ausgegeben(*), alles
andere kommt so wie erwartet. Fuer dieses Verhalten
hab ich zur Zeit noch keine Erklaerung.

Benutze den avr-gcc

(*) Anstelle des S kommt einfach ein Leerzeichen. Kann ich
nicht erklaeren. Ich habs bis auf Portebene im Simulator
nachvollzogen, die Ausgabe duerfte stimmen.
Hmm. So wies aussieht, wird nachdem das Display auf die 2.-te
Zeile gesetzt wird, das erste ausgegebene Zeichen verschluckt.
Koennte auch ein Fehler im Hapsim sein.

Wie gesagt: prinzipiell funktioniert der Code. Zumindest tritt
das beschriebene Verhalten bei mir nicht auf.
Gast #285162
Lesenswert?
• ▲
▼
@ KArl Heinz:

Die erste Zeile wird bei dir korrekt ausgegeben?

Hast du keine Compiler Warnungen?

Das mit dem S ist wieder bei mir nicht ;)
Ich sehe die zweite Zeile perfekt und ohne Probleme ):

Aber das Übergeben von diesen verdammten verrückten Strings bösewerd

Naja ich muss das bald fertig haben... also werde ich halt nicht
schlafen :)

OK, ich gebe in meinem MAKE File die Taktfrequenz an.

MfG

Saschisch
#285163
Lesenswert?
• ▲
▼
Compiler-Warnungen hab ich 3

2 davon kannst Du ignorieren (musst Du aber nicht). Die 3.te ist
allerdings schwerwiegend.
Keine von den 3-en hat allerdings mit Deinem Problem zu tun:

../LCD.c:74: warning: suggest parentheses around arithmetic in operand
of |
../LCD.c:76: warning: suggest parentheses around arithmetic in operand
of |
../LCD.c:189: warning: passing arg 1 of `print' makes pointer from
integer without a cast

Die ersten beiden beziehen sich auf:

portx = (0x1f & (data>>4)|(1 << rs));           // rechtschieben

gcc schlaegt vor, dass mit Klammern eindeutig
festgelegt wird in welcher Reihenfolge & und |
abgearbeitet werden.

Die 3-te schwerwiegende:

void drucken(char buffer2 [],int x,int y)
{
  ...
  print(buffer2[i]);

Da hat er recht. Das wird so nichts.
Da wirst Du nochmal druebergehen muessen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren