PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Adressierung i2c eeprom 24c65



mat-sche
24.12.2007, 19:09
zu erst ein schönes Weihnachtsfest euch allen!

Ich habe folgendes Problem:

nach langem suchen habe ich einen Code gefunden (unten) mit dem ich mein eeprom beschreiben und auch wieder auslesen kann.
Mir ist nur noch schleierhaft, wie ich die Speicherzellen/Speicherbereiche, also in hex, für jedes Byte der 64kbit ermitteln kann.

Und was sagt Ihr zu dem Code, gibt es eine bessere Methode, um über i2c auf ein eeprom zu zugreifen?

=>code bitte<= :)







$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
$hwstack = 228
$swstack = 228
$framesize = 128
$lib "i2c_twi.lbx"
Config Twi = 400000 ' Init TWBR und TWSR
' TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !
TWCR = &B00000100 ' nur TWEN setzen

'----------------- LCD Display an Port c =>Conector SV9-------------------------------------------------------------------------------------------------

Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 ' Pinbelegung "LCD-Port)"
' SV8 6 5 4 3 7 8 ' Pinbelegung SV9 Board
'------------------ DS1820 on pinA 0 (pull up)--------------------------------------------------------------------------------------------------------------------------------------


'

'--------- Eeprom Anschlüße ------
Config Sda = Portc.1 'SDA und SCL definieren
Config Scl = Portc.0


Const E_ctlw = &HA0
Const E_ctlr = &HA1

Dim E_ah As Byte
Dim E_al As Byte
Dim E_addr As Word
Dim E_dat As Byte
Dim Dat As Byte

Declare Sub E_write(byval E_addr As Word , Dat As Byte)
Declare Sub E_read(byval E_addr As Word , E_dat As Byte)
Declare Sub 24lc256_test

call 24lc256_test
end

' Routine to test the 24LC256
'
Sub 24lc256_test
'Test read and writes
Print "Testing I2C Eeprom"
Dat = 10
For E_addr = &H1000 To &H1010
Call E_write(e_addr , Dat)
Call E_read(e_addr , E_dat)
Print E_dat ; " ";
Incr Dat
Incr Dat
Incr Dat ' +1 +1 +1
Next E_addr

Print
Print "Here a counter should appear from 0, 3, 6, 9, 12, 15, 18,21, 24, 27 etc."
Print "End of Test"
End Sub


' Routine to write the 24LC256
'
Sub E_write(byval E_addr As Word , Dat As Byte)
E_ah = High(e_addr)
E_al = Low(e_addr)
I2cstart
I2cwbyte E_ctlw
I2cwbyte E_ah
I2cwbyte E_al
I2cwbyte Dat
I2cstop
Waitms 10
End Sub


' Routine to read the 24LC256
'
Sub E_read(byval E_addr As Word , E_dat As Byte)
E_ah = High(e_addr)
E_al = Low(e_addr)
I2cstart
I2cwbyte E_ctlw
I2cwbyte E_ah
I2cwbyte E_al
I2cstart
I2cwbyte E_ctlr
I2crbyte E_dat , Nack
I2cstop '
End Sub

Vielen Dank und gute und erholsame Feiertage!

MAT

Rofo88
24.12.2007, 20:27
Wenn Du die Adresse mit ner Overlay-Variable versiehst gehts einfacher...schaue mal ins Wiki

https://www.roboternetz.de/wissen/index.php/Bascom_und_I2C_EEprom

ein schönen Fest noch

stefan_Z
24.12.2007, 22:17
Schau hier mal, das Problem hatte ich auch schon mal.
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=286178

Klappt super, je nach EEP-ROM-Größe muss man noch die Adresse anpassen (s. Datenblatt). Im Pollinboard v2 ist es in der Tat so, dass der Schreibschutz-Pin fest auf VCC gelegt ist, daher muss man den zum Beschreiben hochbiegen/isolieren...

mat-sche
25.12.2007, 14:29
Soooo.....

der Weihnachtsmann war nicht da ](*,) , drum bastle ich weiter O:)

Gestern hab ich es nun endlich geschafft das eeprom zu beschreiben.
Ich denke mir, dass bei einer 64kbit, also 8192 byte, großem Speicher das zu erst speichernde byte bei &H0 beginnt und bei &H1 weiter geht?!

Ist das so richtig? oder wie spricht man die einzelnen byte Speicherzellen, ihre Adresse, an?

Dann ist die nächste Frage, wie kann ich die Informationen in den einzelnen Speicherzellen wieder löschen oder reicht es wenn ich diese wieder überschreibe?

Gruß MAT

Rofo88
25.12.2007, 14:45
Ja da hast Du recht die erste Speicherzelle ist bei &H0 weiter gehts mit &H1; &H2 usw.

Zum löschen kann man die Speicherzelle einfach überschreiben.

mat-sche
25.12.2007, 15:02
@rofo88

dann hat sich ja das ausschlafen heute geloht :D

Dann hab ich aber noch eine Frage, wie kann ich single Werte in dem EEprom speichern?

Rofo88
25.12.2007, 15:38
Ich glaube das Single-Werte und IIC-EEPROM von Bascom nicht direkt unterstütz werden.

Also mußt Du den Single-Wert in die einzelnen Bytes zerlegen und die Bytes dann ins EEPROM schieben.


Dim X As Single At $100
Dim A As Byte At $100 Overlay
Dim B As Byte At $101 Overlay
Dim C As Byte At $102 Overlay
Dim D As Byte At $103 Overlay

Damit hast Du die Single-Variable X in 4 Bytes zerlegt und kannst die ins EEPROM schieben.

mat-sche
25.12.2007, 15:52
hmmmm.

Nur leider habe ich das noch nicht richtig mit dem overlay verstanden.

Ich bekomme eine Variable temp (single) von meinem ds1820 und Deiner Meinung nach, muss ich dann diese in 4 einzelne byte oder in 2 word auftrennen. Und in den eeprom schieben.

Beim Auslesen muss ich diese doch auch wieder in einen single umwandeln.

Gibt es unter bascom ne Funktion zum wandeln von/zu und zurück?

stefan_Z
25.12.2007, 16:52
Ja, ne, das mit dem OVERLAY geht anders (habs eben auch dank dem Sample kapiert):
- X ist die single und belegt am Speicherplatz $100 vier Bytes (eben Nr. 100-103)
- A bis D werden auf dem selben Speicherplatz reserviert - A auf $100 usw.
- Wenn du X veränderst, dann werden automatisch auch die anderen 4 Variablen geändert - und umgekehrt genauso.
Natürlich darfst du bei sowas die Variablen nicht einfach für ne FOR NEXT Schleife nutzen (außer du verstehst, was da passiert), denn sonst verlierst du ja die Inhalte.

mat-sche
25.12.2007, 18:04
Nun das mit dem Overlay ist wohl die richtige Richtung....

ich kann es nur nicht in einen Code umwandeln:

1. ich empfange ein single der aus 4 byte besteht
2. ich muss diesen in 2 word oder in 4 bytes teilen
3. dann will ich diese, abhängig der Aufteilung, in eine bestimmte Adresse im eeprom speichern
und 4. lese ich dann die Adressen wieder aus und setze die einzelnen bytes/words wieder zusammen

ABER WIE??? das ist mein Problem!

Hat jemand einen Lösungsansatz?

stefan_Z
25.12.2007, 21:22
Du machst das mit dem Overlay und hast ja dann deine vier Bytes!
Also den Empfangenen Wert in X speichern und dann hast du die Bytes A B C D, die du nacheinander ins EEP schreibst.
Du kannst A B C D auch wieder nacheinander aus dem EEP lesen und dann X Printen - und SCHWUPPS ist der ganze Wert wieder da!

mat-sche
26.12.2007, 09:44
Morgen!

Gestern, kurz vor'm bowlen ist mir die Overlayfunktion aufgegangen und ich werd das mal ausprobieren. Was ich nur noch nicht versteh/weiß ist, was die $100 bedeuten. Ich denke mal, dass dies eine Zeiger für den Zwischenspeicher im AVR ist?!
Kann mir das irgend wer mal erklären?

MAT

stefan_Z
27.12.2007, 01:28
$100 ist die Speicheradresse des 1. Bytes
Und da $101 die 2. ist nehme ich mal an, dass die immer 1 Byte groß sind ;-)
Und um deine Frage von hier https://www.roboternetz.de/phpBB2/viewtopic.php?t=36650&sid=09ab971e86e961357b4fbee8aec5743d zu beantworten:
Die vier Werte in Variablen ABCD einlesen und dann mit PRINT X an den Rechner schicken. Dann brauchts auch kein Excel mehr!
Und wenns in Excel sein muss:
(niedrigstes Byte) + (2. Byte * 256) + (3. Byte * 65536) + (4. Byte * 16777216) = ganzer Wert

mat-sche
27.12.2007, 12:40
Heyho Stefan,

im Prinzip hast Du recht mit dem Printbefehl, doch warum soll ich Kontrollerkapazität verschwenden wenn ich den eeprom singleweise auslese und mit z.Bsp. Exel auswerte.

$100 kann es auch sein, dass es die Speicherzuweisung vom benutzten S-Ram ist?

und dann hab ich noch einige Verständnisprobleme zu Deiner Exellösung!,
steh irgendwie auf`m Schlauch. Muss aber sagen, dass ich auch nicht die Ahnung von Exel habe. Könntest Du das noch mal ein wenig beschreiben

@all:

hier nun mein fertiger Code für einmal Speicher nach Tasterdrücken und auslesen nach Tasterdrücken:



'************************************************* *********

'Programm : 1xTemp-Messung mit EEpromspeicherung
'By : mat-sche
'Compiler : BASCOM-AVR 1.11.8.8
'Hardware : DS1820 an Port A.0
' with calculated for 0.1 C resolution
' LCD-Display 4x20 an PortC
' EEprom 24c65 (64kBit) an Hardware TWI
'Chip type : MEGA32
'Date : 27.12.2007
'************************************************* *********

$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
$hwstack = 228
$swstack = 228
$framesize = 128
$lib "i2c_twi.lbx" 'TWI-Lib für Hardware I2C


'----------------- LCD Display an Port c =>Conector SV9 ------------------------
Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 ' Pinbelegung "LCD-Port)"
' SV9 6 5 4 3 7 8 ' Pinbelegung SV9 Board
Config Lcd = 20 * 4
Cursor Off Noblink
'------------------ DS1820 on pinA 0 (pull up)----------------------------------

Config 1wire = Porta.0 '

Declare Sub Read1820
Declare Sub Crcit
Declare Sub Temperature

Dim Bd(9) As Byte
Dim I As Byte , Tmp As Byte
Dim Crc As Byte
Dim T As Integer , Temp As Single
Dim V As Byte , A As Word
'

'----------------- Config TWI --------------------------------------------
Config Twi = 400000 ' Init TWBR und TWSR
' TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !
Twcr = &B00000100 ' nur TWEN setzen
'----------------- Eeprom Anschlüße --------------------------------------------
Config Sda = Portc.1 'SDA und SCL als Hardware-TWI definieren
Config Scl = Portc.0
Portb.2 = 1 'Pullups für Taster ein
Portb.3 = 1
Const E_prom_w = &HA0 'Epromadresse 160 (A1/2/3 auf GND) schreiben
Const E_prom_r = &HA1 'Epromadresse 160+1 für schreiben der Daten

'EEprom 24C32,24C128, 24C256 haben im Gegensatz zu den 24C16'er einen Adressraum von zwei Byte.
'Weil grösserer Speicherbereich im EEprom vorhanden ist Darum muss man den Adressbereich in High und Low Adressbereich
'trennen. (Zuerst High-Adressbereich schreiben und dann Low-Adressbereich)
Dim E_ah As Byte 'höherwertiges Byte der SpeicherAdresse (Adresse=Word)
Dim E_al As Byte 'niederwertiges Byte der SpeicherAdresse (Adresse=Word)
Dim E_addr As Word 'SpeicherAdresse EEprom
Dim E_dat_r As Byte 'Daten der zu lesenen Daten aus EEprom
Dim E_dat_w As Byte 'Daten der zu schreibenen Daten ins EEprom
Dim Temperature As Single
Dim Storetemp(4) As Byte At Temperature Overlay 'Maske: weise die 4Byte aus dem Single(Temperature) dem
'Storetemp(1-4) zu

Declare Sub E_write(byval E_addr As Word , E_dat_w As Byte) 'Sub zum schreiben in EEprom mit Übergabe einer Kopie der Variable (Eaddr/E_dat_w)
Declare Sub E_read(byval E_addr As Word , E_dat_r As Byte) 'Sub zum lesen aus EEprom
Declare Sub 24lc256_test


'------------------ Startbildschirm --------------------------------------------




Cls 'clear the LCD display
Locate 1 , 1
Lcd "Speicherung 1xTemp." 'display this at the 1.line

Locate 2 , 1 'display this at the 2. line
Lcd " im EEprom 24c65 "

Locate 3 , 1 'display this at the 3.line
Lcd "Taster S7 speichern"

Locate 2 , 1 'display this at the 4.line
Lcd "Taster S8 auslesen"

Wait 5
Cls
'------------------ Hauptprogramm ----------------------------------------------
Do
Temperature

If Pinb.3 = 0 Then Call 24lc256_test
If Pinb.2 = 0 Then

Cls
Locate 2 , 1
Lcd Storetemp(1) ; " " ; Storetemp(2) ; " " ; Storetemp(3) ; " " ; Storetemp(4) ; ""; 'Anzeige der 4 einzelnen Bytes aus dem Overlay der Temperatur
Locate 3 , 1
Call E_read(&H10 , E_dat_r) 'Aufruf der Subroutine zum lesen der einzelnen Bytes
Call E_read(&H11 , E_dat_r) 'E_read(&H10 , E_dat_r)
Call E_read(&H12 , E_dat_r) ' &H10 - zu lesende Adresse aus EEprom
Call E_read(&H13 , E_dat_r) ' E_dat_r - Daten aus dem Speicherort
Lcd "Speicherwert= " ; Temperature ; "" 'Anzeige der Temperature zusammengesetzt aus dem Overlay: Storetemp(4)
Locate 4 , 1 : Lcd "Read i2c error= " ; Err 'Err: Daten korrekt gesendet? 0=i.o.; 1=bad
End If




Loop

End


'////////////////// Subroutinen ////////////////////////////////////////////////
Sub Temperature ' actual measuring

1wwrite &HCC : 1wwrite &H44 ' start measure
Waitms 300 ' wait for end of conversion
Read1820
Deflcdchar 0 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32 ' replace ? with number (0-7) ' read 9 bytes
Locate 1 , 1 : Lcd "Temperatur= "
' sensor present, check CRC
Locate 1 , 13 : Lcd Fusing(temp , "#.##") ; Chr(0) ; "C" ' CRC OK, print T*10 on LCD

End Sub

'//////////////////////////////////////////////////////////////////////////////
Sub Read1820 ' reads sensor ans calculate
' T for 0.1 C
1wreset ' reset the bus
1wwrite &HCC ' read internal RAM
1wwrite &HBE ' read 9 data bytest
Bd(1) = 1wread(9) ' read bytes in array
1wreset ' reset the bus


T = Makeint(bd(1) , Bd(2))
T = T / 2
Temp = Bd(8) - Bd(7)
Temp = Temp / Bd(8)
Temp = T + Temp
Temp = Temp - 0.25

End Sub
'///////////////////////////////////////////////////////////////////////////////'
Sub 24lc256_test


Temperature = Temp
Call E_write(&H10 , Storetemp(1))
Call E_write(&H11 , Storetemp(2))
Call E_write(&H12 , Storetemp(3))
Call E_write(&H13 , Storetemp(4))

End Sub
'///////////////////////////////////////////////////////////////////////////////
' Routine to write the 24C65

Sub E_write(byval E_addr As Word , E_dat_w As Byte )
E_ah = High(e_addr) 'E_ah = EEprom high Adressbyte der jeweiligen Word-Adresse (H&10)
E_al = Low(e_addr) 'E_ah = EEprom low Adressbyte der jeweiligen Word-Adresse (H&10)
I2cstart 'Start I2C
I2cwbyte E_prom_w 'Sende Slave Adresse
I2cwbyte E_ah 'Sende Speicheradresse High
I2cwbyte E_al 'Sende Speicheradresse Low
I2cwbyte E_dat_w 'Sende Daten Werte
I2cstop 'Stop I2C
Waitms 10
End Sub

'///////////////////////////////////////////////////////////////////////////////
' Routine to read the 24C65

Sub E_read(byval E_addr As Word , E_dat_r As Byte)
E_ah = High(e_addr)
E_al = Low(e_addr)
I2cstart
I2cwbyte E_prom_w
I2cwbyte E_ah
I2cwbyte E_al
I2cstart
I2cwbyte E_prom_r
I2crbyte E_dat_r , Nack
I2cstop '
End Sub


Dank & Gruß MAT

stefan_Z
27.12.2007, 15:48
Wieso verschwendest du irgendwas? Haste auf dem AVR noch deinen Webserver und eine Callcenter Datenbank laufen?
Die $100 ist sicherlich die Speicheradresse im RAM, daarum gehts ja dabei. Und da die 4 anderen Variablen den selben Platz belegen verschwendest du nichts (vielleicht vier zusätzliche Stackpointer, aber das is nicht viel...)
Das Rechenbeispiel für Excel ist die ganz normale Umwandlung von mehreren Bytes in einen Word-/Single-Wert.
8 Bits können 256 Zustände annehmen. Wenn ich dann das 2. Byte (das ja den nächsten Teil vom Zahlenraum abbildet) zurechnen will, muss ich die Nullen um ein Byte verschieben - eben um die 256. Das 3. Byte dann um 256*256 usw... Was du nur wissen musst ist, welches Byte das niedrigste und welches das höchste ist - das steht aber im Datasheet vom Chip...

mat-sche
27.12.2007, 16:23
Verschwenden will ja keiner etwas :D, und wenn ich einen Webserver darauf liefen lassen könnte würde ich an die Decke springen :) .
Leider bin ich noch weit davon entfernt.

Danke Dir erstmal noch für die Hilfen, ich habe bei dieser Geschichte schon einiges dazu gelernt. Werde mir als nächstes mal einige PCF-IC anschauen und mein Wissen vertiefen!

Dank noch mal!

MAT