bei meinem Programm ist es nötig die Textdaten aus dem interenen EEPROM meines MEGA8535 auzulesen. Ich schreib in C mit ICC die Daten folgendermaßen in das EEPROM: #pragma data:eeprom char ms11[20] ="Zeile 1 weiter mit A"; char ms12[20] ="Zeile 1 weiter mit B"; #pragma data:data in meinen Routinen rrufe ich dan lcd_line(*ms11); auf um damit dies abzuarbeiten void lcd_line(char *adr) { u08 zeichen; u08 x; for ( x=1; x<19 ; x++ ) { zeichen = read_eep(0,(*adr+x)); // übergabe des Hig und Lowbytes if (( zeichen != 0)) { // noch keine String-End marke erkannt lcd_char(zeichen); } else { x=21; // Aussprung bei Stringende } } } Auf dem LCD erscheint dann: in Zeile 1 "weiter mit A " und Zeile 2 "el etrmtAZie2WIE " gibt es was besonderes beim Auslesen des EEPROM´s was ich hier falsch mache, oder bin ich für das EEPROM nutzen zu doof ;-(( rene
rene wrote: > gibt es was besonderes beim Auslesen des EEPROM´s was ich hier falsch > mache, oder bin ich für das EEPROM nutzen zu doof ;-(( Fürs EEPROM nicht, aber für Stringbehandlung in C :-) (du hast es herausgefordert) char ms11[20] ="Zeile 1 weiter mit A"; Dieser String hat keine 20 Zeichen, sondern 21 (Du hast das abschliessende '\0' Zeichen vergessen) Lass doch den Compiler das Zeugs abzählen, der macht das zuverlässiger als du: char ms11[] ="Zeile 1 weiter mit A"; ----- for ( x=1; x<19 ; x++ ) { zeichen = read_eep(0,(*adr+x)); // übergabe des Hig und Lowbytes if (( zeichen != 0)) String Inidizierung beginnt in C, genauso wie Arrayindizierung (da Strings ja nichts anderes als Arrays sind) mit 0 und nicht mit 1. Ausserdem: Warum zählst du da mit? Jeder String endet in C mit einem '\0' Zeichen. Das ist dein Aufhänger für die Schleife: x = 0; do { zeichen = read_eep(0,(*adr+x)); // übergabe des Hig und Lowbytes if( zeichen != '\0' ) { ... } x++; } while( zeichen != '\0' ); Den Mambo Zambo, den du da mit den Pointer aufführst versteh ich nicht. Liegt aber wohl daran, dass ich nicht weiss wie dein Compiler Pointer ins EEPROM behandelt.
Hallo kbuchegg wie so Mombo zambo mit Pointern... Geht das den einfacher ist bin für alles was einfacher geht offen. Mit deinem Sourcevorschlag, ging nicht so ganz ;-| habe nun noch mehr "Müll" auf dem LCD.... mit der Suche im Forum bin ich bis dato auch nicht viel weiter gekommen. Ich weiß nicht mehr weiter... was meinst Du mit ..... >String Inidizierung beginnt in C, genauso wie >Arrayindizierung (da Strings ja nichts anderes als >Arrays sind) mit 0 und nicht mit 1. sind Die anfänge von Strings im EEPROM auch markiert?? mein EEPROM sieht in Ponyprog ganz normal aus. zwar ist die erste zelle leer (0xff), aber dan kommen auch gleich die Daten. rene
rene wrote: > Hallo kbuchegg > > wie so Mombo zambo mit Pointern... Geht das den einfacher ist bin für > alles was einfacher geht offen. > Es geht um das hier:
1 | lcd_line(*ms11); |
2 | |
3 | auf um damit dies abzuarbeiten |
4 | |
5 | |
6 | void lcd_line(char *adr) |
7 | {
|
8 | u08 zeichen; |
9 | u08 x; |
10 | for ( x=1; x<19 ; x++ ) |
11 | {
|
12 | zeichen = read_eep(0,(*adr+x)); // übergabe des |
lcd_line kriegt die Adresse eines Strings. Dieser String steht im EEPROM. Nur: Warum wird dann die Funktion so aufgerufen: lcd_line(*ms11); In normalem C ergibt *ms11 den ersten Charcater der in ms11 gespeichert wurde. Das passt alles nicht richtig zusammen, es sei denn auf deinem System werden Pointer ins EEPROM speziell behandelt. Das weiss ich aber nicht. zeichen = read_eep(0,(*adr+x)); // übergabe Das kommt mir auch etwas Spanisch vor. Eine Funktion wie read_eep müsste doch eigentlich die Adresse kriegen von der sie lesen soll. Wenn adr jetzt aber bereits die Adresse im Speicher ist, von der gelesen werden soll, wieso wird dann der Pointer dereferenziert? > Mit deinem Sourcevorschlag, ging nicht so ganz ;-| Das kann ich mir vorstellen. Deine Pointerverrenkungen in diesem Code sind so nicht durchschaubar. > > habe nun noch mehr "Müll" auf dem LCD.... Auch das glaub ich. Meiner Meinung nach stopfst du alles mögliche in die read_eep Funktion hinein, nur nicht die Speicheradresse von der read_eep lesen soll. > was meinst Du mit ..... >>String Inidizierung beginnt in C, genauso wie >>Arrayindizierung (da Strings ja nichts anderes als >>Arrays sind) mit 0 und nicht mit 1. > > > sind Die anfänge von Strings im EEPROM auch markiert?? mein EEPROM sieht > in Ponyprog ganz normal aus. > zwar ist die erste zelle leer (0xff), aber dan kommen auch gleich die > Daten. Und. Wen kümmerst. Der Compiler gibt dir die Adresse an der der String anfängt in ms11. Von dort beginnt der String. Und er endet mit einem '\0' Byte. Wo auch immer das im EEPROM Speicher sein mag. Du übergibst diese Adresse an die Funktion lcd_line .... lcd_line(ms11); ... Die Funktion lcd_line holt sich diese Adresse void lcd_line( char* adr ) und benutzt sie um mittels read_eep genau von dieser Stelle ein Zeichen zu holen read_eep( 0, adr ); (was macht der 0 hier als erstes Funktionsargument? Ich kenne die Funktion read_eep nicht)
Danke für die Antwort... hat mir viel neues gelernt... read_eep(0,xx); Ist eine eigene Funktion, mit der ich eine Adresse im High und Lowbyte übergebe, den diese muss ja auch bei aufruf getrennt dem System übergeben werden. Werde mir die genannten Themen mal genauer anschauen und es noch mal versuchen..... Danke erst mal für die Ausführliche Erklärung. rene
rene wrote: > Danke für die Antwort... hat mir viel neues gelernt... > > read_eep(0,xx); > > Ist eine eigene Funktion, mit der ich eine Adresse im High und Lowbyte > übergebe, den diese muss ja auch bei aufruf getrennt dem System > übergeben werden. Alles klar. Ich hab mir das auf dem Heimweg noch mal durch den Kopf gehen lassen. (Ich rate jetzt ein bischen, da ich wie gesagt nicht sicher bin, wie dein Compiler mit Pointern im EEPROM umgeht. Ich geh halt davon aus, wie ich als Compilerbauer das machen würde). Meiner Ansicht nach, müsste die Funktion so aussehen:
1 | void lcd_line(char *adr) |
2 | {
|
3 | u08 zeichen; |
4 | |
5 | while( ( zeichen = read_eep( adr >> 8, adr & 0xFF ) ) != '\0' ) |
6 | {
|
7 | lcd_char(zeichen); |
8 | adr++; |
9 | }
|
10 | }
|
und aufgerufen wird das
1 | #pragma data:eeprom
|
2 | |
3 | char ms11[] = "Zeile 1 weiter mit A"; |
4 | char ms12[] = "Zeile 1 weiter mit B"; |
5 | |
6 | #pragma data:data
|
7 | |
8 | int main() |
9 | {
|
10 | ...
|
11 | |
12 | lcd_line( ms11 ); |
13 | lcd_line( ms12 ); |
14 | }
|
hi kbuchegg, Das sieht ja super aus und auch kompakt...aber bei der Zeile: while( ( zeichen = read_eep( adr >> 8, adr & 0xFF ) ) != '\0' ) kommt folgendes als Meldung vom Compiler (50): operands of >> have illegal types `pointer to char' and `int' (50): operands of & have illegal types `pointer to char' and `int' woher kommt das `int' soll das vieleicht die 8 und das 0xff sein. Diese habe ich aber nicht als solche Def. Oder übersehe ich hier noch was rene
rene wrote: > hi kbuchegg, > Das sieht ja super aus und auch kompakt...aber > > bei der Zeile: > > while( ( zeichen = read_eep( adr >> 8, adr & 0xFF ) ) != '\0' ) > > kommt folgendes als Meldung vom Compiler > > (50): operands of >> have illegal types `pointer to char' and `int' > (50): operands of & have illegal types `pointer to char' and `int' > Ich dachte mir schon, dass da ein cast notwendig sein wird :-) > woher kommt das `int' soll das vieleicht die 8 und das 0xff sein. Exakt. adr ist ein pointer to char und das adr >> 8 passt ihm nicht. Am besten wäre es, wenn du das Aufteilen der Adresse in ein High Byte und ein Low Byte überhaupt in die Funktion verlagern würdest. Dann würde die Funktion so aussehen: char read_eep( char* Addr ) { u08 HighByte = (u08)(((u16)Addr) >> 8); u08 LowByte = (u08)(((u16)Addr) & 0xFF ); ... weitermachen mit LowByte, Highbyte } Sieht ein bischen wild aus. Die Idee dahinter ist es, aus dem Pointer einen unsigned int zu machen. Damit kann ich dann Bitschieben soviel ich will. Dafür wird dann allerdings der Aufruf viel einfacher: while( ( zeichen = read_eep( adr ) ) != '\0' ) und das ist schliesslich das entscheidende: Das eine Funktion ein Interface zur Verfügung stellt, dass einfach zu benutzen ist. Und noch einfacher als einfach eine Adresse hineinstopfen geht wohl kaum :-)
bin noch nicht zum Testen gekommen, werde es noch machen und dan berichten, aber erst mal vielen Dank für die Müh... rene
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.