Forum: Mikrocontroller und Digitale Elektronik PIC EEPROM: Falsche Daten geschrieben?


von Patrick K (Gast)


Lesenswert?

Hallihallo!

Ich habe folgendes Problem:
Mit dem unten aufgefuehrten Code soll der EEPROM des PIC beschrieben 
werden. Danach wird die Eingabe mit dem geschriebenen Wert ueberprueft.

Wenn ich, die geschriebenen Daten auslese bekomme ich aber fuer beide 
Adressen die Werte "1" und nicht die, die ich eingetippt habe.

Ich entschuldige mich vorab fuer die Nichtkommentierung des Codes 
aufgrund von Dringlichkeit.
Kann jemand helfen?

Gruesse
1
void Configurate_ID (void)
2
{
3
4
unsigned int8 ConfigOption,ExpIDByte1,ExpIDByte2,ActIDByte2,ActIDByte1;
5
unsigned int8 actualID,expectedID,TimeCounter;
6
7
char c;
8
9
10
11
12
13
  printf("\n\rDo you want to change the Station IDs? Press Y or N   ");
14
15
  TimeCounter = 0;
16
   set_timer1(0);
17
18
   do{
19
      if(get_timer1() > 60000)
20
        {
21
         TimeCounter++;
22
         set_timer1(0);
23
        }
24
   }while((TimeCounter <= 20) && !RCIF);
25
26
27
28
   if(RCIF)
29
   {
30
      ConfigOption = ReadByte();
31
32
      if((ConfigOption == 'y') || (ConfigOption == 'Y'))
33
         {
34
            //RECEIVING EXPECTED ID
35
            printf("\n\rPlease type in the expected ID:  ");
36
            TimeCounter = 0;
37
            set_timer1(0);
38
39
            do{
40
            if(get_timer1() > 60000)
41
            {
42
               TimeCounter++;
43
               set_timer1(0);
44
            }
45
46
            }while((TimeCounter <= 20) && !RCIF);
47
            ExpIDByte1=ReadByte();
48
49
             TimeCounter = 0;
50
             set_timer1(0);
51
52
             do{
53
             if(get_timer1() > 60000)
54
               {
55
               TimeCounter++;
56
               set_timer1(0);
57
               }
58
               }while((TimeCounter <= 20) && !RCIF);
59
               ExpIDByte2=ReadByte();
60
61
               //RECEIVING ACTUAL ID
62
               printf("\n\rPlease type in the ID of the actual station:   ");
63
               TimeCounter = 0;
64
            set_timer1(0);
65
66
            do{
67
            if(get_timer1() > 60000)
68
            {
69
               TimeCounter++;
70
               set_timer1(0);
71
            }
72
73
            }while((TimeCounter <= 20) && !RCIF);
74
            ActIDByte1=ReadByte();
75
76
             TimeCounter = 0;
77
             set_timer1(0);
78
79
             do{
80
             if(get_timer1() > 60000)
81
               {
82
               TimeCounter++;
83
               set_timer1(0);
84
               }
85
               }while((TimeCounter <= 20) && !RCIF);
86
               ActIDByte2=ReadByte();
87
88
89
         }
90
91
         printf("\n\rAct1\t");
92
         WriteByte(ActIDByte1);
93
         printf("\n\rAct2\t");
94
         WriteByte(ActIDByte2);
95
         printf("\n\rExp1\t");
96
         WriteByte(ExpIDByte1);
97
         printf("\n\rExp2\t");
98
         WriteByte(ExpIDByte2);
99
100
         //CONVERT ASCII TO HEX
101
102
         ActIDByte1=ActIDByte1 && 0x0F;
103
         ActIDByte2=ActIDByte2 && 0x0F;
104
         ExpIDByte1=ExpIDByte1 && 0x0F;
105
         ExpIDByte2=ExpIDByte2 && 0x0F;
106
107
         ActIDByte1=swap(ActIDByte1);
108
         ExpIDByte1=swap(ExpIDByte1);
109
110
         actualID = ActIDByte1 || ActIDByte2;
111
         expectedID = ExpIDByte1 || ExpIDByte2;
112
         
113
         printf("\n");
114
         WriteByte(actualID);
115
         printf("\n");
116
         WriteByte(expectedID);
117
118
119
         //WRITING SEQUENCE
120
121
         printf("\nShould IDs be written (y)?   ");
122
          TimeCounter = 0;
123
            set_timer1(0);
124
125
            do{
126
            if(get_timer1() > 60000)
127
            {
128
               TimeCounter++;
129
               set_timer1(0);
130
            }
131
132
            }while((TimeCounter <= 20) && !RCIF);
133
134
             ConfigOption = ReadByte();
135
136
         if((ConfigOption == 'y') || (ConfigOption == 'Y'))
137
         {
138
            write_eeprom(0x01,actualID);
139
            write_eeprom(0x02,expectedID);
140
141
            delay_ms(500);
142
143
144
            //if(EEIF==0)    //Write completed bit
145
            {
146
147
               //Reading and comparing the written IDs
148
               if((read_eeprom(0x02)==actualID) && (read_eeprom(0x01)==expectedID))
149
               {
150
                  printf("\n\r IDs were written successful");
151
152
                  printf("\n\r Expected ID: %u", read_eeprom(0x01));
153
                  printf("\n\r Actual ID  : %u", read_eeprom(0x02));
154
               }
155
               else
156
               {
157
                  printf("\n\rWriting failed");
158
159
               }
160
161
162
163
            }
164
         }

von Severino R. (severino)


Lesenswert?

Hallo Patrick

Ich weiss zwar nicht, weshalb die Werte nicht korrekt ausgegeben werden, 
aber ich möchte Dir allgemeine Tipps geben:

Versuche, den Code auf das Minimum zu reduzieren, um das Problem zu 
zeigen:
z.B.:
1
    write_eeprom(0x01,actualID);
2
    write_eeprom(0x02,expectedID);
3
4
    delay_ms(500);
5
6
    printf("\n\r Expected ID: %u", read_eeprom(0x01));
7
    printf("\n\r Actual ID  : %u", read_eeprom(0x02));

Allerdings steckt wahrscheinlich die Knacknuss gerade in write_eeprom(), 
die Du eben nicht gepostet hast.
Stimmen die Rückgabetypen von read_eeprom() mit dem "%u" überein?

Weiter:
if(EEIF==0)    //Write completed bit
ist das nötig oder nicht? Wartet write_eeprom() bis der Schreibvorgang 
beendet ist?

Ausserdem:
Um welchen PIC handelt es sich?
Um welchen Compiler?
Hast Du das EEPROM mal mit dem Programmer (welchem?) ausgelesen?
Steht da drin was Du erwartest?

von holger (Gast)


Lesenswert?

>         actualID = ActIDByte1 || ActIDByte2;
>         expectedID = ExpIDByte1 || ExpIDByte2;

         actualID = ActIDByte1 | ActIDByte2;
         expectedID = ExpIDByte1 | ExpIDByte2;

von Patrick K (Gast)


Lesenswert?

Hallo Severino.

-Mit dem Programmer habe ichs schon ausgelesen (MPLAB). Und zeigt mir im 
Speicher genau 0x01 an. Komische Sache.
-Es ist ein PIC16F688.
-Ich glaube nicht dass das EEIF Flag von Noeten ist.
-Als Compiler benutze ich den PIC-C Compiler


Schon mal Danke fuer die Tipps!

Auch danke an Holger, ich glaube das koennte auch der Fehler sein...Ich 
habe das auch schon im Kopf gehabt, aber irgendwie nicht ausprobiert...

von holger (Gast)


Lesenswert?

>         actualID = ActIDByte1 || ActIDByte2;

Die Zeile mal übersetzt:

if(ActIDByte1>0 || ActIDByte2>0) actualID=1;
else actualID=0;

Na, dämmert es ?
Was du wolltest ist ein bitweises Oder
von ActIDByte1 und ActIDByte2.
Hat nicht ganz geklappt ;)

von Patrick K (Gast)


Lesenswert?

Hallo Holger..ich habe das jetzt mal probiert...

Er schreibt zwar nun was anderes...aber immer noch nicht das Richtige. 
Er schreibt in beide Adressen "17", wenn ich die Zahlen 30 und 35 
eintippe...

von holger (Gast)


Lesenswert?

>wenn ich die Zahlen 30 und 35 eintippe...

Wenn du 30 eintippst sendest du zwei Bytes:
'3' und '0'

Wenn du 35 eintippst sendest du auch zwei Bytes:
'3' und '5'

Das heisst: Wenn du zwei Zahlen eintippst musst
du zwei Zeichen empfangen. Aus diesen zwei ASCII Zeichen
musst du deinen Wert zusammenbauen bevor du da
was brauchbares fürs EEPROM bekommst.

Google mal nach ASCII Code. Ein bißchen Arbeit
sollst du ja auch noch haben.

von Patrick K (Gast)


Lesenswert?

Ja aber das habe ich doch schon alles gemacht. Hier baue Ich die zwei 
Bytes zusammen:
1
   printf("\n\rAct1\t");
2
         WriteByte(ActIDByte1);
3
         printf("\n\rAct2\t");
4
         WriteByte(ActIDByte2);
5
         printf("\n\rExp1\t");
6
         WriteByte(ExpIDByte1);
7
         printf("\n\rExp2\t");
8
         WriteByte(ExpIDByte2);
9
10
         //CONVERT ASCII TO HEX
11
12
         ActIDByte1=ActIDByte1 && 0x0F;
13
         ActIDByte2=ActIDByte2 && 0x0F;
14
         ExpIDByte1=ExpIDByte1 && 0x0F;
15
         ExpIDByte2=ExpIDByte2 && 0x0F;
16
17
         ActIDByte1=swap(ActIDByte1);
18
         ExpIDByte1=swap(ExpIDByte1);
19
20
         actualID = ActIDByte1 | ActIDByte2;
21
         expectedID = ExpIDByte1 | ExpIDByte2;

von holger (Gast)


Lesenswert?

>Ja aber das habe ich doch schon alles gemacht. Hier baue Ich die zwei
>Bytes zusammen:

Sorry, glatt mal überlesen :(

>         ActIDByte1=ActIDByte1 && 0x0F;

Schon wieder das Ding mit bitweise. Diesmal UND

        ActIDByte1=ActIDByte1 & 0x0F;


Probier doch mal:
         ActIDByte1=ActIDByte1 - '0';
         ActIDByte2=ActIDByte2 - '0';
         ExpIDByte1=ExpIDByte1 - '0';
         ExpIDByte2=ExpIDByte2 - '0';

von Patrick K (Gast)


Lesenswert?

Danke fuer die Hilfe.

Ich habe beide Moeglichkeiten probiert, nur mit diesen wird jetzt nichts 
mehr geschrieben....

von holger (Gast)


Lesenswert?

>            write_eeprom(0x01,actualID);
>            write_eeprom(0x02,expectedID);

>              //Reading and comparing the written IDs
>               if((read_eeprom(0x02)==actualID) && 
>(read_eeprom(0x01)==expectedID))
>               {

Wie soll da auch ein Vergleich zustande kommen
wenn du die Adressen vertauscht ?

von Patrick K (Gast)


Lesenswert?

Das habe ich inzwischen schon behoben...habe ich selbst gemerkt. Nur die 
Zahlen die jetzt ausgegeben werden sind immer noch nicht dir Richtigen

von holger (Gast)


Lesenswert?

>Nur die Zahlen die jetzt ausgegeben werden sind immer noch nicht dir >Richtigen

Wieviele Popel muss man dir aus der Nase ziehen
bevor du sagst welche Zahlen du erwartest und welche
rauskommen ?

Tschüss auf jeden Fall schon mal.
Machs doch alleine.

von Patrick K (Gast)


Lesenswert?

Da ich gerade ziemlich erkaelter bin sinds einige Popel.

Die Zahlen die ich erwarte sind:
Wenn ich 30 Eingebe erhalte ich als Ascii 33 und 30, dann wandel ich 
dass in Hex um. Und diese zwei bytes bringe ich wieder zusammen dass 
sich eine 30 ergibt, die dann in die Adresse geschrieben wird.

von holger (Gast)


Lesenswert?

>         ActIDByte1=ActIDByte1 && 0x0F;
>         ActIDByte2=ActIDByte2 && 0x0F;
>         ActIDByte1=swap(ActIDByte1);

         ActIDByte1=ActIDByte1 -'0';
         ActIDByte2=ActIDByte2 -'0';
         ActIDByte1= 10 * ActIDByte1 + ActIDByte2;

Ist das denn soo schwer ?

von holger (Gast)


Lesenswert?

ActIDByte1=ActIDByte1 -'0';
         ActIDByte2=ActIDByte2 -'0';
         ActIDByte1= 10 * ActIDByte1 + ActIDByte2;
         actualID = ActIDByte1;

Hätte ich jetzt fast vergessen :(

von Patrick K (Gast)


Lesenswert?

Ja, fuer jemanden der in Mexiko sitzt und damit so gut wie keine 
Erfahrungen hat ist das schwer.
Wenn dann auch noch die richtigen Ansprechpartner fehlen und man unter 
Zeitdruck steht ist man umso mehr froh, wenn man hier in diesem Forum 
Hilfe bekommt. Tut mir leid dass dies hier fuer die meisten keine harte 
Nuss ist, aber es gibt eben auch Weichere. Und mit der hab eben ich zu 
kaempfen...

Vielen Dank fuer die Hilfe, ich werds schon hinbekommen.

von Severino R. (severino)


Lesenswert?

Hola Patrick

Du musst zuerst mal herausfinden, ob das Problem im Schreiben ins EEPROM 
oder im Lesen aus dem EEPROM steckt.

Versuch mal Folgendes:
1
    actualID = 50;
2
    expectedID = 60;
3
4
    write_eeprom(0x01,actualID);
5
    write_eeprom(0x02,expectedID);
6
7
    delay_ms(500);
8
9
    printf("\n\r Expected ID: %u", read_eeprom(0x01));
10
    printf("\n\r Actual ID  : %u", read_eeprom(0x02));

Durch die feste Zuweisung eines konstanten Wertes an Deine Variablen 
kannst Du mögliche Fehler durch die Konvertierung des ASCII-Strings in 
einen int ausschalten.
Natürlich kannst Du auch etwas Anderes als 50 und 60 wählen.

Und schau bitte mit dem Programmer nach, was nun im EEPROM steht.

Wenn jetzt alles stimmt, ist das Problem bei der Konvertierung des 
Strings und hat somit nichts mit dem EEPROM zu tun.

Hast Du eigentlich einen ICD2 mit einem PIC16F688-ICD Header? Damit 
könntest Du recht bequem debuggen und die Variablen auslesen.

Und welchen Compiler genau benutzt Du? Den von Hi-Tech?
Woher hast Du die xxxxx_eeprom Funktionen? Dort müsste man herausfinden, 
ob das mit dem EEIF Flag nun nötig ist oder nicht.

von Patrick K (Gast)


Lesenswert?

Hallo Severino!

Also durch den Syntax von Holger und dem Auslesen habe ich 
herausgefunden dass das Schreiben funktioniert. Irgendwas stimmt also 
mit dem Auslesen nicht.

Das Problem hier ist (es ist geschaeftlich) dass ich nur den Picstart 
Plus zur Verfuegung habe. Keine Emulator, nix. Recht muehselig, das 
Ganze.

Die EEPROM Funktionen sind alle im Compiler mit dem Namen PIC-C, PCW 
Compiler C IDE. Mehr Angaben stehen mir nicht zur Verfuegung.

Das Flag brauch ich ja nicht unbedingt. Ich koennte ja auch ne kleine 
Verzoegerung einbauen von ein paar Milisekunden, da es auch 
Geschwindigkeit bei dem Prog nicht ankommt.


Ich habe hier eher das Gefuehl dass es an der Konvertierung liegt und 
ich irgendwie den Ascii "richtig" umwandeln muss...

von Patrick K (Gast)


Lesenswert?

Vielen Dank!

Also mit dem letzten Code von Holger funktionierts!

Jetzt versuche ich mal herauszufinden warum dass bei mir nicht 
klappte...

Vielen Dank nochmals...

von Patrick K (Gast)


Lesenswert?

Ich habe das ganze jetzt einwandfrei hinbekommen.

Ich moechte nur an dieser Stelle an einige Personen apellieren:

Vor Eurem Fachwissen habe ich einen grossen Respekt. Nur solltet ihr 
vielleicht ab und zu dran denken eure die charakterliche und 
zwischenmenschliche Ebene nicht mit der eines uCs zu verwechseln.
Hier schreiben immer noch Menschen, die einfach nur Tipps und Hilfe 
brauchen, keine uCs mit denen man umgehen kann wie man will.

Des Weiteren braucht ihr hier niemanden fuer dumm verkaufen wie mit 
"schonmal gegoogelt?" oder so einem Bloedsinn. Die Leute die hier ins 
Forum schreiben, wissen wohl schon warum. Und ihr habts hier auch nicht 
mit Pestalozzischuelern zu tun (ich will niemandem ggf. zu Nahe treten).

Also ein bisschen mehr Respekt. Wenn Du eine grosse Ahnung von der 
Materie hast, sei Dir das gegoennt. Leider sind die meisten auf 
wichtigeren Ebenen volle Versager...

Denkt darueber nach.

Und nochmals danke an die, die auf nette Art und Weise geholfen haben...

von Severino R. (severino)


Lesenswert?

Hallo Patrick

Ich finde es toll, dass Du einen Feedback gegeben hast.
Auch das gehört nämlich dazu. Viele Leute strengen sich nämlich an, 
nützliche Antworten zu liefern, und investieren auch reichlich Zeit.
Da wäre es ja nur selbstverständlich, dass der Fragesteller 
anschliessend einen Feedback (inkl. Erfolgsmeldung) gibt und sich 
bedankt.

Leider ist es in den Foren ähnlich wie im Auto: Etliche Leute werden 
unpersönlich, unmenschlich und anonym.

Allerdings gibt es leider auch Fragesteller, welche nicht nur die 
Forumsregeln missachten (z.B. Controllertyp im Betreff, überhaupt einen 
möglichst präzisen Betreff), sondern auch dermassen unspezifische Fragen 
stellen, dass man einfach nicht sinnvoll darauf antworten kann. Und dann 
gibt es halt Antworten, welche die Grenze der Ironie überschreiten und 
u.U. auch beleidigend wirken können.

Ganz zu schweigen von Fragen, auf welche z.B. Wikipedia oder auch diese 
Website ausführliche Antworten bereit halten.

Es ist wirklich nicht immer leicht, eine Frage sowohl kurz als auch 
präzise zu stellen.

von maddin (Gast)


Lesenswert?

hey,

das liegt wohl in der natur des menschen, wenn man selber bis zu einem 
gewissen grad in der sache steckt, dann übersieht man zu schnell die 
selbstverständlichkeiten, die dann aber fehlen.

und:

es wird einem hier im forum sehr leicht gemacht, solche fragen stellen 
zu können, dadurch das es frei zugänglich ist, und man jeden sch. 
schreiben kann.

theoretisch könnte man dem schon abhelfen, indem man bei der eröffnung 
eines neuen beitrages einen themenbereich wählen MUSS, unswar einen 
bereich aus "ALLE ARTIKEL" einfach die überschriften, mit dem hinweis 
das man dort zuvor mal gucken sollte, oder man sogar gucken muss.

m.

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.