Forum: Mikrocontroller und Digitale Elektronik Flackern beim EEprom-Zugriff


von Andy (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits!

Ich habe ein kleines Problem mit meinem Programm. Und zwar will ich
eine LED über ein Poti dimmen. Dazu verwende ich den Mega8 und dessen
ADC Eingang. Außerdem will ich haben, dass nach dem Einschalten der
Spannungsversorgung die LED in der Helligkeit leuchtet, wie beim
Ausschlalten. Dazu schreibe ich alle 8 sek. den Helligkeitswert in das
EEprom.
NUR: Beim Schreiben in das EEprom flackert die LED, d.h. alle 8
Sekunden.

Kann mir jemand sagen, warum das so ist? Mache ich irgendwo einen
Fehler? Ich habe die Datei im Anhang (BASCOM).

Vielen Dank für Eure Hilfe!!

mfg
Andy

von Karl heinz B. (kbucheg)


Lesenswert?

Beim EEprom schreiben muss eine bestimmte Sequenz
eingehalten werden und das Timing ist eher kritisch.
Daher wird BASCOM wahrscheinlich die Interrupts kurzzeitig
abschalten was dein Timing durcheinander bringt.

von johnny.m (Gast)


Lesenswert?

Schau mal ins Datenblatt, wie lange ein Schreibzugriff (ein Byte) auf
das EEPROM dauert. Das ist afaik im ms-Bereich. Wenn Du einen long-Wert
(sind das bei BASCOM auch 32 Bit?) hineinschreibst, dann dauert das
entsprechend länger. Der Compiler muss natürlich auch dafür sorgen,
dass während des Schreibens ins EEPROM keine Interrupts auftreten, so
dass das Programm an sich komplett unterbrochen wird, wenn geschrieben
wird. Und Störungen im Bereich einiger ms kann man durchaus schon
optisch wahrnehmen. Da ich allerdings von BASCOM keine Ahnung habe,
habe ich mir das Programm jetzt nicht genauer angesehen und weiß
deshalb nicht, wie die LED genau angesteuert wird....

von johnny.m (Gast)


Lesenswert?

Hab grad mal nachgeschaut: Die (typ.) Schreib-Zugriffszeit für das
EEPROM liegt bei sage und schreibe 8,4 ms! Wenn man da mehrere Bytes
direkt hintereinander ablegt, dann ist das Programm entsprechend lange
unterbrochen...

von Andy (Gast)


Lesenswert?

Erstmal danke für Eure Antworten.

OK, d.h. wenn ich eine Long-Variable ins EEprom schreibe, nimmt das
schon ca. 32ms in Anspruch. Ist klar, dass das dann flackert.

Wie könnte ich dann eine sinnvolle Sicherung der Helligkeit vornehmen?
Ich wollte schon den ADC-Interrupt nehmen. Aber wenn ich das Poti dann
von null auf hundert drehe, dann wird das EEprom ja 100x beschrieben,
oder? Das wäre auch nicht sinnvoll!

Ich bin für jeden Tipp dankbar!!

mfg
Andy

von johnny.m (Gast)


Lesenswert?

Ich weiß nicht, ob ich das Programm richtig verstehe, aber versuchst Du
da, so was wie eine Software-PWM zur Helligkeitssteuerung zu machen?
Wenn ja, dann wird sich das Problem wahrscheinlich nur mit einer
Hardware-PWM umgehen lassen. Die ist nämlich unabhängig vom
Programmablauf, da der Timer den zugehörigen Pin selber toggelt.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Du könntest die Betriebsspannung überwachen, und sobald diese unter
einen bestimmten Wert fällt, deine Helligkeit sichern.
Weiterhin könntest du überprüfen, ob sich die Potistellung geändert
hat. Das wird in relativ grossen Abständen gemacht, und dann muß der
Poti-Wert auch über einen gewisesn Zeitraum konstant bleiben, um
gesichert zu werden.

von Andy (Gast)


Lesenswert?

Ja, ich mache die Helligkeitssteuerung über Software-PWM.

OK, dann muss ich es wohl über HW-PWM machen. Nur habe ich damit keine
Erfahrungen. Gibt es irgendetwas, was ich beachten muss? Ist das sehr
schwierig??

THX

von johnny.m (Gast)


Lesenswert?

Das ist im Prinzip leichter als eine Soft-PWM, weil Du den Timer einmal
startest und nur von Zeit zu Zeit mal einen neuen Wert ins
Compare-Register schreiben musst und ansonsten keine Aktionen im
Programm durchführen musst. Ansonsten macht der Timer nämlich alles
selber. Du müsstest Dir "nur" im Datenblatt die entsprechenden Infos
zusammensuchen... Das ist da allerdings recht ordentlich tabellarisch
zusammengefasst.

BTW:

> Incr Zaehler
> If Zaehler = 1 Then
>     Zaehler = 0

Das kommt mir selbst als BASCOM-Unwissender etwas komisch vor. Wenn
Zaehler beim Einsprung in die Routine 0 ist, wird um 1 erhöht,
abgefragt, ob 1 ist (was ja dann immer der Fall sein dürfte) und wieder
auf 0 gesetzt. Die drei Zeilen kannste also vermutlich weglassen, es sei
denn, ich habe das Konzept irgendwie nicht durchschaut...

von johnny.m (Gast)


Lesenswert?

Ach ja, Du musst die LED dann natürlich auch an den entsprechenden Pin
hängen. Timer 0 hat beim Mega8 leider keine Compare-Einheit, deshalb
müsstest Du dann entweder Timer 1 oder 2 nehmen. Dann die LED an den
entsprechenden Compare-Ausgang (OC1A, OC1B oder OC2), den jeweils
korrekten PWM-Modus einstellen und los gehts...

von Andy (Gast)


Lesenswert?

@ johnny:

Du hast schon recht: Diese Abfrage ist sinnlos. Ich habe hier vorher
einen anderen Wert als 1 stehen gehabt, um das EEprom nicht zu oft zu
beschreiben. Ich habe dann nur "testhalber" 1 hingeschrieben.

OK, dann werde ich das ganze mit HW-PWM versuchen! Vielen Dank für die
Hilfe!!!


mfg
Andy

von Peter D. (peda)


Lesenswert?

Während des EEPROM-Schreibens muß überhaupt kein Interrupt disabled
werden, sondern nur für die Dauer der 2 Befehle, die das Schreiben
einleiten.

Du brauchst also nur das EEPROM-Schreiben selber programmieren.

Ich würde allerdings auch noch vor dem Schreiben erstmal vergleichen,
ob schon das richtige drinsteht, dann sparst Du massig Schreibzyklen.


Peter

von Andy (Gast)


Lesenswert?

@ PeDa
Und wie kann ich das EEprom-Schreiben selber programmieren? Hab davon
überhaupt keine Ahnung!

Wäre toll, wenn du mir helfen könntest!

Andy

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>Und wie kann ich das EEprom-Schreiben selber programmieren? Hab davon
>überhaupt keine Ahnung!

Da könnte ein Blick ins Datenblatt helfen. Dort ist beschrieben, wie
man sowas macht; allerdings in Assembler oder C.

von johnny.m (Gast)


Lesenswert?

Da müsstest Du das Datenblatt bemühen, da steht das detailliert drin.

Ich gehe aber mal davon aus, dass das Problem ein ganz anderes ist
(nachdem ich mir Dein Programm doch mal näher angeschaut habe):
Du schreibst innerhalb eines Interrupt-Handlers mehrere Bytes direkt
hintereinander ins EEPROM, was, wie oben schon angedeutet, einige -zig
Millisekunden dauert. Da während eines Interrupt-Handlers die
Bearbeitung aller anderen Interrupts (inklusive desjenigen, der die LED
umschaltet) deaktiviert ist, ist es nicht der EEPROM-Zugriff an sich,
der das Flackern verursacht, sondern eben die Tatsache, dass Du Dir
durch den Zugriff im Interrupt-Handler das Programm blockierst. Ich
vermute auch, dass BASCOM so schlau ist wie Peter und nach den
Schreib-Befehlen die Interrupts wieder freigibt. Wenn Du das EEPROM im
Hauptprogramm schreibst, dürfte sich das Problem erledigen.

von Peter D. (peda)


Lesenswert?

Nun, ganz genau so, wie es im Datenblatt angegeben ist:

- Adreßregister setzen
- Datenregister setzen
- Interrupt sperren
- Schreibbefehle ausgeben
- Interrupt freigeben
- pollen bis Schreibbit auf fertig steht

Und das für jedes Byte, d.h. einen mehrbytigen Wert erst in ein
Bytefeld schreiben, unter C nennt sich das ne Union.


Peter

von Peter D. (peda)


Lesenswert?

Da hat Johnny voll recht.

EEPROM schreiben im Interrupt ist natürlich verboten !


Peter

von Andy (Gast)


Lesenswert?

@Johnny
Daran hab ich auch schon gedacht, aber nur wird mir dann das EEprom
nach ein paar Stunden verrecken, oder. Es hält ja nur 100.000 Schreib-
und Lesezyklen aus, oder?

Oder ich lasse im Hauptprogramm ein Zählvariable mitlaufen, und erst
bei Erreichen eines Wertes schreibe ich ins EEprom.

Was sagst du??

von johnny.m (Gast)


Lesenswert?

Du brauchst nur in der Interrupt-Routine, in der Du sonst das EEPROM
geschrieben hast, eine (Bit-) Variable zu setzen, die Du im
Hauptprogramm abfragst. Wenn sie gesetzt ist->EEPROM schreiben und
Variable wieder löschen.

von Andy (Gast)


Lesenswert?

OK, das muss ich gleich testen. Danke!

von Andy (Gast)


Lesenswert?

... flackert trotzdem!

von johnny.m (Gast)


Lesenswert?

BTW:

> Es hält ja nur 100.000 Schreib- und Lesezyklen aus, oder?

Nein, es hält mindestens 100000 Schreib- Lösch- Zyklen aus. Das
Lesen hat keinen Effekt auf die Lebensdauer, wäre auch schlimm. Das
heißt aber auch nur, dass ATMEL diese Anzahl garantiert, in der
Realität der Wert aber sicher weit darüber liegt. Wenn Dein EEPROM
schon nach 99999 Lösch-Schreib-Zyklen den Geist aufgibt, dann muss
ATMEL Dir einen neuen µC schenken, vorausgesetzt, Du kannst das
nachweisen, dass es tatsächlich nur 99999 waren....

von Michael Wilhelm (Gast)


Lesenswert?

Und die Schreib-Löschzyklen beziehen sich auf "eine" Zelle. Wenn du
nach X Schreibzyklen auf eine andere Zelle wechselst, hast du bei der
auch wieder 100000 Schreib-Löschzyklen.

MW

von johnny.m (Gast)


Lesenswert?

> ... flackert trotzdem!

Dann ist BASCOM wohl doch nicht so schlau wie ich dachte. Ich weiß
schon, warum ich in C und Assembler programmiere (Tschulligung, der
Kommentar musste jetzt sein;-). Also deaktiviert BASCOM anscheinend
tatsächlich für die komplette Dauer des Schreibvorganges das I-Bit...

Dann wirst Du wohl doch nicht umhin kommen, es entweder mit einer
HW-PWM zu versuchen, oder tatsächlich dass EEPROM-Schreiben selber zu
programmieren. Beides bedeutet allerdings ein Studium des Datenblattes
an den entsprechenden Stellen.

Übrigens: Eine Soft-PWM ist zwar nett zum Lernen, wird aber eigentlich
i.d.R. nur dann eingesetzt, wenn eine HW-PWM aus irgendwelchen Gründen
nicht möglich ist (keine Compare-Einheit frei, zu viele Kanäle
erforderlich...). Der Mega8 hat 3 PWM-Kanäle (1 8-Bit vom Timer 2 und
zwei mit je max. 16 Bit vom Timer 1). Da sollte doch was möglich
sein...

@Michael:
Genau! Man muss dann nur irgendwo (natürlich ebenfalls im EEPROM)
ablegen, in welcher Zelle man grad ist (Zähler).

von Läubi (Gast)


Lesenswert?

Mal nur interessehalber... wenn der Poti eh den Wert der PWM vorgibt,
warum musst du dann den alten wert speichern?
Wenn du beim Programmstart den Potiwert einliest, hast du ja den
"alten" Wert wenn der Poti nicht bewegt wurde... wurde es bewegt,
änderst du den Wert eh beim nächsten inlesen auf den neuen Wert...

von inoffizieller WM-Rahul (Gast)


Lesenswert?

@Läubi: Klasse Einwand! Das EEPROM durch Reibung zu ersetzen...

von Karl heinz B. (kbucheg)


Lesenswert?

Das ist das eine.
Das andere ist:
Bevor man einen neuen Wert schreibt, sollte man den alten
Wert erst mal auslesen und feststellen ob ein Schreiben
überhaupt notwendig ist. Sowas verlängert die Lebensdauer
des EEprom ungemein.

von Thomas O. (Gast)


Lesenswert?

und ins EEPROM schreiben braucht man auch erst wenn das µC abgeschalten
werden soll.

Ich würde es so machen Poti-Wert vom ADC ins SRAM schreiben und den ADC
auch die Betriebsspannung messen lassen wenn diese dann runtergeht weil
die Spannungsversorgung ausgeschalten wurde schreibts du die Daten erst
ins EEPROM. Die Abfrage ob sich was geändert hast kannste dir dann auch
sparen, weil das Schreiben ins SRAM auch so lange dauern wird wie die
Abfrage mit dem Sprungbefehl selbst.

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.