Aus RN-Wissen.de
Wechseln zu: Navigation, Suche


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 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

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. :-)

Autor

Siehe auch

Weblinks