Inhaltsverzeichnis
Ansteuern vom I2C EEproms mit Bascom
Der Artikel demonstriert wie man EEPROM Speicherbausteine unter Bascom über den I2C-Bus anspricht.
Struktur:
'---- schreiben ins EEprom ---------------------------------------- I2cstart 'Start I2C I2cwbyte Slave Adresse I2cwbyte Speicheradresse I2cwbyte Wert I2cstop 'Stop I2C Waitms 10 'warte 10ms '--- lesen vom EEprom -------------------------------------------- I2cstart 'Start I2C I2cwbyte Slave Adresse I2cwbyte Speicheradresse I2cstart 'Start I2C I2cwbyte Slave Adresse +1 für Lesen I2crbyte lese Wert I2cstop 'Stop I2C
Beispiel für EEprom 24C16
Zum besseren Verständnis werden hier die I2C Befehle untereinander geschrieben. In einem grösserem Programm könnte man aber auch eine Sub-Routine deklarieren, die dann den Schreib/Lesevorgang abwickelt.
(Eine Sub-Routine braucht aber ca. um die 30Byte pro Aufruf mehr an Speicher, als ein Gosub-Aufruf. Ich persönlich bleibe deshalb doch lieber bei den Gosub's.)
Beispiel :
'============I2C EEprom schreiben/lesen ================================== ' =========== Für 24C16 EEprom ===================== ' 8MHz Quarz ' LCD auf Port B , ' $regfile = "m8def.dat" $crystal = 8000000 '---Config für LCD ----------------- Config Lcd = 40 * 2 Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5 Config Lcdbus = 4 Config Lcdmode = Port Cursor On 'SDA und SCL definieren Config Sda = Portd.5 Config Scl = Portd.7 Dim X As Byte Dim A As Byte Dim B As Byte Dim Lesen As Byte CLS Do '---- schreibe in EEprom ---- For A = 1 To 10 Incr X '1 bis Überlauf zählen I2cstart 'Start I2C I2cwbyte &HA0 'Sende Slave Adresse I2cwbyte A 'Sende Speicheradresse I2cwbyte X 'Sende Wert I2cstop 'Stop I2C Waitms 10 'warte 10ms Locate 1 , 1 Lcd "ins EEprom = " ; X ; " " ' Ausgabe der geschriebenen Werte am LCD Waitms 500 Next A '--- lesen vom EEprom ---- For B = 1 To 10 I2cstart 'Start I2C I2cwbyte &HA0 'sende Slave Adresse I2cwbyte B 'sende Speicheradresse I2cstart 'Start I2C I2cwbyte &HA1 'sende Slave Adresse +1 für lesen I2crbyte Lesen , Nack 'lese Adresse vom EEprom I2cstop 'Stop I2C Locate 2 , 1 Lcd "Lese EEprom= " ; Lesen ; " " 'Ausgabe der EEprom Werte Waitms 500 Next B Loop End
Schleife A schreibt den Wert 1-10 in die Speicherstelle 1-10
Schleife B liest Speicherstelle 1-10 wieder aus und zeigt dies auch am LCD an.
Beispiel für EEprom 24C256
EEprom 24C32,24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte. (Weil grösserer Speicherbereich im EEprom vorhanden ist) Darum muss man den Adressbereich in High und Low Adressbereich trennen. (Zuerst High-Adressbereich schreiben und dann Low-Adressbereich)
Beispiel:
Wie Beispiel oben, nur mit erweiterten Adressbereich.
'============I2C EEprom schreiben/lesen ================================== ' =========== Für 24C256 EEprom ===================== ' 8MHz Quarz ' LCD auf Port B , ' $regfile = "m8def.dat" $crystal = 8000000 '---Config für LCD ----------------- Config Lcd = 40 * 2 Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5 Config Lcdbus = 4 Config Lcdmode = Port Cursor On 'SDA und SCL definieren Config Sda = Portd.5 Config Scl = Portd.7 Dim X As Byte Dim A As Byte Dim B As Byte Dim Lesen As Byte CLS Do '---- schreibe in EEprom ---- For A = 1 To 10 Incr X '1 bis Überlauf zählen I2cstart 'Start I2C I2cwbyte &HA0 'Sende Slave Adresse I2cwbyte 1 'Sende Speicheradresse High I2cwbyte A 'Sende Speicheradresse LOw I2cwbyte X 'Sende Wert I2cstop 'Stop I2C Waitms 10 'warte 10ms Locate 1 , 1 Lcd "ins EEprom = " ; X ; " " ' Ausgabe der geschriebenen Werte am LCD Waitms 500 Next A '--- lesen vom EEprom ---- For B = 1 To 10 I2cstart 'Start I2C I2cwbyte &HA0 'sende Slave Adresse I2cwbyte 1 'sende Speicheradresse High I2cwbyte B 'sende Speicheradresse Low I2cstart 'Start I2C I2cwbyte &HA1 'sende Slave Adresse +1 für schreiben I2crbyte Lesen , Nack 'lese Adresse vom EEprom I2cstop 'Stop I2C Locate 2 , 1 Lcd "Lese EEprom= " ; Lesen ; " " 'Ausgabe der EEprom Werte Waitms 500 Next B Loop End
High/Low Adressbereich mit Overlay leicht ansprechen
'============I2C EEprom lesen/schreiben ================================== '===========Für 24C256 EEprom===================== ' 8MHz Quarz ' LCD auf Port B , $regfile = "m8def.dat" $crystal = 8000000 '---Config für LCD ----------------- Config Lcd = 40 * 2 Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5 Config Lcdbus = 4 Config Lcdmode = Port Cursor On Config Sda = Portd.5 ' I2C-Port festlegen Config Scl = Portd.7 ' I2C-Port festlegen Dim X As Byte Dim A As Word Dim B As Word Dim Schreiben As Byte Dim Lesen As Byte Dim Adresse As Word At $160 'Die Adresse als Word-Variable Dim Low_adresse As Byte At $160 Overlay 'Zeiger auf das erste Byte Dim High_adresse As Byte At $161 Overlay 'Zeiger auf das zweite Byte '===================Hauptprogramm=============================================== Do '----schreiben---- For Adresse = 250 To 260 'Adresse geht über die Byte-Grenze Incr X '1 bis Überlauf I2cstart 'Start I2cwbyte &HA0 'Sende Slavadresse I2cwbyte High_adresse 'Sende Speicheradresse High I2cwbyte Low_adresse 'Sende Speicheradresse LOW I2cwbyte X 'Sende Wert I2cstop 'stop Waitms 10 Locate 1 , 1 Lcd "->Adres.=" ; Adresse ; "Wert=" ; X ; " " 'Anzeige vom schreiben Waitms 500 Next Adresse '---lesen---- For Adresse = 250 To 260 I2cstart 'Start I2cwbyte &HA0 'Sende Slavadresse +1 für Schreiben I2cwbyte High_adresse 'Sende Speicheradresse High I2cwbyte Low_adresse 'Sende Speicheradresse Low I2cstart 'Start I2cwbyte &HA1 'Sende Slavadresse +1 für Lesen I2crbyte Lesen , Nack 'Lese Adresse vom EEprom I2cstop 'Stop Locate 2 , 1 Lcd "<-Adres.=" ; Adresse ; "Wert=" ; Lesen ; " " 'Anzeige vom lesen Waitms 500 Next Adresse Loop End
Die Sache mit dem Overlay :
Dim Adresse As Word At $160
Hier definiere ich die Variable für die Adresse vom I2C-EEprom als Word-Variable. Die Variable soll ab Adresse $160 im Ram vom AVR abgelegt werden. Die Word-Variable hat einen Bereich von zwei Byte und braucht daher den Bereich von $160 - $161
Mit:
Dim Low_adresse As Byte At $160 Overlay Dim High_adresse As Byte At $161 Overlay
weise ich der neuen (Pseudo) Variablen "Low_adresse" einen Zeiger auf die Speicherstelle $160 und "High_adresse" einen Zeiger auf $161 zu.
"Low_adresse" und "High_Adresse" sind also keine Variablen, sondern nur jeweils ein "Zeiger" auf diesen Speicherberreich der Variable: "Adresse" !
Mit diesen zwei Zeigern habe ich automatisch jetzt meine Low und High Adressen für das I2C-EEprom.
Ich kann diese zwei Zeiger jetzt ganz normal, wie Variablen, im Programm verwenden. :-)