erstellt 12.06.2010
Atmega 8 speichert im Eeprom
Zunächst einmal , was überhaupt ist ein Eeprom ?
Also der Begriff kommt aus dem Englischen und ist die Abkürzung für
  (Electrically Erasable Programmable Read-Only Memory ) was soviel heißt wie
Elektrisch Programmier und Löschbarer nur Lese Speicher.
Die Funktion kann man sich in etwa vorstellen wie mehrere nebeneinander gestellte Batterien,
die wenn sie geladen sind den Wert 1  und wenn sie leer sind den Wert 0 beinhalten.
Da Batterien sich mit der Zeit selber entladen würden sie auch mit der Zeit ihren Inhalt also die Werte verlieren , ganz genau  so ist es auch beim Eeprom,
nur dauert es da etwas länger bis zu mehrere Jahre.
Und wozu braucht man  Eeproms ?
Man benötigt Eeprom's um dauerhaft Werte speichern zu können, also so das auch eingestellte Werte z.B. nach dem Aus und wieder Einschalten der
Versorgungsspannung  noch vorhanden bleiben.
Man denke an eine Uhr in der ich das  Datum einstelle , um nicht nach jedem erneuten einschalten das Datum neu eingeben zu müssen werden solche Werte
dauerhaft im Eeprom  gespeichert.
Der Atmega 8 hat einen Eeprom Speicher von 512 Byte, die minimale Anzahl der Schreib-Lesezyklen beträgt 100 000.
Beachten sollte man das dass Schreiben ins Eeprom eine gewisse Zeit in Anspruch nimmt , in etwa 9 Millisekunden dass sollte der Programmierer in seinen Programm mit einplanen.
Um einige Versuche mit dem EEprom Speicher zu unternehmen, hab ich eine kleine Schaltung erstellt, die auch zu andere Zwecke benutzt werden kann.
Die Schaltung besteht aus einem Atmega 8 Mikroprozessor  mit angeschlossenen Display und einer SPI Schnittstelle über den der Atmega programmiert wird.
Die Stromversorgung wird über einen Festspannungsregler 78L05 auf konstante 5 V gehalten.
Um den Aufwand gering zu halten benutze ich zur Stromversorgung ein altes ausgedientes Stecker Netzteil wie sie auch zum laden von Handys benutzt werden.
Davon hat man ja meistens noch einige zu Hause rumliegen.
Zusätzlich noch als Signalgeber einen Piezo und einigen Leuchtdioden .
Der Trimmer  P1 dient zur Kontrasteinstellung des Displays , R6 ist der Vorwiderstand für die Display Hintergrundbeleuchtung.
INT0 und INT1 sind zwei Jumper (Jumper offen ) die zu Testzwecke geschlossen werden können, wird in diesem Versuch aber nicht benutzt.
Zusätzlich wurde eine Verbindung vom PIN B. 2 des Atmega 8 zur Hintergrundbeleuchtung des LCD Moduls geschaffen um die Hintergrundbeleuchtung innerhalb
des Programmablaufs ein bzw. auszuschalten ,um  bei einem möglichen Batterie betrieb den Stromverbrauch so niedrig
 wie möglich zu halten.
Zusätzlich wurde noch ein Taster angebracht um die im EEprom gespeicherten Werte wieder löschen zu können.
Im nachhinein hab ich mich entschlossen der Schaltung noch einen Akku zu spendieren, damit die Schaltung notfalls auch ohne Netzversorgung läuft.
Hier die dazugehörige Platine, der Atmega versteckt sich hinter dem Display .
Auf der rechten Seite befindet sich die Pragrammierschnittstelle in Form eines 9 poligen SUB-D Stecker
wobei von den 9 Polen allerdings nur 5 benötigt werden.
Habe mir aber angewöhnt bei allen meinen Schaltungen  aus Kompatibilitätsgründen  den gleichen Stecker zu verwenden.
Und  da bietet sich dieser Stecker an weil er auch bei PC's eine Standardschnittstelle war , zumindest bis  die neuen USB Schnittstellen auf dem Markt kamen.
In den heutigen modernen PC's sind diese  kaum noch zu finden, deshalb liegt bestimmt noch bei manch einem Zuhause dieser Stecker in irgend welchen Wühlkisten herum.
Die kleine Platine die aufgesteckt wurde ist ein 1 Kanal Funkempfänger somit ist man auch in der Lage über Funk einen Befehl an den Atmega zu senden.
Der Taster in der Mitte der Platine dient zum löschen des Eeproms.
Oben links über dem Display befindet sich links der 5 Volt Festspannungsregler und rechts davon eine Steckbrücke ( Jumper )zum unterbrechen der Stromversorgung.
Hier soll  versucht werden Daten im Internen Eeprom vom Atmega 8 zu speichern und wieder auszulesen.
Generell gibt es verschieden Möglichkeiten Daten im internen EEprom zu speichern.
Eine Möglichkeit ist es direkt eine Variable als EEprom Variable zu deklarieren , damit werden die Daten innerhalb des Programms direkt in der Variable abgespeichert
und liegen damit schon im EEprom .
Die andere Möglichkeit besteht darin die Befehle "WriteEeprom" und "ReadEprom" zu benutzen.
Zunächst befassen wir uns mit der Epromvariable.
Die Epromvariable  ist keine echte Variable sondern nur ein Synonym dafür,deshalb gelten für diese Quasivariable nicht die gleichen Gesetzmäßigkeiten wie für eine echte Variable.
Einige der Anweisungen funktionieren einfach nicht mit der Eprom Variablen. Um also den vollen Funktionsumfang bei der Programmierung zu erhalten bedienen wir uns eines Tricks
indem wir die Eprom Variable immer erst in eine LocaleVariable kopieren , dann kann sie bearbeitet werden  um sie dann anschließend wieder zurück zu kopieren.
Nachfolgend die grundsätzliche Vorgehensweise:

Programmzeile Beschreibung
Dim Eprom_speicher As Eram Byte Als erstes muss diese Variable  folgendermaßen definiert werden
Dim Local_speicher  As Byte    Dann definieren wir noch eine Locale ( Normale ) Variable
Do Schleifenanfang
 Local_speicher = Local_speicher + 1      Den Wert in der Varable E um 1 aufaddieren
Eprom_speicher = Local_speicher          Wert von Variable E (SRAM) in Variable E_Speicher (EEprom) kopieren
Waitms 10      Zeit zum Schreiben ins EEprom lassen
Local_speicher = Eprom_speicher         Wert von EEprom wieder ins SRam kopieren um es anzuzeigen zu können
Waitms 10
Zeit zum kopieren lassen
Cls  Display löschen
Lcd Local_speicher           Wert am Display anzeigen lassen
Waitms 200      Pause damit Wert angezeigt werden kann 
loop


Das Komplette Programm erstellt mit Bascom welches je nach Bedarf geändert werden kann :
Funktion
Nach dem  Einschalten des Atmega's leuchtet zuerst die grüne Led für ca 6 Sekunden und verlöscht dann wieder anschließend wird ständig die Hauptschleife
durchlaufen und am Eingang  Pin D.0 abgefragt ob ein Signal vom Funkempfänger vorhanden ist, gleichzeitig blinkt die Rote Led als Funktionskontrolle .
Sollte ein Funksignal empfangen werden wird  die Hintergrundbeleuchtung des Displays eingeschaltet und ein Pieps Ton ausgegeben anschließend wird die Anzahl
der Empfangenen Funksignale auf dem Display angezeigt und alle drei Led's blinken für eine gewisse Zeit.
Nach dem das blinken der drei Led's beendet ist, blinkt wieder die Rote Led und die Schaltung ist wieder Betriebsbereit.
Während das blinken der Rote Led kann jederzeit die Taste gedrückt werden um die Anzahl der eingegangen  Meldungen zu löschen.
Ansonsten bleibt die Anzahl der Meldungen auch enthalten wenn die Betriebsspannung zwischenzeitlich ausgeschaltet wurde.  
Programmzeile Beschreibung
$regfile "m8def.dat" Definiert den Atmega als Atmega 8
$crystal = 1000000   Taktfrequenz auf 1 Mega sezen (Standard)
Config Lcd = 16 * 2   definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , Rs = Portc.5 , E = Portc.4 Konfiguration der Displayanschlüsse
Ddrb = &B00000011      Port B.0 und B.1 als Ausgang setzen
Ddrd = &B11000000    Port D.6 und D.7 als Ausgang sezten
Portb = &B00000001   Pull Down setzen für Pin B.0
Portd = &B00001100    Pull Down setzen für Pin D.2 und D.3
Timer1 konfigurieren
Tccr1a = &B01000000
Compare1a = 70 Vergleichswert
Variable definieren
Dim A As Byte  Für Alarmschleife  
Dim Ee_prom As Eram Byte   EEprom Variable definieren   
Dim S_ram As Byte            Sram (Standard)Variable definieren
Voreinstellungen
Cls Display löschen
Lcd "Version XX" Text ausgeben  
Portd.6 = 1 Grüne Led an
Portb.2 = 1                  Hintergrundbeleuchtung des Display's an 
Wait 6 Pause einfügen ca 6 Sekunden
Portd.6 = 0  Grüne Led aus
Portb.2 = 0             Hintergrundbeleuchtung des Display's aus 
S_ram = Ee_prom               Nach  Neustart Alten Wert des Zählers aus dem EEprom laden  
Hauptprogramm
Do Schleifenanfang
Portb.2 = 0                   Hintergrundbel. aus
Portb.0 = 1                   Rote Led an 
Waitms 40                    Pause
Portb.0 = 0               Rote Led aus
If Pind.0 = 0 Then Gosub Alarm     Ausg. des Funkmodul wird abgefragt evtl. nach Unteroutine Alarm springen
If Pind.4 = 0 Then Waitms 50  Verhindert Tastenprellen
If Pind.4 = 0 Then S_ram = 0  Gespeicherte Wert im EEprom bei Tastendruck. löschen
If Pind.4 = 0 Then Gosub Licht     Bei Tastendruck zur Unteroutine Licht springen
Waitms 70  Pause
Loop Schleifenrücksprung nach "DO"
End
 Summer Routine
Summer: Sprungadresse vom Summer
Tccr1b = &B00001010                                   Summer an
Waitms 100   Pause für die länge des Summtones
Tccr1b = &B00001000    Summer aus
Return Zurück  zur Ursprungverzweigung
Alarm Routine
Alarm: Sprungandresse vom Alarm
Portb.2 = 1                Hintergrundbel des Displays einschalten 
Gosub Summer Spring zur Unterroutine Summer komm dann zurück
S_ram = S_ram + 1            Den Wert 1 zur Variable hinzuzählen
Waitms 20                    Pause 
Ee_prom = S_ram               SRam Variable in die Eprom Variable kopieren  
Waitms 20                   Pause zum Schreibvorgang fürs Eprom
S_ram = Ee_prom              Eprom Variable zurück kopieren
Cls                           Display löschen   
 Locate 1 , 1  Ausgabe auf dem Display in Zeile 1 , Spalte 1
 Lcd "Alarm"   Textausgabe auf Display
 Locate 2 , 1  Ausgabe auf dem Display in Zeile 2 , Spalte 1
Lcd S_ram   Ausgabe des Inhaltes der S_Ram Variable
 A = 1 Varable A den Wert 1 zuweisen
Do Schleifenanfang
If A = 100 Then Exit Do Schleife verlassen wenn A Hundert erreicht hat
 A = A + 1 Variable A um 1 aufadieren
Portb.0 = 1    Led Rot an
Waitms 50 Pause
 Portb.0 = 0      Led rot aus
Waitms 100 Pause
Portd.7 = 1   Led Gelb an
Waitms 50 Pause
Portd.7 = 0  Led gelb aus
Waitms 100 Pause
Portd.6 = 1     Led grün an
Waitms 50 Pause
Portd.6 = 0    Led Grün aus
Waitms 100 Pause
Loop Rücksprung zum Schleifenanfang , also nach "DO"




Aktualisiert am 12.05.2019