PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bascom I2C Eeprom ST 24C64



fredred
14.01.2014, 14:12
Hallo Forum,
es gibt schon viele Beispiele und Hinweise diese mit Byte zu beschreiben und lesen.
Ist ja auch kein Problem aber ich finde keine vernünftige Lösung für Single –Variablen.
Dieses Thema ist nach meiner persönlichen Meinung schon sehr unübersichtlich geworden. Somit ein Neustart.
Nun bitte ich um Hilfe.

Vielen Dank vorab
Mit freundlichen Grüßen
fredred


Zum Verständnis mein Terminal- Ausdruck für Byte-Variablen.
Funktioniert prima. Aber wie mit Single-Variablen ????
-------------------------------------

I2C Scan start
gefunden h A0 b 10100000

EEPROM beschreiben...
Adresse >1< wurde mit >0 beschrieben!
Adresse >2< wurde mit >110 beschrieben!
Adresse >3< wurde mit >120 beschrieben!
Adresse >4< wurde mit >130 beschrieben!
Adresse >5< wurde mit >140 beschrieben!
Adresse >6< wurde mit >150 beschrieben!

EEPROM auslesen...
Adresse >1< wurde mit >0 gelesen!
Adresse >2< wurde mit >110 gelesen!
Adresse >3< wurde mit >120 gelesen!
Adresse >4< wurde mit >130 gelesen!
Adresse >5< wurde mit >140 gelesen!
Adresse >6< wurde mit >150 gelesen!

Hier mein letzter Code
'****************** Test-Platine *************************
'* ist ein Testmodul für Data extern EEprom als Speicher *
'* am I²C Bus ein 24c64 angeschlossen zum speichern *
'* und lesen der Variablen *
'* *
'* alle Auswertungen für Test nur über Terminal anzeigen *
'* *
'*************! fredred@arcor.de !************************

$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200

'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version aus.
Print " "
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print " "
Waitms 100

$lib "i2c_TWI.lib" 'Hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz

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

Dim Adresse As Word 'ist Adresszähler für Eeprom
Dim Adresse_l As Byte At Adresse Overlay
Dim Adresse_h As Byte At Adresse + 1 Overlay


Dim Wert(6) As Word 'ist Schreibwerte Array
Dim Wertalt As Word 'ist Lesewert
Dim Aktionen As Byte 'ist Status für Aktionen

'war nur ein erfolgloser Versuch

'Dim Wert As Single
'Dim Werts As Byte At Wert(4) Overlay
'Dim Wertalt As Single
'Dim Wertl(4) As Byte At Wertalt Overlay


'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben

Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben

'Config Portc.4 = Output
'Eepvoll Alias Portc.4 'LED-Warnung für EEprom voll

'+++ zu Test ob I²C Hardware OK ist +++
Gosub I2c_test
'++++++++++++++++++++++++++++++++++++++

'------- nach Reset lesen -------------
Gosub Lesen
'--------------------------------------

Do

'!!! Testwerte !!!
Wert(1) = Aktionen
Wert(2) = 110
Wert(3) = 120
Wert(4) = 130
Wert(5) = 140
Wert(6) = 150
'!!!!!!!!!!!!!!!!!!

'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Incr Aktionen 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
Loop
End


'################################################# ##################
Lesen:
Print ""
Print "EEPROM auslesen..."

For Adresse = 1 To 6
I2cstart
I2cwbyte 24c64w
I2cwbyte Adresse_h
I2cwbyte Adresse_l
I2cstart
I2cwbyte 24c64r
I2crbyte Wertalt , Nack
I2cstop
Print "Adresse >" ; Adresse ; "< wurde mit >" ; Wertalt ; " gelesen!"
Next
Return

'################################################# ############################
Schreiben:
Print ""
Print "EEPROM beschreiben..."

For Adresse = 1 To 6
I2cstart
Adresse_h = High(adresse)
Adresse_l = Low(adresse)
I2cwbyte 24c64w
I2cwbyte Adresse_h
I2cwbyte Adresse_l
I2cwbyte Wert(adresse)
I2cstop
Print "Adresse >" ; Adresse ; "< wurde mit >" ; Wert(adresse) ; " beschrieben!"
Next
Return

'################################################# ############################

I2c_test:

Dim Busaddress As Byte
Dim Busaddress_read As Byte
Dim Chipaddress As Byte

Print "I2C Scan start"

'I²C Porterweiterung testen
'Alle Adresen suche und Anzeigen
'Step 2 soll nur IC Adresse aufrufen für lesen
For Chipaddress = 0 To 254 Step 2 ' IC's am I²C-Bus erkennen
I2cstart 'send start
I2cwbyte Chipaddress 'sende Addresse auf Bus
If Err = 0 Then 'Chip gefunden
If Chipaddress = 24c64w Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
End If
End If
Next
Waitms 200
I2cstop
Return
'---------------------------------------------------------

So sieht das mit Code-Fenster aus - Manf

RoboHolIC
14.01.2014, 17:16
Bitte schließe den Terminalausdruck in [CODE] -Tags ein, damit der Thread besser lesbar wird. Danke.

fredred
15.01.2014, 10:14
Guten Tag,

bin noch nicht so firm im Forum.
War der Meinung mein Ergebnis sollte in der Erklärung stehen wie weit ich gekommen bin.
Um somit eventuelle Anfragen ob Hartware usw. OK ist zu vermeiden.
Auch dein Hinweis gehören in eine gutes Forum.
Somit vielen Dank.

Mit freundlichen Grüßen
fredred

Searcher
15.01.2014, 13:11
es gibt schon viele Beispiele und Hinweise diese mit Byte zu beschreiben und lesen.
Ist ja auch kein Problem aber ich finde keine vernünftige Lösung für Single –Variablen.

Hallo,
nach Deinem Code hast Du ja schon Bytes geschrieben und zurückgelesen. Den Kommentaren zufolge hast Du es beim Typ Single auch schon mit Overlays versucht. Die Overlay Verwendung scheint mir bei Dir falsch gewesen zu sein.

Hier ein Codefragment um eine Single-Variable zu schreiben und zu lesen. Wichtig hierbei eben die richtige Deklaration der Overlays. Übertragen in Deinen Code mit Ergänzungen und den den richtigen EEPROM Adressen "darfst" Du machen ;) Wenn das klappt, kann man zum Speichern mehrerer Single übergehen.

Dim I As Byte 'Laufvariable für for-next Schleife

Dim Four_byte_var_wr As Single 'Single Variable für Write belegt vier Byte
Dim Byte_var_write(4) As Byte At Four_byte_var_wr Overlay 'Array mit vier mal ein Byte liegt über der Write-Single

Dim Four_byte_var_rd As Single 'Single Variable für Read belegt vier Byte
Dim Byte_var_read(4) As Byte At Four_byte_var_rd Overlay 'Array mit vier mal ein Byte liegt über der Read-Single

Four_byte_var_wr = &H1A2B3C4D 'dezimal = 439041101 (irgendeine Zahl)

For I = 1 To 4 'die vier Bytes der Single Variablen zum EEPROM schreiben
.
I2cwbyte Byte_var_write(i) ,(ack , Nack)
.
Next
.
For I = 1 To 4 'die vier Bytes der Single Variablen vom EEPROM lesen
.
I2crbyte Byte_var_read(i) ,(ack , Nack)
.
Next

Print Four_byte_var_wr
Print Four_byte_var_rd

End 'end program


Gruß
Searcher

PS. Die [ CODE][ /CODE] Tags (ohne die Leerzeichen in den eckigen Klammern) erreicht man auch mit dem "Erweitert" Button und dann mit dem # Zeichen. Posts kann man auch nachträglich noch editieren.

fredred
15.01.2014, 15:24
Hallo Searcher,

sieht auf dem ersten Blick schon mal sehr Gut aus.
Werde es Morgen mal versuchen im mein Code einzubinden.
Vorab schon mal vielen Dank.

Gruß
fredred

fredred
17.01.2014, 14:07
Guten Tag,

komme nicht zum Erfolg. Nun bin ich langsam ans aufgeben.
Vermute ich verstehe Overlay nicht richtig oder der IC Eeprom (ST24c64) ist eigenwillig mit Adressierung der Speicherzuordnung.
Nochmals kurz meine Endvision. 6 Single-Variablen speichern dann nach nächster Aktion die nächsten 6 Single-Variablen anhängen usw. und dann auf Befehl kompletten Speicherbereich printen lassen.

Nur zum Verständnis vorab ein Printauszug dank Hilfe.
Gleichen String hintereinander speichern dann auslesen.

'ist Test Single-Variable
Four_byte_var_wr = 500.1
Siehe Code

Byte-Wert 205
Byte-Wert 12
Byte-Wert 250
Byte-Wert 67
geschrieben 500.10
gelesen 23.69E-39
gelesen 6.25E-36

Nun der Code.


$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200

'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version aus.
Print " "
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print " "
Waitms 100
$lib "i2c_TWI.lib" 'hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz
Const 24c64w = &B10100000
Const 24c64r = &B1010000
'Format für Single zwei Nachkommastellen
Config Single = Scientific , Digits = 2

Dim Adresse As Word 'ist Adresszähler für Eeprom
Dim Adresse_l As Byte At Adresse Overlay
Dim Adresse_h As Byte At Adresse + 1 Overlay
Dim I As Byte 'Laufvariable für for-next Schleife
Dim Four_byte_var_wr As Single 'Single Variable für Write belegt vier Byte
Dim Byte_var_write(4) As Byte At Four_byte_var_wr Overlay 'Array mit vier mal ein Byte liegt über der Write-Single
Dim Four_byte_var_rd As Single 'Single Variable für Read belegt vier Byte
Dim Byte_var_read(4) As Byte At Four_byte_var_rd Overlay 'Array mit vier mal ein Byte liegt über der Read-Single
'ist Test Single-Variable
Four_byte_var_wr = 500.1 '&H1A2B3C4D 'dezimal = 439041101 (irgendeine Zahl)
Do
'********* schreiben **************
For Adresse = 1 To 8 Step 4 'Adressbereich festlegen
I2cstart
Adresse_h = High(adresse)
Adresse_l = Low(adresse)
I2cwbyte 24c64w
I2cwbyte Adresse
I2cwbyte Adresse_h
I2cwbyte Adresse_l
I2cstop
I2cstart
For I = 1 To 4 'die vier Bytes der Single Variablen zum EEPROM schreiben
I2cwbyte Byte_var_write(i) ',(ack , Nack)
Waitms 10 'etwas Zeit geben
Print "Byte-Wert " ; Byte_var_write(i) 'Byte anzeigen ist OK
Next I
I2cstop
'++++ ausgeben +++++++++
'!!dieses Print macht kein Sinn Variable ist vor Do schon festgelegt!!
Print "geschrieben " ; Four_byte_var_wr
'+++++++++++++++++++++++
Next Adresse

Wait 2 ' nur für Test

'********** lesen ****************
For Adresse = 1 To 8 Step 4 'Adressbereich festlegen
I2cstart
Adresse_h = High(adresse)
Adresse_l = Low(adresse)
I2cwbyte 24c64w
I2cwbyte Adresse_h
I2cwbyte Adresse_l
I2cstop
I2cstart
For I = 1 To 4
I2crbyte Byte_var_read(i) , Nack 'die vier Bytes der Single Variablen vom EEPROM lesen
Waitms 10 'etwas Zeit geben
Next I
I2cstop
'++++ ausgeben ++++
Print "gelesen " ; Four_byte_var_rd
'++++++++++++++++++
Next Adresse

Loop
End


Danke an alle Helfer und besonders an Markus Fulde.
fredred

Searcher
17.01.2014, 23:10
Hallo fredred,

komme nicht zum Erfolg. Nun bin ich langsam ans aufgeben.
Vermute ich verstehe Overlay nicht richtig oder der IC Eeprom (ST24c64) ist eigenwillig mit Adressierung der Speicherzuordnung.
Dranbleiben! Das wird schon. Liegt jetzt erstmal nicht den Overlays sondern hauptsächlich an der Reihenfolge der I2C Kommandos und der Berechnung der Adressen - denke ich:confused: Das zu berichtigen ist mir ehrlich gesagt zuviel :( . Angefangen schon ganz oben bei der "Const 24c64r", da fehlt das letzte Bit.


Nochmals kurz meine Endvision. 6 Single-Variablen speichern dann nach nächster Aktion die nächsten 6 Single-Variablen anhängen usw. und dann auf Befehl kompletten Speicherbereich printen lassen.

Hast Du es schon geschafft nur eine Single zu schreiben und zu lesen?

Wenn nicht, dann hier ein Programm in Anhang, daß das macht. Es liest über die UART (zB vom PC Hyperterminal) eine Zahl ein, schreibt sie in das ext. EEPROM und liest sie danach wieder aus und gibt die geschriebene und gelesene Zahl wieder am Terminal aus.

Das Programm ist getestet, allerdings auf einem Tiny44. Du müsstest es auf den Mega32 anpassen. Die Anpassungen sollten aber nur Header, die SW-UART und SW-I2C betreffen.

Falls Du es bei Dir zum Laufen bekommst, poste es nochmal und mal schaun, wie wir mehrere Singles bearbeiten können.

Gruß
Searcher

fredred
18.01.2014, 16:13
Hallo Forum Mitglieder und Gäste
Guten Tag Herr Searcher,

dank der Hilfe, gibt es mich wieder Mut, weiter zu mache.
Dumm war nur das "Const 24c64r", da fehlt das letzte Bit. War nur ein Copyfehler.
Bitte um Entschuldigung. Natürlich muss da noch eine 1 dran sein.

Aktuelle Hilfe:
Single- Variable wird geschrieben und so wie es sein soll gelesen.
Konnte diese zwar nicht über Hyperterminal eingeben(mag sein da ich nicht den von BASCOM nutze)
[mein genutztes Terminal zeigt Strings/Hex und Binär an] ist oft sehr Hilfreich.
Ist aber gegenstandslos.
Lasse die Variable einfach hoch zählen. Nach Erfolgreichen Test und Beendigung meiner Freudensprünge gleich mal versucht den Adressbereich für die nächsten Single-Variablen anzuhängen. Oh Oh Oh schon wieder Erfolglos.
Vermute die vielen Sprünge haben nicht nur meine Knochen belastet sonder auch mein Gehirn noch mehr geschädigt.

Der hilfreiche Code für eine Single Variable kann mit Deklarationen belassen bleiben.
Anpassungen für mein Projekt bekomme ich hin(hoffe ich)

‚??? Dies kann ich nicht nachvollziehen ???
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
Config Base = 0 'Array Indexe beginnen mit 0
‚???????????????????????????????????????

HIER MEIN VERSUCH (erst mal schreiben)
6 Single pro Aktion hintereinander schreiben und nach nächster Aktion die 6 Single anhängen bis Eeprom voll.

‘!!! Als Array geändert Number_from_rs232 !!!
Dim Number_from_rs232(7) As Single
Dim Aktionen As Byte

Do
Wait 2
Incr Aktionen
If Mem_addr = 4 Then Mem_addr = Mem_addr_low_byte * Aktionen

For Z = 1 To 6
If Z = 1 Then Number_from_rs232(1) = 100.10
If Z = 2 Then Number_from_rs232(2) = 200.20
If Z = 3 Then Number_from_rs232(3) = 300.30
If Z = 4 Then Number_from_rs232(4) = 400.40
If Z = 5 Then Number_from_rs232(5) = 500.60
If Z = 6 Then Number_from_rs232(6) = 600.60

Four_byte_var_write = Number_from_rs232(z) 'Single Variable mit irgendeiner Zahl belegen
‘habe ich mit [Number_from_rs232(7) As Single] gemacht


‘??? Weis auch hier nicht warum ???
Four_byte_var_read = 0 'Zurückgelesene Single "löschen"

'### BEGINN ext. EEPROM schreiben (byte write method) ###
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
Next J
Next Z
'### ENDE ext. EEPROM schreiben (byte write method) ###
Print "Number written to ext. EEPROM: " ; Four_byte_var_write

Loop
‘-----------------------------------------------------------------------------------------------------------------

ERGEBNIS:
Schreibt alle Single auf Adresse 1 bis 4 somit wird auch nur [Number_from_rs232(6)] gelesen. Ist ja auch der letzte Inhalt.
Wie geschrieben habe ist schon ein Erfolgserlebnis. Dumm für mich ist nur, dass die Vermutung aufkommen könnte ich möchte ein fertigen Code. Aber nach 525 Test- .BAS und 1889 Progmmed
(nur für diesen I²C Eeprom), ohne Endergebnis, benötigt man schon Hilfe.
Dachte anfangs dies mache ich in 10 Minuten. Aber, Aber.

Nun genug des Geschwätz und helft mich weiter.
Danke
fredred

Searcher
18.01.2014, 18:47
Hallo fredred,

Guten Tag Herr Searcher,
:-) Komisch so angesprochen zu werden. Ich duze jeden außer er verlangt explizit das siezen. Ist allgemeiner Gebrauch im Roboternetz. Also einfach Searcher und das Du, oder?


Dumm war nur das "Const 24c64r", da fehlt das letzte Bit. War nur ein Copyfehler.
Bitte um Entschuldigung. Natürlich muss da noch eine 1 dran sein.
Brauchst Dich nicht entschuldigen; passiert doch jedem mal. Aber die CODE Tags könntest Du mal nutzen ;)


Lasse die Variable einfach hoch zählen. Nach Erfolgreichen Test und Beendigung meiner Freudensprünge gleich mal versucht den Adressbereich für die nächsten Single-Variablen anzuhängen. Oh Oh Oh schon wieder Erfolglos.
Vermute die vielen Sprünge haben nicht nur meine Knochen belastet sonder auch mein Gehirn noch mehr geschädigt
:lol: Habe versucht Deinen Code hinzubiegen und ihn in CODETAGS unten eingefügt. Besser lesbar als Deiner, oder? ;) Hoffe die Kommentare sagen genug, sonst nachfragen.


‚??? Dies kann ich nicht nachvollziehen ???
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
Mem_addr ist "overlayed" von Mem_addr_low_byte und Mem_addr_high_byte, die beim Schreiben und Lesen immer auf die aktuelle Speicheradresse im EEPROM zeigen müssen. Mem_addr wird also ständig verändert und muß deshalb vor dem Schreiben bzw vor dem Lesen einer Single auf einen sinnvollen Wert gebracht werden. War das die Frage:confused:


Config Base = 0 'Array Indexe beginnen mit 0
‚???????????????????????????????????????
Defaultmäßig beginnen die Arrayindexe mit 1. Wenn sie mit 0 beginnen erleichtert es einige Dinge besonders bei Adressrechnungen, da zB EEPROM Speicheradressen bei 0 beginnen.
DIM AR(2) as Byte hat MIT dem Kommando 3 Elemente: AR(0), AR(1), AR(2)
DIM AR(2) as Byte hat OHNE dem Kommando 2 Elemente: AR(1), AR(2)


HIER MEIN VERSUCH (erst mal schreiben)
6 Single pro Aktion hintereinander schreiben und nach nächster Aktion die 6 Single anhängen bis Eeprom voll.
Code sollte nun die 6 Singles schreiben - jedoch nicht getestet. Die Variable "Aktionen" wird zur Berechnung der Speicheradresse weiterverwendet aber nun erst zum Ende der Hauptschleife erhöht. Abbruchbedingung habe ich keine gefunden. EEPROMS sind nicht unendlich beschreibbar. Zu oft in einer schnellen Schleife zerstört sie.


‘??? Weis auch hier nicht warum ???
Four_byte_var_read = 0 'Zurückgelesene Single "löschen"
Diente einer Kontrolle. Wenn im Programm beim Print eine 0 rauskam, wußte ich, das nicht vom EEPROM gelesen wurde. Nicht wichtig für die Funktion.


Wie geschrieben habe ist schon ein Erfolgserlebnis. Dumm für mich ist nur, dass die Vermutung aufkommen könnte ich möchte ein fertigen Code. Aber nach 525 Test- .BAS und 1889 Progmmed
(nur für diesen I²C Eeprom), ohne Endergebnis, benötigt man schon Hilfe.
Kein Problem solange man merkt, daß sich jemand Mühe gibt und das meine ich bei Dir zu erkennen. Ich selbst bin auch kein Profi und lerne auch gleich mit.


'HIER MEIN VERSUCH (erst mal schreiben)
'6 Single pro Aktion hintereinander schreiben und nach nächster Aktion die 6 Single anhängen bis Eeprom voll.

'!!! Als Array geändert Number_from_rs232 !!!

Dim Mem_addr_first_store_loc As Word 'nicht mehr als Const sondern Variable, ist defaultmäßig auf 0

Dim Number_from_rs232(7) As Single
Dim Aktionen As Byte
Aktionen = 0 'ist sowieso defaultmäßig auf 0
Do
Wait 2

'If Mem_addr = 4 Then Mem_addr = Mem_addr_low_byte * Aktionen
Mem_addr_first_store_loc = Aktionen * 24 '24 = 6 Singles * 4 Byte (ein Single belegt 4 Byte)

For Z = 0 To 5 'for-next mit 0 beginnen lassen
If Z = 0 Then Number_from_rs232(0) = 100.10
If Z = 1 Then Number_from_rs232(1) = 200.20
If Z = 2 Then Number_from_rs232(2) = 300.30
If Z = 3 Then Number_from_rs232(3) = 400.40
If Z = 4 Then Number_from_rs232(4) = 500.60
If Z = 5 Then Number_from_rs232(5) = 600.60

Four_byte_var_write = Number_from_rs232(z) 'Single Variable mit irgendeiner Zahl belegen
'habe ich mit [Number_from_rs232(7) As Single] gemacht

'??? Weis auch hier nicht warum ???
'Four_byte_var_read = 0 'Zurückgelesene Single "löschen"

'### BEGINN ext. EEPROM schreiben (byte write method) ###
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
Next J
Next Z
'### ENDE ext. EEPROM schreiben (byte write method) ###
Print "Number written to ext. EEPROM: " ; Four_byte_var_write

Incr Aktionen 'Aktionen erst am Ende der Loop erhöhen

Loop


Gruß
Searcher

fredred
19.01.2014, 15:05
Guten Tag Searcher,

wie es aussieht wird der Eeprom dank deiner Hilfe, nach meinen Vorstellungen, beschrieben.
Aber das Entresultat sieht man nur beim auslesen(nach Reset). Ist meine persönliche Erfahrung. Dachte vor langer Zeit, alles im Griff zu haben aber die Auslesung kam nicht vom Eeprom sondern vom RAM.

So nun in der Hoffnung wir machen weiter bis zum Ziel.
Kommt schon wieder die nächste Aufgabe für dich.
Eeprom auslesen und meinen Code „hinzubiegen“.
In meinen Versuch wird zwar der Eeprom gelesen aber die Werte sind Expotential.
Somit nehme ich an die Ausleseadressen sind verschoben.
Im Code sollt somit für dich nur meine Dim’s und die Gosub lesen für Hilfe betrachtet werden.
Wie schon geschrieben benötige Hilfe zum lernen wie Single sauber in Adressbereiche des Eeproms geschrieben/gelesen werden können.


$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200 '19200


'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version aus.
Print
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print
Waitms 100
$lib "i2c_TWI.lib" 'hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz
'Format für Single zwei Nachkommastellen
Config Single = Scientific , Digits = 2
'################################################# ##############################
Config Base = 0 'Array Indexe beginnen mit 0
Const Dev_addr_write = &B10100000 'EEPROM Schreibadresse
Const Dev_addr_read = &B10100001 'EEPROM Leseadresse
'Const Mem_addr_first_store_loc = 0 'Auf EEPROM Seitenanfang legen, im folgenden PRG keinen roll over produzieren!
Dim Mem_addr_first_store_loc As Word
Dim J As Byte 'Laufvariable für for-next Schleife Single
Dim Z As Byte 'Anzahl der Single_Variablen schreiben
Dim L As Byte 'alle Single_Variablen auslesen
Dim Aktionen As Byte 'nächsten Schreibzyklus vortschreiben
Dim Four_byte_var_write As Single
Dim Byte_var_write(3) As Byte At Four_byte_var_write Overlay '4 Elemente, Arrayindex von 0 bis 3
Dim Four_byte_var_read As Single
Dim Byte_var_read(3) As Byte At Four_byte_var_read Overlay '4 Elemente, Arrayindex von 0 bis 3
Dim Mem_addr As Word
Dim Mem_addr_low_byte As Byte At Mem_addr Overlay
Dim Mem_addr_high_byte As Byte At Mem_addr + 1 Overlay
Dim Number_from_rs232(6) As Single 'Array der 6 Schreib-Variablen

'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben
Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben
Gosub Lesen 'nach Reset erstmal lesen
Do
'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
Loop

'### BEGINN ext. EEPROM schreiben (byte write method) ###
Schreiben:
Mem_addr_first_store_loc = Aktionen * 24 '24 = 6 Singles * 4 Byte (ein Single belegt 4 Byte)
For Z = 0 To 5 'for-next mit 0 beginnen lassen
If Z = 0 Then Number_from_rs232(0) = 100.10
If Z = 1 Then Number_from_rs232(1) = 200.20
If Z = 2 Then Number_from_rs232(2) = 300.30
If Z = 3 Then Number_from_rs232(3) = 400.40
If Z = 4 Then Number_from_rs232(4) = 500.60
If Z = 5 Then Number_from_rs232(5) = 600.60
Four_byte_var_write = Number_from_rs232(z) 'Single Variable Z schreiben
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
Next J
'!!! nüt für Test !!!
Print
Print "Aktionen " ; Aktionen
Print "Adressbereich ab " ; Mem_addr_first_store_loc
Print "Number written to ext. EEPROM: " ; Four_byte_var_write
'!!!!!!!!!!!!!!!!!!!!
Next Z
Incr Aktionen 'nächsten Schreibzyklus anstoßen
'### ENDE ext. EEPROM schreiben (byte write method) ###
Return

'### BEGINN ext. EEPROM lesen (random address read method) ###
Lesen:
For L = 0 To 240 Step 4 'hier mein Versuch 10 Aktionen lesen
Mem_addr = Mem_addr_first_store_loc 'Leseadresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Next J Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen
Mem_addr_first_store_loc = L
'### BEGINN SW UART Ausgabe ###
Print
Print "Adressbereich ab " ; Mem_addr
Print "Number read from ext. EEPROM : " ; Four_byte_var_read
Next L
ENDE ext. EEPROM lesen (random address read method) Return

Bin schon wieder gespannt wo mein Denkfehler liegt.

Vorab vielen Dank
fredred

Searcher
19.01.2014, 16:17
Hallo,

Kommt schon wieder die nächste Aufgabe für dich.
Eeprom auslesen und meinen Code „hinzubiegen“.
:p:)


In meinen Versuch wird zwar der Eeprom gelesen aber die Werte sind Expotential.
Somit nehme ich an die Ausleseadressen sind verschoben.
Ja, weil beim "Lesen:" die Mem_addr zu spät auf den richtigen Wert gesetzt wird.
Habe in grün meine Änderungen geschrieben und blau, daß was ich rausgenommen habe.

Vor dem Aufruf von "Schreiben" sollte auch die Variable "Aktionen" auf 0 gesetzt werden (Aber nicht innerhalb des jetzigen Unterprogramms). Wenn der µC nicht zurückgesetzt wird und Du die Funktion nochmal aufrufst, hat "Aktionen" irgendeinen Wert von vorher.

Würde auch empfehlen, das DEBOUNCE Kommando zum Entprellen und Aufruf der Unterprogramme zu nutzen.

Hoffe hab auf die Schnelle nichts übersehen.
Gruß
Searcher



'### BEGINN ext. EEPROM lesen (random address read method) ###
Lesen:
For L = 0 To 236 Step 4 'hier mein Versuch 10 Aktionen lesen
Mem_addr = L 'Mem_addr_first_store_loc 'Leseadresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen
Next J
'Mem_addr_first_store_loc = L (auskommentiert)
'### BEGINN SW UART Ausgabe ###
Print
Print "Adressbereich ab " ; Mem_addr 'Mem_addr zeigt hier schon auf den Anfang der nächsten Single
Print "Number read from ext. EEPROM : " ; Four_byte_var_read 'Single paßt nicht zu vorher geprinteten Mem_addr
Next L
Return
'########ENDE ext. EEPROM lesen (random address read method)

fredred
19.01.2014, 16:59
Hallo,

kann alles nicht ausprobieren. Meine Liebe Frau schreit schon wieder, es ist Sonntag und du sitzt schon wieder ab 5:30 Uhr an deinen "Komposter".
Melde mich Morgen.
Gruß
fredred

fredred
20.01.2014, 17:08
Hallo Searcher
Hallo Forum,

nun bin trotz Hilfe am Ende.
Nochmals mein letzter Versuch gekürzt nur mal die 6 Single schreiben und lesen ohne Fortschreibung.
In der Hoffnung mein Code ist nun besser lesbar. Stelle ich diesen noch mal ab


$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200 '19200


'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version aus.
Print
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print
Waitms 100
$lib "i2c_TWI.lib" 'hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz
'Format für Single zwei Nachkommastellen
Config Single = Scientific , Digits = 2
'################################################# ##############################
Config Base = 0 'Array Indexe beginnen mit 0
Const Dev_addr_write = &B10100000 'EEPROM Schreibadresse
Const Dev_addr_read = &B10100001 'EEPROM Leseadresse
'Const Mem_addr_first_store_loc = 0 'Auf EEPROM Seitenanfang legen, im folgenden PRG keinen roll over produzieren!
Dim J As Byte 'Laufvariable für for-next Schleife Single
Dim Mem_addr_first_store_loc As Word
Dim Mem_addr As Word
Dim Mem_addr_low_byte As Byte At Mem_addr Overlay
Dim Mem_addr_high_byte As Byte At Mem_addr + 1 Overlay
Dim Z As Byte 'Anzahl der Single_Variablen schreiben
Dim Number_from_rs232(6) As Single 'Array der 6 Schreib-Variablen
Dim Four_byte_var_write As Single
Dim Byte_var_write(3) As Byte At Four_byte_var_write Overlay '4 Elemente, Arrayindex von 0 bis 3
Dim L As Byte 'alle Single_Variablen auslesen
Dim Number_from_rl232(6) As Single
Dim Four_byte_var_read As Single
Dim Byte_var_read(3) As Byte At Four_byte_var_read Overlay '4 Elemente, Arrayindex von 0 bis 3
Dim Aktionen As Byte 'nächsten Schreibzyklus vortschreiben

'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben
Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben
Gosub Lesen 'nach Reset erstmal lesen
Do
'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
Loop

'### BEGINN ext. EEPROM schreiben (byte write method) ###
Schreiben:
Print "Byte der 6 Single-Variablen schreiben"
Print
Mem_addr_first_store_loc = Aktionen * 1 '24 = 6 Singles * 4 Byte (ein Single belegt 4 Byte)
For Z = 0 To 5 'for-next mit 0 beginnen lassen
If Z = 0 Then Number_from_rs232(0) = 100.10
If Z = 1 Then Number_from_rs232(1) = 200.20
If Z = 2 Then Number_from_rs232(2) = 300.30
If Z = 3 Then Number_from_rs232(3) = 400.40
If Z = 4 Then Number_from_rs232(4) = 500.60
If Z = 5 Then Number_from_rs232(5) = 600.60
Four_byte_var_write = Number_from_rs232(z) 'Single Variable Z schreiben
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
Print "Single-Variable " ; Z ; " = Adresse " ; J ; " Bytewert " ; Byte_var_write(j)
Next J
Print "!! Ausgabe !! " ; Four_byte_var_write
Print
Next Z
Incr Aktionen 'nächsten Schreibzyklus anstoßen
'### ENDE ext. EEPROM schreiben (byte write method) ###
Return
' Eergebnis: sieht doch Gut aus.
'(
Byte der 6 Single-Variablen schreiben
Single-Variable 0 = Adresse 0 Bytewert 51
Single-Variable 0 = Adresse 1 Bytewert 51
Single-Variable 0 = Adresse 2 Bytewert 200
Single-Variable 0 = Adresse 3 Bytewert 66
!! Ausgabe !! 100.10
Single-Variable 1 = Adresse 0 Bytewert 51
Single-Variable 1 = Adresse 1 Bytewert 51
Single-Variable 1 = Adresse 2 Bytewert 72
Single-Variable 1 = Adresse 3 Bytewert 67
!! Ausgabe !! 200.20
Single-Variable 2 = Adresse 0 Bytewert 102
Single-Variable 2 = Adresse 1 Bytewert 38
Single-Variable 2 = Adresse 2 Bytewert 150
Single-Variable 2 = Adresse 3 Bytewert 67
!! Ausgabe !! 300.30
Single-Variable 3 = Adresse 0 Bytewert 51
Single-Variable 3 = Adresse 1 Bytewert 51
Single-Variable 3 = Adresse 2 Bytewert 200
Single-Variable 3 = Adresse 3 Bytewert 67
!! Ausgabe !! 400.40
Single-Variable 4 = Adresse 0 Bytewert 205
Single-Variable 4 = Adresse 1 Bytewert 76
Single-Variable 4 = Adresse 2 Bytewert 250
Single-Variable 4 = Adresse 3 Bytewert 67
!! Ausgabe !! 500.60
Single-Variable 5 = Adresse 0 Bytewert 102
Single-Variable 5 = Adresse 1 Bytewert 38
Single-Variable 5 = Adresse 2 Bytewert 22
Single-Variable 5 = Adresse 3 Bytewert 68
!! Ausgabe !! 600.60
')

'### BEGINN ext. EEPROM lesen (random address read method) ###
Lesen:
Print "Byte der 6 Single-Variablen lesen"
Print
For L = 0 To 5 'Step 4 'hier mein Versuch 10 Aktionen lesen
Mem_addr = L 'Mem_addr_first_store_loc 'Leseadresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10
Print "Single_Variable " ; L ; " = Adresse " ; J ; " Bytewert " ; Byte_var_read(j)
Next J
'Mem_addr_first_store_loc = L (auskommentiert)
'### BEGINN SW UART Ausgabe ###
Print "!! Ausgabe !! " ; Four_byte_var_read 'Single paßt nicht zu vorher geprinteten Mem_addr
Print
Next L
'zurück setzen
Aktionen = 0 'alle Aktionen wurden ausgelesen.
Return
'########ENDE ext. EEPROM lesen (random address read method)
' Eergebnis: Ist doch Müll
'(
Byte der 6 Single-Variablen lesen
Single_Variable 0 = Adresse 0 Bytewert 102
Single_Variable 0 = Adresse 1 Bytewert 38
Single_Variable 0 = Adresse 2 Bytewert 22
Single_Variable 0 = Adresse 3 Bytewert 68
!! Ausgabe !! 600.60 [ist die letze Variable aber weningsten schon mal ein Wert]
Single_Variable 1 = Adresse 0 Bytewert 38
Single_Variable 1 = Adresse 1 Bytewert 22
Single_Variable 1 = Adresse 2 Bytewert 68
Single_Variable 1 = Adresse 3 Bytewert 0
!! Ausgabe !! 0.0
Single_Variable 2 = Adresse 0 Bytewert 22
Single_Variable 2 = Adresse 1 Bytewert 68
Single_Variable 2 = Adresse 2 Bytewert 0
Single_Variable 2 = Adresse 3 Bytewert 0
!! Ausgabe !! 0.0
Single_Variable 3 = Adresse 0 Bytewert 68
Single_Variable 3 = Adresse 1 Bytewert 0
Single_Variable 3 = Adresse 2 Bytewert 0
Single_Variable 3 = Adresse 3 Bytewert 0
!! Ausgabe !! 0.0
Single_Variable 4 = Adresse 0 Bytewert 0
Single_Variable 4 = Adresse 1 Bytewert 0
Single_Variable 4 = Adresse 2 Bytewert 0
Single_Variable 4 = Adresse 3 Bytewert 7
!! Ausgabe !! 96.30E-36
Single_Variable 5 = Adresse 0 Bytewert 0
Single_Variable 5 = Adresse 1 Bytewert 0
Single_Variable 5 = Adresse 2 Bytewert 7
Single_Variable 5 = Adresse 3 Bytewert 134
!! Ausgabe !! -25.39E-36
')

Vielen Dank für die aufwendigen Hilfeleistungen.
Nehme nach wie vor an der IC ST24C64 will mich narren.

Mit freundlichen Grüßen
fredred

Searcher
20.01.2014, 21:19
Hallo fredred,

Nehme nach wie vor an der IC ST24C64 will mich narren.
;) Nein, leider nicht. In dem "Schreiben" Unterprogramm war noch ein Bug - habe ich rot markiert :-b :( (Da läßt sich noch einiges optimieren, habe es aber erstmal so stehen lassen.)

Den Rest habe ich nochmal versucht gerade zu biegen und sollte :-k für Dich kompilierbar und ablauffähig sein. Ich kann leider nur mit Tiny44 und einem 24C08 testen. Viel Glück (auch für mich :) ) :pray: (Debounce habe ich auch mal reingebracht - meine Taster prellen fürchterlich)

Gruß
Searcher



$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200 '19200


'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version aus.
Print
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print
Waitms 100
$lib "i2c_TWI.lib" 'hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz

'Format für Single zwei Nachkommastellen
Config Single = Scientific , Digits = 2
Config Base = 0 'Array Indexe beginnen mit 0

Const Dev_addr_write = &B10100000 'EEPROM Schreibadresse
Const Dev_addr_read = &B10100001 'EEPROM Leseadresse
Dim J As Byte 'Laufvariable für for-next Schleife Single
Dim Mem_addr_first_store_loc As Word
Dim Mem_addr As Word
Dim Mem_addr_low_byte As Byte At Mem_addr Overlay
Dim Mem_addr_high_byte As Byte At Mem_addr + 1 Overlay
Dim Z As Byte 'Anzahl der Single_Variablen schreiben
Dim Number_from_rs232(6) As Single 'Array der 6 Schreib-Variablen
Dim Four_byte_var_write As Single
Dim Byte_var_write(3) As Byte At Four_byte_var_write Overlay '4 Elemente, Arrayindex von 0 bis 3
Dim L As Byte 'alle Single_Variablen auslesen
Dim Number_from_rl232(6) As Single
Dim Four_byte_var_read As Single
Dim Byte_var_read(3) As Byte At Four_byte_var_read Overlay '4 Elemente, Arrayindex von 0 bis 3
Dim Aktionen As Byte 'nächsten Schreibzyklus vortschreiben

'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben
Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben
Gosub Lesen 'nach Reset erstmal lesen

Do

Debounce Taster_s , 0 , Schreiben , Sub
Debounce Taster_l , 0 , Lesen , Sub

'(
'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
')

Loop

'### BEGINN ext. EEPROM schreiben (byte write method) ###
Schreiben:
Print "Byte der 6 Single-Variablen schreiben"
Print
Mem_addr_first_store_loc = Aktionen * 24 '24 = 6 Singles * 4 Byte (ein Single belegt 4 Byte)
Mem_addr = Mem_addr_first_store_loc 'Speicheradresse für ext. EEPROM initialisieren
For Z = 0 To 5 'for-next mit 0 beginnen lassen
If Z = 0 Then Number_from_rs232(0) = 100.10
If Z = 1 Then Number_from_rs232(1) = 200.20
If Z = 2 Then Number_from_rs232(2) = 300.30
If Z = 3 Then Number_from_rs232(3) = 400.40
If Z = 4 Then Number_from_rs232(4) = 500.60
If Z = 5 Then Number_from_rs232(5) = 600.60
Four_byte_var_write = Number_from_rs232(z) 'Single Variable Z schreiben
' Mem_addr = Mem_addr_first_store_loc 'HIER WAR DER BUG !!! steht jetzt vor Laufschleife
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
Print "Single-Variable " ; Z ; " = Adresse " ; J ; " Bytewert " ; Byte_var_write(j)
Next J
Print "!! Ausgabe !! " ; Four_byte_var_write
Print
Next Z
Incr Aktionen 'nächsten Schreibzyklus anstoßen
'### ENDE ext. EEPROM schreiben (byte write method) ###
Return


'### BEGINN ext. EEPROM lesen (random address read method) ###
Lesen:
Print "Byte der 6 Single-Variablen lesen"
Print
For L = 0 To 5 ' Step 4 'hier mein Versuch 10 Aktionen lesen
Mem_addr = L * 4 'statt step 4: L * 4 Leseadresse für ext. EEPROM initialisieren
For J = 0 To 3 'Laufschleife um 4 Bytes zu schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10
Print "Single_Variable " ; L ; " = Adresse " ; J ; " Bytewert " ; Byte_var_read(j)
Next J

'### BEGINN SW UART Ausgabe ###
Print "!! Ausgabe !! " ; Four_byte_var_read 'Single paßt nicht zu vorher geprinteten Mem_addr
Print
Next L
'zurück setzen
Aktionen = 0 'alle Aktionen wurden ausgelesen.
Return
'########ENDE ext. EEPROM lesen (random address read method)

fredred
21.01.2014, 16:14
Hallo Searcher,

nun ist es wie es sein soll. Schreiben und lesen OK
Habe sehr viel, dank deiner Hilfe, gelernt und muss im nachhinein schon etwas schmunzeln wie man sich „verrennen“ kann.
Sehr Hilfreich war auch „Config Base = 0“ kannte ich nicht.
Nur “addr_first_store_loc” kann ich immer noch nicht nachvollziehen.
Ein sehr wichtiger Hinweis war auch „I2cstop“ zu entfernen "random address read" habe es im Datenblatt gelesen, aber nicht geschnallt, dass dies ein Adresspointer im IC auslöst.
PS. Ich kann kein Englisch(zu DDR durfte ich es nicht lernen. War nur denen gegönnt die in Russisch gut waren. Da war ich eine Niete. Meine stärke war nur Mathe und Physik.
Genug des PS. geschwätzt
Habe noch eine Kleinigkeit eingefügt
Wenn Speicherbereich = NAN dann lesen beenden. Will doch keine NOP lesen. Es klappt.

Nun geht es für mich endlich weiter.
Nur lesen der Ausgaben als String in Terminal-Log printen. Habe schon ein Ordner angelegt in dem alle Prints Ausgaben eingetragen werden
Möchte aber für Weiterverarbeitung in [Excel] das es so aussieht.
“ String = Aktionen + „;“ + Byte_var_read(0) + „;“ + Byte_var_read(1) usw. “
Bin mir sicher du hast eine Lösung wie dies zu realisieren ist. Soll aber nicht bedeuten
„mach mal“ Ich warte auf eine fertige Lösung. Habe schon selber angefangen dies zu lösen.
Aber na JA mit Overlay muss ich noch viel lernen.

Somit herzlichen Dank für die Hilfe.
Kann nur sagen du bist „Goldwert“ für Einsteiger in BASCOM.

Mit freundlichen Grüßen
fredred

Searcher
21.01.2014, 18:34
Hallo,


... und muss im nachhinein schon etwas schmunzeln wie man sich „verrennen“ kann.
Ja, das kenne ich:( Ein von mir jetzt nicht näher benannter Freund im Roboternetz:cool:würde sowieso empfehlen, zuerst ein PAP (http://de.wikipedia.org/wiki/Programmablaufplan) oder PAD (http://www.rn-wissen.de/index.php/PIC_Assembler#Programmablaufdiagramm_.28PAD.29) (Programmablaufplan) zu erstellen.



Nur “addr_first_store_loc” kann ich immer noch nicht nachvollziehen.
Hat sich während der Programmentwicklung eingeschlichen und war irgendwann von mir dazu gedacht um dem Unterprogramm zu sagen, ab welcher Adresse geschrieben bzw. gelesen werden soll. Die Variable kann wieder wegfallen (wegoptimiet werden). Der Wert 24 kommt daher, daß bei einer Aktion 6 Singles geschrieben werden. Eine Single hat 4 Byte. 6 * 4 = 24. Beim ersten Aufruf von Schreiben ist "Aktionen" = 0 und die erste beschriebene Mem_addr ist damit die Adresse 0. Wird Schreiben nochmal aufgerufen, ohne daß "Aktionen" zurückgesetzt wurde, also ohne die "Lesen" aufzurufen, ist "Aktionen" = 1. Mem_addr wird zu 1 * 24 = 24 und damit werden dann die ersten 6 Singles nicht überschrieben. Die "Schreiben" kann also so beginnen:


Schreiben:
Print #1 , "Byte der 6 Single-Variablen schreiben"
Print #1 ,
Mem_addr = Aktionen * 24 '24 = 6 Singles * 4 Byte (ein Single belegt 4 Byte)
For Z = 0 To 5 'for-next mit 0 beginnen lassen, 6 Durchläufe - pro Single einen
.
.




Wenn Speicherbereich = NAN dann lesen beenden. Will doch keine NOP lesen. Es klappt.:confused:\\:D/



Möchte aber für Weiterverarbeitung in [Excel] das es so aussieht.
“ String = Aktionen + „;“ + Byte_var_read(0) + „;“ + Byte_var_read(1) usw. “
Bin mir sicher du hast eine Lösung wie dies zu realisieren ist.
Das müsstest Du aber noch genauer beschreiben. So eine EXCEL Spreadsheet hat Zeilen und Spalten. Was soll konkret in den Zeilen und Spalten stehen? Mit Printanweisungen kann man eine Ausgabe produzieren, die zB dem csv Format entspricht. Viele Terminalprogramme erlauben es, direkt eine Logdatei der empfangenen Zeichen mitzuschreiben. So kriegt man mit "Hausmitteln" recht einfach viele Daten nach EXCEL.



Kann nur sagen du bist „Goldwert“ für Einsteiger in BASCOM.
Danke. Mir hat aber auch Deine Frau leid getan und ich möchte nicht, daß sie nächsten Sonntag heiser wird :lol: :lol: :lol:

Gruß
Searcher

PS:Allgemein zum Programmablauf ging mir noch so einiges, daß ich mir angelesen habe, durch den Kopf:
Speicherzellen in EEPROMS können je nach Typ und Hersteller unterschiedlich oft aber begrenzt beschrieben werden.
Jedes Mal, wenn mit I2cstop nach write ein EEPROM interner Schreibvorgang ausgelöst wird, verbleiben weniger Schreibzyklen.
Im gegenwärtigen Programm (mit byte write method) sind das für einen Block von 6 Singles vierundzwanzig Schreibvorgänge.
Durch Nutzen des Page Writes (bis zu 32 Bytes mit einem internen Schreibvorgang - Datenblatt) kann das drastisch reduziert werden und damit die Lebensdauer des EEPROM erhöht werden.
Wenn nicht immer der komplette EEPROM beschrieben wird, kann man folgende Schreibzugriffe immer erhöhen, so daß man nicht immer die gleichen Speicherzellen beschreibt. Ist man an der obersten Adresse angelangt, fängt man unten wieder an. Erhöht weiter die Lebensdauer bis er unsterblich wird. :)

Ich bisher nichts gefunden, daß der EEPROM beim Lesen eine Wartezeit braucht.
Einsatz von Current Address Read method und Sequential Read würden das Lesen beschleunigen.

Aber Änderungen in dem gegenwärtigen Schreib-/Lesealgorithmus würden das Programm meist komplizierter machen.
Weitere Optimierungen ...

fredred
22.01.2014, 14:28
Hallo Searcher,

alles klar mit “addr_first_store_loc” wollte nur sicher sein, dass ich deine Code auch bis zum letzen Punkt verstehe.
Wenn ich Hilfe bekomme möchte ich diese auch verstehen und nicht nur anwenden.
Die Werte in den Adressbereichen zu schreiben habe ich auf Anhieb verstanden. War ja auch das Signal zum weiter machen.
Die NAN abfrage habe ich eingebaut, um beim auslesen, unbeschriebene Adressen, nicht mit zulesen. Sind ja Werksseitig auf &HFF. Für Single sieht es so aus.
[If Byte_var_read(0) = 0 And Byte_var_read(1) = 0 And Byte_var_read(2) = 127 And Byte_var_read(3) = 67 Then
Return ...] somit Printausgabe NAN.

Bedingt: Eeprom wird in mein Projekt von Adr. 0 bis Adr. Max gelesen, aber nur wenn gültige Werte vorhanden sind.
Die Schreibvariable „Aktionen“ will ich nicht nutzen. Kann ja mal ein Reset auftreten. Da Eeprom auch je nach bedarf ausgelesen wird, könnte es sein Adr. Max wird nicht erreicht.
Zum Verständnis speichere ¼ Stunden Lastprofil Stromzähler, Gaszähler und Temperaturen Daten usw. 24 Single pro ¼ Stunde = 96 Byte pro Stunde. Somit können auf ST24C64
ca. 7 Tage gespeichert werden bis Überlauf. Nach Datenblatt ca. 100.000 schreib Zyklen.
Der IC wird mich überleben.

Hier mein Codeschnipsel für bewerte Datenerfassung mit int. Eeprom. funktioniert beim Freund schon sehr lange ohne Probleme.
Die Daten werden über die von mir gebauten RFM12B Funkbrücke vom Keller zur 2 Etage im Haus mit Tagestakt gesendet.
Nicht über Code- Kommentare lachen er hat noch weniger Erfahrungen wie ich.


$regfile "m644pdef.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200

Waitms 100

'kann nach Test entfernt werden ist nur für Prüfung ab wirklich hochgezählt wird
'muss dann auch aus [Temp_str] entfernt werden.
Dim Zeit As Byte

'### hier werden die Variablen für EEprom-Test festgelegt ##########
Dim Datum As String * 8
Dim Var1 As String * 5
Dim Var2 As String * 5
Dim Var3 As String * 5
Dim Var4 As String * 5
Dim Var5 As String * 5
'sind 33 Zeichen + 5x Simikolon = 38 (Test Zeit nochmals 2 Zeichen
'somit muss [Eram String * 41] sein. Immer um 1 größer.

'!!!! nur für Test !!!!!!!!!!!!!!!!!!!!!!!!
'wie du siehst müssen dein Variablen zum speichern in EEprom
'immer vom Typ String sein oder wie die Variable [Zeit]
'in [Temp_str] in ein str() eingebunden werden.

'Hinweis: Für Test einfach mal den Variablen-Inhalt ändern.
Datum = "07.11.13"
Var1 = "15:10"
Var2 = "1:20"
Var3 = "23:59"
Var4 = "1:10"
Var5 = "999.9"
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
‚in Echt kommen die „Var“ vom Empfänger(siehe Beschreibung Hardware)

Dim Tagz As Byte 'ist Tageszähler
Dim Tagzm As Byte
Dim C As Byte 'ist Zähler für EEprom-Speicherplatz schreiben
Dim Mess_eeprom_nr As Byte 'ist Start Adr. im Eeprom
'Abhängig vom verwendeten µC (Mess_eeprom_max = EEPROM / Eram String * 41)
'IC M644 wäre Mess_eeprom_max = 2000/41
'32 x alles speichern dann überschreiben. In Echt wären es die Tage

Const Mess_eeprom_max = 32 'wenn alles OK dann laut Formel ändern.
Tagzm = Mess_eeprom_max - 2 '2 Tage vor überschreiben dann LED-Anzeige
Dim Temp_str As String * 41
Dim Mess_eeprom(mess_eeprom_max) As Eram String * 41
'ist nach Spannungsausfall oder Reset der Zwischenspeicher
'und bleibt erhalten
Dim Temp_stralt As String * 41

'String x Max nach jedem Durchlauf erst 1 dann 2 usw.
'Erster Speicherbereich 1 bis 41 dann x2 somit 42 bis 83 bis Eeprom voll ca. bei 2000
'bei dein EEprom.
'+++++++++++++++++++++++++++++++++++++++++++++

'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben

Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben

Config Portc.4 = Output
Eepvoll Alias Portc.4 'LED-Warnung für EEprom voll
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!


'wenn gewünscht alten Inhalt vom EEprom lesen nach Reset
'natürlich muss dann statt Print der String[Temp_str]
'wieder zerlegt werden wenn der letzte Wert in Variablen
'geschreiben werden soll.

For C = 1 To Mess_eeprom_max
Temp_stralt = Mess_eeprom(c)
Print "aus EEPROM lesen: " ; Temp_stralt
Next C
'muss nicht sein hat aber eine Kontrollfunktion(auslesen um Daten zu sichern)
'nach Reset LED-Ein wenn Neu gelesen dann Aus bis Speicher fast voll
Eepvoll = 1

Wait 1 'nur für Test

'**** hier in Echt in deiner Haupschleife einbinden
Do

Wait 1

Zeit = Zeit + 1 'nur für Test

'hier wird die Zeichenkette für EEprom in [Temp_str] geschrieben
'das [;] ist ein Trennzeichen für Excel. weiter Verarbeidungen
Temp_str = Str(zeit) + ";" + Datum + ";" + Var1 + ";" + Var2 + ";" + Var3 + ";" + Var4 + ";" + Var5

'speichert die Tagessumme in EEprom, wenn ????

' "Time$ >= "23:59:58" ' zum Beispiel eine paar Sekunden früher (Laufzeiten) ausprobieren
'oder [Date(dcf_day)] für Start nutzen wie schon hingewiesen. Alten Tag speichern
'[Date(dcf_day)] ist eine Bascom-Variable, somit muss du nicht erst Date$ zerlegen

' _day_alt <> _day Then in Eeprom schreiben.
'ist nach meiner Meinung besser da Laufzeit vernachlässigt werden kann.

If Taster_s = 0 Then 'dann ersetzen
Gosub Tagspeicher_schreiben
End If

'wenn Taste gedrückt lesen
If Taster_l = 0 Then
Gosub Tagspeicher_lesen
End If

Loop
End

'************************************************* ****************
Tagspeicher_schreiben: ' Daten in EEprom schreiben
Incr Tagz 'Tagzähler hoch setzen

If Mess_eeprom_nr < Mess_eeprom_max Then
Incr Mess_eeprom_nr
End If
Mess_eeprom(mess_eeprom_nr) = Temp_str
Print "in EEPROM gespeichert " ; Temp_str 'für Test

'Warnung wenn Eeprom fast voll(wurde auf Max -2 eingestellt)
If Tagz >= Tagzm Then
Eepvoll = 1 'LED-Anzeige EIN Tageszähler
End If

'EEprom-Speicher voll?
'dann alte Werte verschieben damit neue Werte hinten angehängt werden können
If Mess_eeprom_nr >= Mess_eeprom_max Then

For C = 2 To Mess_eeprom_max
'Wert holen und einen Platz tiefer wieder speichern
Temp_str = Mess_eeprom(c)
Decr C
Mess_eeprom(c) = Temp_str
Incr C
Next C
End If

Return
'************************************************* ***************

Tagspeicher_lesen:

'***** EEprom Speicher printen wenn Taster= 0 ****

For C = 1 To Mess_eeprom_max
Temp_stralt = Mess_eeprom(c)
Print "aus EEPROM lesen: " ; Temp_stralt
Next C

'Speicherzähler im EEPROM zurücksetzen wir haben ja alles gelesen
Mess_eeprom_nr = 0
'Tageszähler zurücksetzen
Tagz = 0
Eepvoll = 0 'LED-Anzeige Aus
Zeit = 0 'nur für Test
Return

'================================================= =================

Nur die kurzen Intervalle sind für mich nicht befriedigend.(Industriestandart sind 36 Tage) Knalle ich aber 8 ST24C128 am Bus kann ich mich ca. 112 Tage Zeit fürAuslesung lassen .

Deine ??? über mein unverständlich Frage, wie ich alle 6 Single für Ausgabe an Terminal-Log übergebe ist OK Möchte wie es, in mein Codeschnipsel zu sehen ist, zum lesen alle Single als String zusammen bastelt.(Trennzeichen [;] )
Mit vielen Schritten bekomme ich es hin aber eine Lösung mit Overlay währ schon besser.
PS. Terminal-Log in eine Datei zu schreiben und dann mit Excel/ Access VBA „Schmuck“ zu machen benötige keine Hilfe.

Nun genug der Schreiberei, muss weiter klappern für Endlösung.

Viele Grüße auch von meiner Frau.
Frau soll sich aber nicht einbilden, nun werde ich die Bude putzen, es geht weiter. Ich:p Frau:(
fredred

Searcher
23.01.2014, 11:34
Hallo fredred,

Viele Grüße auch von meiner Frau. Frau soll sich aber nicht einbilden, nun werde ich die Bude putzen, es geht weiter. Ich:p Frau:(
Danke! und :lol:

Habe zur Zeit nicht die Ruhe um weiterzuschauen. Melde mich, wenn mir was einfällt. Bis dahin schon mal Gutes Weiterkommen.

Gruß
Searcher

fredred
09.02.2014, 12:20
Hallo Forum Mitglieder und Gäste
Guten Tag Searcher,

nun können wir das Thema beenden. Habe alles im Griff.
In mein aktuellem Projekt werden nun alle Variablen automatisch in Eeprom geschrieben und nach bedarf an Excel übergeben, für Auswertungen und grafische Abbildungen. Bild nur mal so im Anhang gelegt. Sehr aufwendige VBA da auch SD-Karten-Daten eingelesen werden können.
Natürlich bin ich auch, im nachhinein interessiert, für Optimierung oder Anregungen.
Somit erlaube ich mich, meine Test-Demo für I²C- Eeprom, mit zu senden.


'****************** Test-Demo **************************
'* ist ein Testmodul für Data extern EEprom als Speicher *
'* am I²C Bus ein 24c64 angeschlossen zum speichern *
'* und lesen der Variablen *
'* alle Variablen werden als Strings konvertiert. *
'* somit unabhänig von Daten-Typ. Auch lange Texte sind *
'* kein Problem mehr. *
'* Die Variablen können mit Hyperterminal_Log als CSV *
'* für Auswertungen an EXCEL übergeben werden *
'* oder nur auf LCD usw. *
'************************************************* ********


$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200 '19200

'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version auf Hyperterminal aus.
Print
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print
Waitms 100
$lib "i2c_TWI.lib" 'Hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz
'Format für Single zwei Nachkommastellen
'nur nötig wenn eine Var den Typ Single hat.
Config Single = Scientific , Digits = 2 '2 Nachkommastellen oder wie auch immer
Config Base = 0
'#### Eeprom Konstanten festlegen ###########
Const Dev_addr_write = &B10100000 'EEPROM Schreibadresse (ST24C64)
Const Dev_addr_read = &B10100001 'EEPROM Leseadresse
Const Stringanz = 6 'String Var Anzahl
Const Stringmax = 8 'für jedes String 8 Byte reserviert.
Const Speichervol = 16000 'maximale Speichergröße in Byte
'############################################

'!!!!!!! Übergabe von Konstanden NICHT ändern !!!!!!!!!!
Const Byteschleife = Stringanz + 1 'bedingt durch String
Const Stringab = Stringmax + 1
Dim Aktschleife As Word
Aktschleife = Stringanz * Stringmax
Aktschleife = Aktschleife + 9 'ist Summe aller Byte + String Endzeichen
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!
Dim Mem_addr As Word 'Adress Zähler
Dim J As Byte 'Laufvariable für Byte Schleife
Dim Mem_addr_low_byte As Byte At Mem_addr Overlay 'da Eeprom > 8kByte aufteilen
Dim Mem_addr_high_byte As Byte At Mem_addr + 1 Overlay
Dim Aktionen As Word 'Schreib-Zähler
Dim Aktionenl As Word 'Lese-Zähler

Dim S As Byte 'Laufvariable für for-next Schleife schreiben
Dim Number_from_rs(byteschleife) As String * Stringab 'Array der Schreib-Variablen
Dim Four_byte_var_write As String * Stringmax
Dim Byte_var_write(stringmax) As Byte At Four_byte_var_write Overlay ' Elemente Arrayindex
Dim L As Word 'Zyklus fortschreiben lesen 'alle Single_Variablen auslesen
Dim Four_byte_var_read As String * Stringmax
Dim Byte_var_read(stringmax) As Byte At Four_byte_var_read Overlay ' Elemente, Arrayindex
Dim Spst As Word
'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben
Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben
Config Portc.4 = Output
Eepvoll Alias Portc.4 'LED-Warnung für EEprom voll
'+++ zu Test ob I²C Hardware OK ist +++
Gosub I2c_test
'++++++++++++++++++++++++++++++++++++++
'Gosub Lesen 'nach Reset erstmal lesen

'### hier werden die Variablen für EEprom-Test festgelegt ##########
Dim Datum As String * Stringmax
Dim Zeit As String * Stringmax
Dim Var2 As String * Stringmax
Dim Var3 As String * Stringmax
Dim Var4 As String * Stringmax
Dim Var5 As String * Stringmax
Dim Var6 As String * Stringmax
'+++ Beispiel für Single ++++++
Dim Temperatur1 As Single
Temperatur1 = 19.66
Var2 = Str(temperatur1) 'Single als String übergeben
'+++++++++++++++++++++++++++++++
Mem_addr = 0 ' Sicher ist Sicher
'**** Hauptschleife ****
Do
'für Test einfach mal so
Datum = "07.11.13"
Zeit = "15:10:00"
'Var2 = "100.10" 'ist ausgeblendet da Beispiel aktiv
Var3 = "200.20"
Var4 = "300.30"
Var5 = "fredred"
Var6 = "Test-OK"

'Aktionen mit Taster in Echt durch Ereignis ersetzen zB. Timer
Debounce Taster_s , 0 , Schreiben , Sub 'entprellen
Debounce Taster_l , 0 , Lesen , Sub
'(
'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
')
Loop
'**** END Hauptsschleife ****

'### BEGINN in ext EEPROM schreiben (byte write method) ###
Schreiben:
'--- für Test ---
Print "Byte der Var-Variablen schreiben " ; "Aktionen " ; Aktionen
Print
'----------------
Mem_addr = Aktionen * Aktschleife 'step Aktionen
'LED Anzeige wenn Eeprom gelesen werden sollte
If Mem_addr >= 226 Then Eepvoll = 1 '226 ist nur ein Beispiel kann auch [Speichervol- xxx] sein
For S = 0 To Stringanz 'for-next mit 0 beginnen da Base = 0
If S = 0 Then Number_from_rs(0) = Datum
If S = 1 Then Number_from_rs(1) = Zeit
If S = 2 Then Number_from_rs(2) = Var2
If S = 3 Then Number_from_rs(3) = Var3
If S = 4 Then Number_from_rs(4) = Var4
If S = 5 Then Number_from_rs(5) = Var5
If S = 6 Then Number_from_rs(6) = Var6
Four_byte_var_write = Number_from_rs(s) 'String Variable L schreiben
For J = 0 To Byteschleife 'Laufschleife schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
'--- nur für Test ---
Print "Var-Variable " ; S ; " = Adresse " ; Mem_addr ; " Bytewert " ; Byte_var_write(j)
'--------------------
Next J
'--- nur für Test ---
Print "!! Ausgabe !! " ; Four_byte_var_write
Print
'---------------------
Next S
Incr Aktionen 'nächsten Schreibzyklus anstoßen
Return
'### ENDE ext EEPROM schreiben ###

'-----------------------------------------------------------
'### BEGINN aus ext.EEPROM lesen ###
Lesen:
Mem_addr = 0 'da Variable auch für schreiben gesetz ist zum lesen zurück setzen.
Aktionenl = 0
For Mem_addr = Aktionenl To Speichervol 'ist max Byte für Eeprom
'--- nur für Test ---
' Print "Byte der 6 Var-Variablen lesen " ; "Zyklus " ; Aktionenl
' Print
'--------------------
For L = 0 To Stringanz
For J = 0 To Byteschleife 'Laufschleife lesen
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
Waitms 10
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen
'--- nur für Test ---
' Print "Var_Variable " ; L ; " = Byte " ; Mem_addr ; " Bytewert " ; Byte_var_read(j)
'--------------------
Next J
'### BEGINN Terminal_log Ausgabe für Auswertungen in Excel ###
'### CSV Trenzeichen ist [;] ###
Print Four_byte_var_read ; ";" ;
'Daten wurden gesichert
Eepvoll = 0 'LED aus
'schreiben beginnt wieder ab Adr 0. Rest bleib erhalten.
Aktionen = 0
'wenn -NAN dann Auslesung beenden(soll nicht unbeschriebenen Speicher lesen)
If Four_byte_var_read = "" Then
Return
End If
Next L
Print Chr(10) 'wird benötigt für CSV(Zeilenumbruch nach Zyklus)
Incr Aktionenl 'Lesezyklus hochzählen bis -Nan
Next Mem_addr
Return
'#### ENDE ext.EEPROM lesen ####

'-----------------------------------------------------
I2c_test:
Dim Busaddress As Byte
Dim Busaddress_read As Byte
Dim Chipaddress As Byte
Print "I2C Scan start"
'I²C Porterweiterung testen
'Alle Adresen suche und Anzeigen
'Step 2 soll nur IC Adresse aufrufen für lesen
For Chipaddress = 0 To 254 Step 2 ' IC's am I²C-Bus erkennen
I2cstart 'send start
I2cwbyte Chipaddress 'sende Addresse auf Bus
If Err = 0 Then 'Chip gefunden
If Chipaddress = Dev_addr_write Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein ST24C64 Adr 000"
End If
'hier können noch weitere I²C IC Teilnehmer abgefragt werden.
'(
If Chipaddress = xxx Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
End If
')
End If
Next
Return


Danke an alle für Hilfe und verbleibe bis zum nächstem Problem
Mit freundlichen Grüßen

fredred
11.02.2014, 16:44
Hallo Leute,

Theorie OK und Praxis zeigt, nicht alles ist OK
Erfahrung:
Nach Einsockeln eines „jungfräulichen“ Eeprom, war eine kleine Optimierung nötig.
Eeprom lesen immer bis zum Ende des Speichers, sollt doch nicht sein.
Die [var_read] ist ja werkseitig immer 255, somit noch dies eingefügt und Abfragen höher gelegt.

If Four_byte_var_read = "" Or Byte_var_read(j) = 255 Then
Nun wird lesen beendet, wenn Speicherplatz „leer „

Auch nach Auslesung des Eeprom wieder von Adr 0 zu beschreiben, war Dumm, nun wird [Mem_Addr] schreiben erst auf 0 gesetzt, wenn [Speichervoll]. Gleiches gilt auch beim Schreiben. Somit erhalten alle Speicherplätze die gleiche „Lebensdauer“


Nun der aktuelle Code.



'****************** Test-Demo **************************
'* ist ein Testmodul für Data extern EEprom als Speicher *
'* am I²C Bus ein 24c64 angeschlossen zum speichern *
'* und lesen der Variablen *
'* alle Variablen werden als Strings konvertiert. *
'* somit unabhänig von Daten-Typ. Auch lange Texte sind *
'* kein Problem mehr. *
'* Die Variablen können mit Hyperterminal_Log als CSV *
'* für Auswertungen an EXCEL übergeben werden *
'* oder nur auf LCD usw. *
'************************************************* ********


$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 32
$framesize = 40
$baud = 19200 '19200

'gibt den Erstellungszeitpunkt im europäischen Format DD-MM-YY hh:nn:ss
'und die Code-Version auf Hyperterminal aus.
Print
Print "erstallt am : " ; Version(1)
Print "Version Code : " ; Version(3)
Print
Waitms 100
$lib "i2c_TWI.lib" 'Hardware I²C einbinden
Config Twi = 100000 ' Takt 100kHz
'Hinweis: Diese Einstellung reserviert ein paar ROM-Speicher mehr..
'nur nötig wenn eine Var den Typ Single hat. Die letzte Stelle wird gerundet.
'Format für Single zwei Nachkommastellen
Config Single = Scientific , Digits = 2 '2 Nachkommastellen oder wie auch immer
Config Base = 0 'alle Zähler mit 0 beginnen
'mehrer unterschiedliche I²C IC am Bus "anzuhängen" ist mit Dev_addr Select kein Problem.
'#### Eeprom Konstanten festlegen ###########
Const Dev_addr_write = &B10100000 'EEPROM Schreibadresse (ST24C64)
Const Dev_addr_read = &B10100001 'EEPROM Leseadresse (ST24C64)
Const Stringanz = 6 'String Var Anzahl
Const Stringmax = 8 'für jedes String 8 Byte reserviert.
Const Speichervoll = 16000 'maximale Speichergröße in Byte (zB.ST24C64)
'############################################
'!!!!!!! Übergabe von Konstanden NICHT ändern !!!!!!!!!!
Const Byteschleife = Stringanz + 1 'bedingt durch String
Const Stringab = Stringmax + 1
Dim Aktschleife As Word
Aktschleife = Stringanz * Stringmax
Aktschleife = Aktschleife + 9 'ist Summe aller Byte + String Endzeichen
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!
Dim Mem_addr As Word 'Adress Zähler
Dim J As Byte 'Laufvariable für Byte Schleife
Dim Mem_addr_low_byte As Byte At Mem_addr Overlay 'da Eeprom > 8kByte aufteilen
Dim Mem_addr_high_byte As Byte At Mem_addr + 1 Overlay
Dim Aktionen As Word 'Schreib-Zähler
Dim Aktionenl As Word 'Lese-Zähler

Dim S As Byte 'Laufvariable für for-next Schleife schreiben
Dim Number_from_rs(byteschleife) As String * Stringab 'Array der Schreib-Variablen
Dim Four_byte_var_write As String * Stringmax
Dim Byte_var_write(stringmax) As Byte At Four_byte_var_write Overlay ' Elemente Arrayindex
Dim L As Word 'Zyklus fortschreiben lesen 'alle Single_Variablen auslesen
Dim Four_byte_var_read As String * Stringmax
Dim Byte_var_read(stringmax) As Byte At Four_byte_var_read Overlay ' Elemente, Arrayindex
'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben
Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben
Config Portc.4 = Output
Eepvoll Alias Portc.4 'LED-Warnung für EEprom voll
'+++ zu Test ob I²C Hardware OK ist +++
Gosub I2c_test
'++++++++++++++++++++++++++++++++++++++
'Gosub Lesen 'nach Reset erstmal lesen

'### hier werden die Variablen für EEprom-Test festgelegt ##########
Dim Datum As String * Stringmax
Dim Zeit As String * Stringmax
Dim Var2 As String * Stringmax
Dim Var3 As String * Stringmax
Dim Var4 As String * Stringmax
Dim Var5 As String * Stringmax
Dim Var6 As String * Stringmax
'+++ Beispiel1 für Single ++++++
Dim Temperatur1 As Single
Temperatur1 = 19.55 'sind 4Byte
Var2 = Str(temperatur1) 'Single als String übergeben
'+++++++++++++++++++++++++++++++
'+++ Beispiel2 für Single ++++++
Dim Temperatur2 As Single
Temperatur2 = -3.55 'sind 4Byte
Var3 = Str(temperatur2) 'Single als String übergeben
'+++++++++++++++++++++++++++++++
Mem_addr = 0 ' Sicher ist Sicher
'**** Hauptschleife ****
Do
'für Test einfach mal so
Datum = "01.02.14"
Zeit = "15:10:00"
'Var2 = "100.10" 'ist ausgeblendet da Beispiel aktiv
'Var3 = "123456" 'ist ausgeblendet da Beispiel aktiv
Var4 = "300.30"
Var5 = "fredred"
Var6 = "Test-OK"

'Aktionen mit Taster in Echt durch Ereignis ersetzen zB. Timer
Debounce Taster_s , 0 , Schreiben , Sub 'entprellen
Debounce Taster_l , 0 , Lesen , Sub
'(
'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
')
Loop
'**** END Hauptsschleife ****

'### BEGINN in ext EEPROM schreiben (byte write method) ###
Schreiben:
'--- für Test ---
Print "Byte der Var-Variablen schreiben " ; "Aktionen " ; Aktionen
Print
'----------------
Mem_addr = Aktionen * Aktschleife 'step Aktionen
'LED Anzeige wenn Eeprom gelesen werden sollte
If Mem_addr >= 626 Then Eepvoll = 1 '626 ist nur ein Beispiel kann auch [Speichervol- xxx] sein
For S = 0 To Stringanz 'for-next mit 0 beginnen da Base = 0
If S = 0 Then Number_from_rs(0) = Datum
If S = 1 Then Number_from_rs(1) = Zeit
If S = 2 Then Number_from_rs(2) = Var2
If S = 3 Then Number_from_rs(3) = Var3
If S = 4 Then Number_from_rs(4) = Var4
If S = 5 Then Number_from_rs(5) = Var5
If S = 6 Then Number_from_rs(6) = Var6
Four_byte_var_write = Number_from_rs(s) 'String Variable S schreiben
For J = 0 To Byteschleife 'Laufschleife schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM
'--- nur für Test ---
Print "Var-Variable " ; S ; " = Adresse " ; Mem_addr ; " Bytewert " ; Byte_var_write(j)
'--------------------
Next J
'--- nur für Test ---
Print "!! Ausgabe !! " ; Four_byte_var_write
Print
'---------------------
Next S

'ist Speicher am Ende dann wieder von vorn
If Mem_addr = Speichervoll Then
'schreiben beginnt wieder ab Adr 0. Rest bleib erhalten.
Aktionen = 0
End If
Incr Aktionen 'nächsten Schreibzyklus anstoßen
Return
'### ENDE ext EEPROM schreiben ###

'-----------------------------------------------------------
'### BEGINN aus ext.EEPROM lesen ###
Lesen:
Mem_addr = 0 'da Variable auch für schreiben gesetz ist zum lesen zurück setzen.
Aktionenl = 0 'starte Lesung bei Adr 0
For Mem_addr = Aktionenl To Speichervoll 'ist max Byte für Eeprom
'--- nur für Test ---
' Print "Byte der 6 Var-Variablen lesen " ; "Zyklus " ; Aktionenl
' Print
'--------------------
For L = 0 To Stringanz
For J = 0 To Byteschleife 'Laufschleife lesen
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
Waitms 10
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen
'--- nur für Test ---
' Print "Var_Variable " ; L ; " = Byte " ; Mem_addr ; " Bytewert " ; Byte_var_read(j)
'--------------------
'wenn -NAN dann Auslesung beenden(soll nicht unbeschriebenen Speicher lesen)
If Four_byte_var_read = "" Or Byte_var_read(j) = 255 Then
Return
End If
Next J
'### BEGINN Terminal_log Ausgabe für Auswertungen in Excel ###
'### CSV Trenzeichen ist [;] ###
Print Four_byte_var_read ; ";" ;
'Daten wurden gelesen
Eepvoll = 0 'LED aus
'Nach Zwischenauslesung Speicherbereich fortsschreiben soll ja nicht
'immer die gleichen Zellen besschreiben("Lebensdauer")
If Mem_addr = Speichervoll Then
'schreiben beginnt wieder ab Adr 0. Rest bleib erhalten.
Aktionen = 0
End If
Next L
Print Chr(3) 'wird benötigt für CSV(End Off Text nach Zyklus)
Incr Aktionenl 'Lesezyklus hochzählen bis -Nan
Next Mem_addr
Return
'#### ENDE ext.EEPROM lesen ####

'-----------------------------------------------------
I2c_test:
Dim Busaddress As Byte
Dim Busaddress_read As Byte
Dim Chipaddress As Byte
Print "I2C Scan start"
'I²C Porterweiterung testen
'Alle Adresen suche und Anzeigen
'Step 2 soll nur IC Adresse aufrufen für lesen
For Chipaddress = 0 To 254 Step 2 ' IC's am I²C-Bus erkennen
I2cstart 'send start
I2cwbyte Chipaddress 'sende Addresse auf Bus
If Err = 0 Then 'Chip gefunden
If Chipaddress = Dev_addr_write Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein ST24C64 Adr 000"
End If
'hier können noch weitere I²C IC Teilnehmer abgefragt werden.
'(
If Chipaddress = xxx Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein ICxxx Adr xxx"
End If
')
End If
Next
Return


Wird wohl nicht der letzte sein
PS. Bin gerate dabei 2 * ST24C512 am Bus als Massenspeicher zu „hängen“.

Mit freundlichen Grüßen
fredred