PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit eeprom Speicherchip



xxrider
16.04.2006, 23:02
Will ich mehr als 16 Werte (word) ins eeprom 24c64 speichern, so werden diese beim Auslesen nicht richtig wiedergegeben. Wenn es <=16 Werte sind, dann stimmen sie.
Werden es mehr als 16, so stimmen nur die 16 zuletzt gespeicherten werte, die vorherigen sind irgendwelche seltsamen Wiederholungs-Fragmente der gespeicherten Zahlen.
Wer kennt die Lösung dieses Problems?

Holger

Stromi
16.04.2006, 23:51
da war mal was mit dem page write modus 32 byte schreiben in einem rutsch, weiß aber nichts genaues, google mal....
Page-Write-Modus

Hanni
17.04.2006, 00:49
oder schau mal ins Datenblatt ....

xxrider
17.04.2006, 10:33
Ja, es wird wohl am page write modus liegen.
Folgendes wurde hierzu bereits geschrieben:

"Die EEPROMs haben einen internen 32 Bytes große Buffer und einen eigenen Addresszähler der von 0 bis 31 gehen kann. Man muß also für 32 Bytes am Stück nur einmal einen Deviceselect durchführen."

und:

"Beim Schreiben kannst du maximal nur 32 Bytes auf einmal senden, danach musst du erstmal par Millisekunden warten bis der EEPROM wieder bereit ist. Dann führst du erneut einen Device Select durch und sendest die Addresse für die nächsten Bytes. Wichtig ist nur das du das Pageboundary beachtest. "

Wie sieht der "device select" in der praxis aus, welche routine muss ich in mein bascom-Programm einfügen?
Mit dem data sheet komme ich leider nicht klar.

Rage_Empire
18.04.2006, 10:51
Bin mir nicht Sicher obs mit den modis zu tun hat wen XXRyder diesen Source verwendet:

https://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=283

-tomas-
19.04.2006, 16:57
@xxrider
noch ein Hinweis aus eigener Erfahrung zu "Beim Schreiben kannst du maximal nur 32 Bytes auf einmal senden":
Das geht nur, wenn die Adressen der 32 Byte im gleichen 32 Byte Block liegen (hier also die unteren 5 Bit des Adresszählers).
Sonst werden die hinteren Bytes wieder vorne angesetzt - das hatte mich schon mal aus dem Rennen geworfen :-)

If more than xx data words are transmitted to the EEPROM, the data word address will 'roll over' and previous data will be overwritten. The address 'roll over' during write is from the last byte of the current page to the first byte of the same page.

Rage_Empire
19.04.2006, 21:15
Hallo thomas,

trifft dies auch auf den Byte-Write-Modus zu? ich meine, da wird doch jedesmal die adresse mitgesendet. ich verstehe nicht ganz, wie du das meinst....auf was muß man deffinitiv achten?

hrei
19.04.2006, 23:18
Hallo thomas,

trifft dies auch auf den Byte-Write-Modus zu? ich meine, da wird doch jedesmal die adresse mitgesendet.

Ach wo, beim Byte-write kann Dir das alles vollkommen wurscht sein. Ein guter Grund, seine Subroutinen auf dieser Basis aufzubauen, auch wenn man dann evtl. ein paar wenige Byte an Programmcode mehr braucht.

Wenn ich gerade dabei bin: Bei den 24Cxx wird das Adresswort immer (ungewöhnlicherweise) mit MSB, LSB übergeben.

Grüße
Henrik

Rage_Empire
19.04.2006, 23:25
also dürfte es mit dem source aus dem download-verzeichis damit eigentlich kein problem machen.

hrei
19.04.2006, 23:50
also dürfte es mit dem source aus dem download-verzeichis damit eigentlich kein problem machen.

Leider doch, weil hier I2CSEND verwendet wird, bei dem mehrere Byte hintereinander mit autoincrement geschrieben werden.

Das fällt bei den Routinen nicht so auf, wer denkt schon etwas Böses bei:
Eebanz = 4 : Gosub Write_ee

und wer denkt schon bei
I2csend 24c64w , Eehead(1) , Eebanz

darüber nach, wie I2csend das verhackstückelt.

Wer es tut, findet heraus, daß die Blockgrenze dabei überschritten werden kann :-(.

Ich muss mal meinen eigenen Democode heraussuchen, bei dem ich das konsequent vermeide (liegt auf einem anderen Rechner).

Grüße
Henrik

Rage_Empire
20.04.2006, 00:07
ach, jetzt verstehe ich. wenn der block überläuft(find grad kein besseren ausdruck), gibts probleme und verursacht das chaos. ok, habs geschnallt. aber wie soll man das verhindern? könnt mir nur vorstellen, wenn vor jedem byte die adresse geschickt wird. shit, das raubt speed und resourcen. ich dank dir hrei, wäre nicht draufgekommen.

-tomas-
20.04.2006, 00:34
@hrei
Du hast es besser formuliert, dass I2CSEND in der source tötlich sein kann :-)

Rage_Empire
20.04.2006, 09:02
dann versuch ichs mal so:


$lib "i2c_TWI.lib"
Config Scl = Portc.0 'PIN für I2C Bus
Config Sda = Portc.1
I2cinit

Config Twi = 400000

Dim Eehead(2) As Byte
Dim Ee_adresse01 As Word At Eehead Overlay
Dim Eebyte(4) As Byte
Dim Eesingle As Single At Eebyte Overlay
Dim Eeword(2) As Word At Eebyte Overlay
Dim Tempeebyte(4) As Byte

Dim Eebanz As Byte
Dim Eead As Word
Dim Exteetemp As Byte

Const 24c64w = &B10100000
Const 24c64r = &B10100001

Const Eetest = 1

'Definition der Funktionen ++++++++++++++++++++++++++++++++++++++++++++++++++ ++
Declare Function Loadbyte(byval Ee_adresse As Word) As Byte
Declare Function Loadword(byval Ee_adresse As Word) As Word
Declare Function Loadsingle(byval Ee_adresse As Word) As Single
Declare Sub Savebyte(byref Ee_daten As Byte , Byval Ee_adresse As Word)
Declare Sub Saveword(byref Ee_daten As Word , Byval Ee_adresse As Word)
Declare Sub Savesingle(byref Ee_daten As Single , Byval Ee_adresse As Word )

Goto 001

Sub Savebyte(byref Ee_daten As Byte , Byval Ee_adresse As Word)
Eebyte(1) = Ee_daten
Ee_adresse01 = Ee_adresse
Eebanz = 1 : Gosub Write_ee
End Sub

Sub Saveword(byref Ee_daten As Word , Byval Ee_adresse As Word)
Eeword(1) = Ee_daten
Ee_adresse01 = Ee_adresse
Eebanz = 2 : Gosub Write_ee
End Sub

Sub Savesingle(byref Ee_daten As Single , Byval Ee_adresse As Word )
Eesingle = Ee_daten
Ee_adresse01 = Ee_adresse
Eebanz = 4 : Gosub Write_ee
End Sub


Function Loadbyte(byval Ee_adresse As Word) As Byte
Ee_adresse01 = Ee_adresse
Eebanz = 1 : Gosub Read_ee
Loadbyte = Eebyte(1)
End Function

Function Loadword(byval Ee_adresse As Word) As Word
Ee_adresse01 = Ee_adresse
Eebanz = 2 : Gosub Read_ee
Loadword = Eeword(1)
End Function

Function Loadsingle(byval Ee_adresse As Word) As Single
Ee_adresse01 = Ee_adresse
Eebanz = 4 : Gosub Read_ee
Loadsingle = Eesingle
End Function






'Routine zum schreiben von Daten in das EEPROM ++++++++++++++++++++++++++++++++

Write_ee:
Eead = Ee_adresse01 + Eebanz
For Exteetemp = 1 To Eebanz Step 1
I2cstart
I2cwbyte 24c64w 'send slave address
I2cwbyte Eehead(1)
I2cwbyte Eehead(2)
I2cwbyte Eebyte(exteetemp) 'send a value
I2cstop
incr Ee_adresse01
Waitms 10
Next
Return


'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++
Read_ee:
Eead = Ee_adresse01 + Eebanz
I2csend 24c64w , Eehead(1) , 2
waitms 1
I2creceive 24c64r , Eebyte(1) , 0 , Eebanz
Return

001:
#if Eetest = 1

Dim Ins As Single
Dim Inw As Word
Dim Inb As Byte

Do
Input "Single: " , Ins
Call Savesingle(ins , 5)
Print "gespeicherter Wert: " ; Ins
Ins = Loadsingle(5)
Print "geladener Wert: " ; Ins

Input "Word: " , Inw
Call Saveword(inw , 10)
Print "gespeicherter Wert: " ; Inw
Inw = Loadword(10)
Print "geladener Wert: " ; Inw

Input "Byte: " , Inb
Call Savebyte(inb , 30)
Print "gespeicherter Wert: " ; Inb
Inb = Loadbyte(30)
Print "geladener Wert: " ; Inb
Loop
#endif

-tomas-
20.04.2006, 09:57
die 'Waitus 10000' in Routine zum Lesen von Daten sind unnötig

Rage_Empire
20.04.2006, 10:10
Ok, danke. hab ich geändert.
Jetzt versteh ich noch nicht ganz, warum das EEPROM für ein Byte genau so viel Zeit benötigt wie für den Page-Write modus wo mehr Informationen gespeichert werden?
Byte-Write: Muß man nach jedem Byte ein Stop machen, oder kann man mit einem neuen Start gleich das nächste Byte schreiben?

hrei
20.04.2006, 12:13
Ok, danke. hab ich geändert.
Jetzt versteh ich noch nicht ganz, warum das EEPROM für ein Byte genau so viel Zeit benötigt wie für den Page-Write modus wo mehr Informationen gespeichert werden?

Es braucht schon etwas mehr Zeit, das fällt Dir aber nicht auf. Das Übergeben der Adresse geht so flott, daß es nicht ins Gewicht fällt. Was Zeit braucht (10mS) ist das Schreiben der Daten. Im Gegensatz zu Tomas würde ich daher den Waitbefehl auch drinlassen, aus Übersichtlichkeitsgründen aber Waitms statt Waitus nehmen.
Damit ist sichergestellt, daß die Daten fehlerfrei geschrieben werden. Es geht wegen des Zeitverbrauchs der restlichen Routine meist auch ohne, nur verlassen kann man sich nicht darauf. Sonst müsste man schulmäßig abfragen, ob das EEprom bereits fertig ist (siehe Datenblatt).


Byte-Write: Muß man nach jedem Byte ein Stop machen, oder kann man mit einem neuen Start gleich das nächste Byte schreiben?

Ja, das Stop ist zwingend notwendig, sonst bist Du wieder ganz unfreiwillig im Page/Blockwrite Modus :-(.

Etwas allgemeines zu Demprogrammen:

Es ist zweckmäßig bei Demos "Klein Fritzchen"- mäßig vorzugehen. Wir wollen ja nicht beweisen, wie schön wir Schleifen verschachteln können und wie kryptisch Programme sein können, sondern demonstrieren, wie der Quatsch im Prinzip funktioniert.
Auch aussagekräftige Variablennamen, und geordnete Kommentare sind wichtig.

Hier mal ein Beispiel zum Wordwrite mit einem anderen Ansatz, das aus eben diesen Gründen so simple gestrickt ist (die Kopfdeklarationen bitte einfach überlesen, die sind nur für meinen Experimenter interessant):



'-------------------------------------------------------------------------------
'-------------- 24Cxx EEPROM Test für M8 /168 /M32-Experimenter ----------------
' April 2006 - HR
'-------------------------------------------------------------------------------
$regfile = "m8def.dat"
'$regfile = "m168def.dat"
$regfile = "m32def.dat"
$crystal = 7372800
'$crystal = 14745000
'$crystal = 16000000

$baud = 9600

$hwstack = 64
$swstack = 64
$framesize = 64

'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'$lib "i2c_twi.lbx" 'Hardware I2C
'Config Twi = 100000
Config Scl = Portc.5 'für Mega8 und 168
Config Sda = Portc.4
Portc.5 = 1
Portc.4 = 1
'Config Scl = Portc.0 'für Mega16 und 32
'Config Sda = Portc.1
'Portc.0 = 1
'Portc.1 = 1
I2cinit
'-------------------------------------------------------------------------------
$lib "Lcd_i2c.lib" 'i2c Treiber für das LCD
Dim _lcd_e As Byte 'Nötig für die Enable Auswahl
_lcd_e = 128 'Für LCDs mit 1 Controller
Waitms 200
'-------------------------------------------------------------------------------
Config Lcd = 16 * 2
Display On
Cursor Off
'-------------------------------------------------------------------------------

Config Adc = Single , Prescaler = Auto 'Für Analogtastatur
Config Portd.3 = Output 'Für LED1
Config Portd.4 = Output 'Für LED2

'Beep Alias Portc.2 'für Mega32
Beep Alias Portb.0 'für Mega8

'-------------------------------------------------------------------------------
Const Pcf8591 = 144 'DA-AD-Wandler auf Basis
Const Eeprom2 = 166 'Eeprom2 auf Basis
Const Eeprom1 = 174 'Eeprom1 oder Ram auf Basis
Const Eeprom0 = 160 'externes Cip Card Eeprom0
Const Pcf8574_1 = 64
Const Tda8444 = 78 'DA-Wandler auf Extension-Platine
Const Pcf8574_lcd = 112 'Portextension für LCD
Const Pcf8583_rtc = 162 'RTC auf Extension-Platine

Const Max520 = 94 'für MAX520 (extern)
Const Keyboard = 0 'ADC-Nr. für Analogtastatur

'-------------------------------------------------------------------------------


Declare Function Read_eeprom(byval Dev As Byte , Byref Address As Word)as Byte
Declare Function Read_eeprom_word(byref Address As Word)as Word

Declare Sub Write_eeprom(byval Dev As Byte , Byref Address As Word , Byval Wert_
As Byte)
Declare Sub Write_eeprom_word(byref Address As Word , Byref Value As Word)

Dim Address_low As Byte 'Address ist hier überlappend
Dim Address_high As Byte 'dimensioniert, um High- und Low-
Dim Address As Word At Address_low Overlay 'Byte einfach ansprechen zu können.

Dim Value_low As Byte 'Dito mit Value
Dim Value_high As Byte
Dim Value As Word At Value_low Overlay

Dim Wert As Byte
Dim Temp_w As Word
Dim I As Word


'------------------------------ Demodurchlauf ----------------------------------

Cls 'Intro
Lcd "EEPROM TEST"
Locate 2 , 1
Lcd "SCHREIBE"
Wait 2

Value = 1500
For Address = 250 To 500 'von Adresse 250 bis 500
Call Write_eeprom_word(address , Value) 'value ins EEprom schreiben.
Value = Value + 20 'Value zur Abwechslung
Next 'um 20 erhöhen

'-------------------------------------------------------------------------------
Wait 2
Cls
Lcd " LESE"

For Address = 250 To 500 'die Werte wieder auslesen
Temp_w = Read_eeprom_word(address)
Locate 2 , 1
Lcd "A: " ; Address ; " " ; "W: " ; Temp_w ; " "
Wait 1 'Pause, damit man was sieht
Next

Locate 1 , 1
Lcd "FERTIG"
'------------------------ Ende Demodurchlauf -----------------------------------
End


'------------------------ Funktionen und Subs ----------------------------------

'-------------------------------------------------------------------------------
'- Word (value) auf 2 aufeinander folgende EEprom Adressen schreiben

Sub Write_eeprom_word(byref Address As Word , Byref Value As Word)
Call Write_eeprom(eeprom1 , Address , Value_low)
Incr Address
Call Write_eeprom(eeprom1 , Address , Value_high)
End Sub
'-------------------------------------------------------------------------------
'- Word von 2 aufeinanderfolgenden EEprom Adressen lesen
'- Der gelesene Wert ist der Rückgabewert der Funktion

Function Read_eeprom_word(byref Address As Word)as Word
Value_low = Read_eeprom(eeprom1 , Address)
Incr Address
Value_high = Read_eeprom(eeprom1 , Address)
Read_eeprom_word = Value
End Function

'-------------------------------------------------------------------------------
'- Byte (wert) auf EEprom Adresse (address) speichern

Sub Write_eeprom(byval Dev As Byte , Byref Address As Word , Byval Wert As Byte)

I2cstart
I2cwbyte Dev
I2cwbyte Address_high
I2cwbyte Address_low
I2cwbyte Wert
I2cstop
Waitms 10

End Sub
'--------------------------------------------------------
'- Byte von EEprom Adresse (address) lesen
'- Der gelesene Wert ist der Rückgabewert der Funktion

Function Read_eeprom(byval Dev As Byte , Byref Address As Word)
Dim Devread As Byte
Devread = Dev + 1

I2cstart
I2cwbyte Dev
I2cwbyte Address_high
I2cwbyte Address_low
I2cstop
I2cstart
I2cwbyte Devread
I2crbyte Read_eeprom , Nack
I2cstop

End Function
'------------------------------------------------------------------------------


Viele Grüße
Henrik

Rage_Empire
20.04.2006, 12:45
hrei: Schöner Source. Ja, deine Variante ist eleganter, das geb ich zu. Hab das mit dem Wait wieder zugefügt, jedoch nur 1ms.
Dank euch, ich habs geblickt! \:D/

-tomas-
21.04.2006, 11:09
@hrei und @Rage_Empire
Ihr redet aneinander vorbei:
Der Waitbefehl wird nur für Write benötigt, ist also im Unterprogramm 'Routine zum lesen von Daten aus dem EEPROM' unnötig.


Dim Address_low As Byte 'Address ist hier überlappend
Dim Address_high As Byte 'dimensioniert, um High- und Low-
Dim Address As Word At Address_low Overlay 'Byte einfach ansprechen zu können.

Da hoffst Du drauf, dass der Compiler auch zukünftig die Variablen im RAM nicht optimiert :-)
Ich gehe immer diesen sicheren Weg (erzeugt die gleiche Codelänge):

Dim Address As Word
Dim Adress_Raw(2) As Byte at Address Overlay
Address_low Alias Adress_Raw(1)
Address_high Alias Adress_Raw(2)

damit kann man auch wunderbar Long etc. in ein EEPROM schreiben/lesen:

Dim Address As Long
Dim Adress_Raw(4) As Byte at Address Overlay

jetzt beim schreiben der Adresse auf die Blockgröße bei PageWrite achten. Hier die Variante zum lesen von LONG.

Devread = Dev + 1
I2cstart
I2cwbyte Dev
I2cwbyte Address_high
I2cwbyte Address_low
I2cstop
I2cstart
I2cwbyte Devread
I2crbyte Adress_Raw(1) , Ack
I2crbyte Adress_Raw(2) , Ack
I2crbyte Adress_Raw(3) , Ack
I2crbyte Adress_Raw(4) , Nack
I2cstop

Das ganze lässt sich dann mit For/Next noch schön machen, wobei Bascom-typisch der Code dann anwachsen könnte ;-)

xxrider
23.04.2006, 10:23
Leider hatte ich nicht viel Glück mit der Umsetzung der hier vorgeschlagenen Sources.
Beim source von hrei bekome ich mit dem print-Befehl nach Auslesen der values (Temp_W) für alle adressen den Wert 44975 zurück.
Während mein 16*2 Display ziemlich verrückt spielt:
"EEPROM" und "Schreibe" beleiben permanent auf dem Display stehen, die rechten Displayhälften verwandln sich in quasi japanische Schriftzeichen.
Doch bei den "japanischen Schriftzeichen" ist eine interessante Beobachtung zu machen: beim Auslesen der values im Sekundentakt ändern sich die richtigen Stellen im Display (auf 5 Änderungen im rechten Feld ändert sich das linke Feld daneben usw.).

Die "Lcd_i2c.lib" Datei wurde vom Compiler nicht gefunden, ist diese Datei von hrei erstellt? Ist sie nötig?

hrei
23.04.2006, 11:59
Die "Lcd_i2c.lib" Datei wurde vom Compiler nicht gefunden, ist diese Datei von hrei erstellt? Ist sie nötig?

Nein, die ist nicht von mir, sondern von Kent Anderson. Außerdem darf die natürlich nur dann eingebunden werden, wenn Du auch ein I2C-LCD verwendest! Ansonsten auskommentieren und statt dessen Deine LCD Config dort einbinden. Ich schreibe oben nicht umsonst:

(die Kopfdeklarationen bitte einfach überlesen, die sind nur für meinen Experimenter interessant):

Siehe Dir doch bitte einfach die Funktionen und Subs an und binde sie in Dein Programm ein. Zeige uns das Resultat Deiner Bemühungen.

Wenn Du dann nur noch Murks empfängst, hast Du ein I2C-Bustiming Problem (eher unwahrscheinlich).

Henrik

xxrider
23.04.2006, 12:39
also ich hab natürlich mein lcd konfiguriert, d.h. die ports zugewiesen, usw.
den lcd_i2c.lib habe ich weggelassen, ich verwende ja kein i2c-LCD.

Ich habe praktisch deinen source 1:1 übernommen und zusätzlich noch ein
print "adresse"; address; "value"; Temp_w
nach deinem Auslesebefehl und AUsgabebefehl an das LCD eingegeben.

am pc-monitor wird mir dann folgendes ausgegeben:
adresse: 251 value: 44975
adresse: 253 value: 44975
....usw value bleibt immer gleich 44975

am meinem Display wird während dessen folgendes ausgegeben:
"EEPROM TEST
SCHREIBE"
und dann:

"EEPROM Txxxxx
Schreibexxxxxxxx"

x steht für diese seltsamen "japanischen Schriftzeichen".

in der Zeile Schreibexxxxxxxx ändern sich diese Schriftzeichen im 1 sekundentakt regelmäßig wie oben beschrieben.

Ja, so siehts bei mir aus. Nicht so toll.

hrei
23.04.2006, 13:14
Sende bitte Deinen Code genau so, wie er jetzt aussieht.

Henrik

xxrider
23.04.2006, 13:40
hier ist mein code:

$regfile = "m32def.dat"

$crystal = 9000000

$baud = 9600

$hwstack = 64
$swstack = 64
$framesize = 64

Portd.5 = 1
Config Portd.2 = Output 'leds
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Input 'taster
Portd.5 = 1


Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.3 , Db6 = Portc.2 , Db7 = Portc.1 , E = Portc.5 , Rs = Portc.7
Config Lcdbus = 4
Config Lcdmode = Port

Portc.6 = 0 'display rw bei bascom immer 0
Config Portc = Output 'display
Reset Portc.1 'write mode for display
Initlcd
Cursor Off
Cls



$lib "i2c_twi.lbx" 'Hardware I2C
Config Twi = 100000
'SDA und SCL definieren
Config Sda = Portc.0
Config Scl = Portd.7
Portc.0 = 1
Portd.7 = 1
I2cinit

'-------------------------------------------------------------------------------
'$lib "Lcd_i2c.lib" 'i2c Treiber für das LCD
'Dim _lcd_e As Byte 'Nötig für die Enable Auswahl
'lcd_e = 128 'Für LCDs mit 1 Controller
'Waitms 200


'-------------------------------------------------------------------------------
'Config Adc = Single , Prescaler = Auto 'Für Analogtastatur
'Config Portd.3 = Output 'Für LED1
'Config Portd.4 = Output 'Für LED2

'Beep Alias Portc.2 'für Mega32
'Beep Alias Portb.0 'für Mega8


'-------------------------------------------------------------------------------
Const Pcf8591 = 144 'DA-AD-Wandler auf Basis
Const Eeprom2 = 166 'Eeprom2 auf Basis
Const Eeprom1 = 174 'Eeprom1 oder Ram auf Basis
Const Eeprom0 = 160 'externes Cip Card Eeprom0
Const Pcf8574_1 = 64
Const Tda8444 = 78 'DA-Wandler auf Extension-Platine
Const Pcf8574_lcd = 112 'Portextension für LCD
Const Pcf8583_rtc = 162 'RTC auf Extension-Platine

Const Max520 = 94 'für MAX520 (extern)
Const Keyboard = 0 'ADC-Nr. für Analogtastatur


'-------------------------------------------------------------------------------


Declare Function Read_eeprom(byval Dev As Byte , Byref Address As Word)as Byte
Declare Function Read_eeprom_word(byref Address As Word)as Word

Declare Sub Write_eeprom(byval Dev As Byte , Byref Address As Word , Byval Wert_
As Byte)
Declare Sub Write_eeprom_word(byref Address As Word , Byref Value As Word)

Dim Address_low As Byte 'Address ist hier überlappend
Dim Address_high As Byte 'dimensioniert, um High- und Low-
Dim Address As Word At Address_low Overlay 'Byte einfach ansprechen zu können.

Dim Value_low As Byte 'Dito mit Value
Dim Value_high As Byte
Dim Value As Word At Value_low Overlay

Dim Wert As Byte
Dim Temp_w As Word
Dim I As Word


'------------------------------ Demodurchlauf ----------------------------------
Cls 'Intro
Lcd "EEPROM TEST"
Locate 2 , 1
Lcd "SCHREIBE"
Wait 2

Value = 0
For Address = 250 To 500 'von Adresse 250 bis 500
Call Write_eeprom_word(address , Value) 'value ins EEprom schreiben.
Print "adresse: " ; Address ; " Value: " ; Value 'Value zur Abwechslung
Value = Value + 20

Next 'um 20 erhöhen

'-------------------------------------------------------------------------------
Wait 2
Cls
Lcd " LESE"

For Address = 250 To 500 'die Werte wieder auslesen
Temp_w = Read_eeprom_word(address)
Locate 2 , 1
Lcd "A: " ; Address ; " " ; "W: " ; Temp_w ; " "
Waitms 200 'Pause, damit man was sieht
Print "adresse: " ; Address ; " Value: " ; Temp_w

Next

Locate 1 , 1
Lcd "FERTIG"
'------------------------ Ende Demodurchlauf -----------------------------------
End



'------------------------ Funktionen und Subs ----------------------------------

'-------------------------------------------------------------------------------
'- Word (value) auf 2 aufeinander folgende EEprom Adressen schreiben

Sub Write_eeprom_word(byref Address As Word , Byref Value As Word)
Call Write_eeprom(eeprom1 , Address , Value_low)
Incr Address
Call Write_eeprom(eeprom1 , Address , Value_high)
End Sub
'-------------------------------------------------------------------------------
'- Word von 2 aufeinanderfolgenden EEprom Adressen lesen
'- Der gelesene Wert ist der Rückgabewert der Funktion

Function Read_eeprom_word(byref Address As Word)as Word
Value_low = Read_eeprom(eeprom1 , Address)
Incr Address
Value_high = Read_eeprom(eeprom1 , Address)
Read_eeprom_word = Value
End Function

'-------------------------------------------------------------------------------
'- Byte (wert) auf EEprom Adresse (address) speichern

Sub Write_eeprom(byval Dev As Byte , Byref Address As Word , Byval Wert As Byte)

I2cstart
I2cwbyte Dev
I2cwbyte Address_high
I2cwbyte Address_low
I2cwbyte Wert
I2cstop
Waitms 10

End Sub
'--------------------------------------------------------
'- Byte von EEprom Adresse (address) lesen
'- Der gelesene Wert ist der Rückgabewert der Funktion

Function Read_eeprom(byval Dev As Byte , Byref Address As Word)
Dim Devread As Byte
Devread = Dev + 1

I2cstart
I2cwbyte Dev
I2cwbyte Address_high
I2cwbyte Address_low
I2cstop
I2cstart
I2cwbyte Devread
I2crbyte Read_eeprom , Nack
I2cstop

End Function

hrei
23.04.2006, 13:54
Na also :-) - Danke.

1) Liegt Dein EEprom1 auch wirklich wie bei mir auf der I2C-Busadresse 174? Wenn nein, bitte anpassen!

2) Immer noch Probleme? Nimm probehalber das Hardware I2C raus.

UPS und Edit:
Das kann bei M32 und Harware I2C ja nicht sein:
Config Sda = Portc.0
Config Scl = Portd.7


Wir kommen der Sache schon auf die Schliche.

Grüße
Henrik

pebisoft
23.04.2006, 14:14
Das kann bei M32 und Harware I2C ja nicht sein:
Config Sda = Portc.0
Config Scl = Portd.7


doch...in bascom kannste die ports selber bestimmen....lol

hrei
23.04.2006, 14:20
Das kann bei M32 und Harware I2C ja nicht sein:
Config Sda = Portc.0
Config Scl = Portd.7


doch...in bascom kannste die ports selber bestimmen....lol

Bevor einfach strukturierte Poster wie Du so laut lachen: Bei Hardware I2C eben nicht.
Man, war das schön als Du Postingverbot hattest und Dir wenigstens immer wieder neue Namen und Anmeldungen einfallen lassen musstest.

Henrik

xxrider
23.04.2006, 15:24
Absolut super :-) :-) :-)

jetzt klappt es.

zu 1: musste ich ändern in Adresse 160. (weiß allerdings nicht wer diese adresse festlegt, in früheren codes hat sie jedenfalls funktioniert)

doch dann ging immer noch nichts.

wie in hreis punkt 2. empfohlen habe ich die hardware i2c rausgenommen - und jetzt gehts wie geschmiert.

die ports sda=c.0 und scl=d.7 sind bei meinem board so fixiert. da kann ich nichts machen.

also vielen vielen dank an die beteiligten
insbesondere hrei und rage empire.
jetzt ist diese hürde genommen und ich kann weitermachen, toll.


@hrei:
warum schreibtest du eigentlich probehalber?
("nimm probehaber das hardware-i2c raus")
kann ich das nicht getrost dann ganz weglassen, wenn es so klappt?

Holger

hrei
23.04.2006, 16:04
Hallo Holger,


@hrei:
warum schreibtest du eigentlich probehalber?
("nimm probehaber das hardware-i2c raus")
kann ich das nicht getrost dann ganz weglassen, wenn es so klappt?

Holger

Probehalber deshalb, weil wenn ein umlegen der Ports auf die Hardwareports möglich gewesen wäre, ich diese Methode aus Effizienzgründen bevorzugen würde. So wie die Dinge bei Dir liegen, geht das nicht, also bleibe getrost bei Software I2C.

Software I2C hat neben der freien Zuweisbarkeit der Ports noch einen weiteren Vorteil: Es ist weniger zetkritisch. Selbst bei größeren Leitungskapazitäten, die eine höhere Anstiegszeit der positiveb Flanken auf dem Bus zur Folge haben, kann Software I2C noch funktionieren, während Hardware I2C kläglich scheitert.
Hier hilft eben bisweilen probieren, wenn kein Speicheroszilloskop zur Verfügung steht, mit dem sich das I2C-Busverhalten messen lässt.

Ach so, die Adresse mit der eine I2C-Komponente angesprochen wird, hängt von der Beschaltung der variablen Adressleitungen ab. In Deinem Fall liegen A0, A1 und A2 auf 0, bei mir auf 1. Siehe hierzu das/die Datenblätter der jeweiligen Komponente(n).

Viele Grüße
Henrik

xxrider
23.04.2006, 17:42
alles klar, Henrik
thanx nochmal,

viele Grüße von
Holger