Sind Pullups auf den beiden Leitungen ?
Hallo schon wieder ich (werd langsam lästig),
hab versucht ein EEPROM an einen Mega8 zu hängen - Geht nicht.
Was mir allerdings aufgefallen ist, im Simulator sind vor
Config Scl = Portb.1
Config Sda = Portb.2
keine so gelben Punkte. Hat das was zu bedeuten?
mfg
Flo
Sind Pullups auf den beiden Leitungen ?
Hat der 24C256 keinen internen Pushup?
Also an Scl und Sda jeweils ein 10k nach 5V oder?
mfg
Flo
Wahrscheinlich nicht, und wenn, dann müsste man sie ein- und ausschalten können. Wäre ja sonst fatal, stell Dir mal vor, jeder I2C-Teilnehmer hätte interne Pullups...Zitat von iltis
Ein Tipp dazu, Du kannst in Bascom den Status des I2C-Busses auswerten:
Code:I2csend &B01110000 , B ' send the value Print "Error : " ; Err ' show error status I2creceive &B01110000 , X ' get a byte Print X ; " " ; Err ' show errorGanz heiße Frage, da gehen die Meinungen ein wenig auseinander!Zitat von iltis
Das richtet sich nach der Leitungslänge und -kapazität, derI2C- Teilnehmerzahl, und vermutlich spielen auch noch die Mondphasen, der Luftdruck und der Bio-Rhythmus des Programmierers eine Rolle...
Bei mir funktioniert die Sache bislang auf zwei Boards problemlos mit je 1x 10k gegen VCC. Vielleicht habe ich aber auch einfach nur Glück gehabt.
Ich habe mal einen "Reichweiten-Test" gemacht, bei etwa 40cm Kabellänge (ungeschirmt) war Sense und die I2C-Kommunikation brach zusammen.
In der Bascom-Hilfe ist auch noch eine aktive Terminierung mit Hilfe von ein paar Transistoren beschrieben.
Die ist wohl besser, wenn der Bus über etwas größere Entfernungen laufen soll, bis zu 80cm wären problemlos möglich , heisst es dort.
Viele Grüße
Torsten
Wenn ein Pushup bei Frauen hilft - warum dann nicht auch bei EEproms?
Es geht jetzt!
Hätte ja die Bascomhilfe gelesen, wenn sie bei mir gehen würde!
mfg
Flo
Hallöchen...
Ich habe mir auch mal ein Testboard aufgebaut, mit nem mega16 drauf.
ausserdem ist ein MAX232, ein Oszillator 4MHz und ein Quarz 16MHz und ISP,
I2C und ein EEPROM am I2C mit dran (mit extra 10k PULLUPs)
Nun würde ich gern den EEPROM (Atmel 24c256) mal ansprechen.
Da ich noch keine Ahnung von I2C habe wollte ich mal fragen wie der Bascom-Code aussehen muss?
mit dem Code aus der Bascom- Hilfe friert das Programm ein, schreibt nix mehr über RS232 auf n Laptop, meine Interruptbehandlung läuft aber weiter (LED blinkt im Sekundentakt)
danke schonmal im Voraus für die Hilfe.
Ich häng mal ein Bild von meinem Board dran (Streifenrasterplatine)
Hab hier was für dich....kann Bytes, Words und Singles in einem EEPRom schreiben und lesen. Du kannst die Datei einfach per Include laden und dann bequem die Subs und Funcs verwenden. Verwendet wird hier der Hardware-TWI, kann auch für Soft-TWI geändert werden. Ist zwar für ein 24c64 EEPROM, geht jedoch auch mit größeren...mußt evtl. die Adresse des EEProms ändern.
Code:$lib "i2c_TWI.lib" Config Scl = Portc.0 'PINs für I2C Bus Config Sda = Portc.1 I2cinit Config Twi = 400000 Dim Eehead(2) As Byte Dim Eebyte(4) As Byte Dim Eesingle As Single At Eebyte Overlay Dim Eeword(2) As Word At Eesingle Overlay Dim Eebanz As Byte Dim Ee_adresse01 As Word At Eehead Overlay Dim Eead As Word Const 24c64w = &B10100000 Const 24c64r = &B10100001 '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(byval Ee_daten As Byte , Byval Ee_adresse As Word) Declare Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word) Declare Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word ) Goto 001 Sub Savebyte(byval 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(byval 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(byval 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: 'Disable Interrupts Eead = Eead + Eebanz Eebanz = Eebanz + 2 I2csend 24c64w , Eehead(1) , Eebanz 'Waitms 10 'Enable Interrupts 'If Err = 1 Then Call Error(55) Return 'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++ Read_ee: 'Disable Interrupts Eead = Eead + Eebanz I2csend 24c64w , Eehead(1) , 2 'Waitms 10 I2creceive 24c64r , Eebyte(1) , 0 , Eebanz 'Waitms 1 'Enable Interrupts 'If Err = 1 Then Call Error(55) Return 001: Dim Ins As Single Dim Inw As Word Dim Inb As Byte Dim I As Word Do Input "Single: " , Ins For I = 20 To 100 Step 4 Call Savesingle(ins , I) Next I Print "gespeicherter Wert: " ; Ins Ins = Loadsingle(20) 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 For I = 10 To 410 Step 4 Call Savesingle(0 , I) Next I
@Rage_Empire
Besten Dank für die schnelle Hilfe...
jetzt klappt alles.
Habe den Code von dir mal in mein Testprogi eingebaut, ist doch ok, oder?
Habe sicherheitshalber auch noch den Writeprotect-Pin des EEPROM auf masse gelegt.
hier ist mein 'alles mögliche Test-Programm'
Wenn Pina.0, Pina.2 oder Pina.4 auf null gehen, wirs jeweils die Eingabe einer Variablen gefordert und in den EEPROM geschrieben.Code:'####################################################### '# Erster Versuch ATMega16 # '# 3 Taster # '# 2 LEDs # '# I2C, ISP, serial-232, extra 4MHz Oszi # '# I2C EEPROM 24c256 # '####################################################### $regfile = "m16def.dat" $framesize = 32 $swstack = 32 $hwstack = 32 $crystal = 12000000 '12mhz $baud = 9600 '$lib "i2c_TWI.lib" Config Adc = Single , Prescaler = Auto , Reference = Internal 'Avcc Config Portb.2 = Output 'Ein Pin wird aus Ausgang konfiguriert PC0 (also Pin0 von Port C) Config Portb.3 = Output Config Porta.0 = Input Config Porta.2 = Input Config Porta.4 = Input Config Porta.5 = 0 Config Scl = Portc.0 'PINs für I2C Bus Config Sda = Portc.1 Config I2cdelay = 10 'geht auch ohne .lib I2cinit Config Twi = 400000 Dim Eehead(2) As Byte Dim Eebyte(4) As Byte Dim Eesingle As Single At Eebyte Overlay Dim Eeword(2) As Word At Eesingle Overlay Dim Eebanz As Byte Dim Ee_adresse01 As Word At Eehead Overlay Dim Eead As Word Dim I As Word Dim W As Word Dim S As Single Const 24c256w = &B10100000 Const 24c256r = &B10100001 Config Timer1 = Timer , Prescale = 256 'konfiguriere Timer1 Enable Timer1 'schalte Den Timer1 Ein On Timer1 Isr_von_timer1 'verzweige Bei Timer1 überlauf Zu Isr_von_timer1 Config Timer0 = Timer , Prescale = 256 'konfiguriere Timer0 Enable Timer0 'schalte Den Timer1 Ein On Timer0 Isr_von_timer0 Enable Interrupts Load Timer1 , 46875 Load Timer0 , 183 Porta.0 = 1 Porta.2 = 1 Porta.4 = 1 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(byval Ee_daten As Byte , Byval Ee_adresse As Word) Declare Sub Saveword(byval Ee_daten As Word , Byval Ee_adresse As Word) Declare Sub Savesingle(byval Ee_daten As Single , Byval Ee_adresse As Word ) Goto 001 Sub Savebyte(byval 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(byval 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(byval 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: Disable Interrupts Eead = Eead + Eebanz Eebanz = Eebanz + 2 I2csend 24c256w , Eehead(1) , Eebanz Waitms 10 Enable Interrupts 'If Err = 1 Then Call Error(55) Return 'Routine zum lesen von Daten aus dem EEPROM ++++++++++++++++++++++++++++++++++++ Read_ee: Disable Interrupts Eead = Eead + Eebanz I2csend 24c256w , Eehead(1) , 2 Waitms 10 I2creceive 24c256r , Eebyte(1) , 0 , Eebanz Waitms 1 Enable Interrupts 'If Err = 1 Then Call Error(55) Return Isr_von_timer1: 'isr Von Timer1 Load Timer1 , 46875 'Timer1 soll wieder von 34286 wegzählen Toggle Portb.2 'z.B. erhöhe Variable um 1 Return Isr_von_timer0: 'isr Von Timer1 Load Timer0 , 183 'Timer1 soll wieder von 34286 wegzählen If I = 0 Then I = 193 'If Porta.0 = 0 Then Toggle Portb.3 'z.B. erhöhe Variable um 1 End If Return '################### HAUPTPROGRAMM ######################################### 001: Dim Ins As Single Dim Inw As Word Dim Inb As Byte Do Print Portb.2 If Pina.0 = 1 Then Set Portb.3 Else Reset Portb.3 If Pina.0 = 0 Then Print "T1" Input "Single: " , Ins 'For I = 10 To 100 Step 4 Call Savesingle(ins , 10) 'Next I Print "gespeicherter Wert: " ; Ins Ins = Loadsingle(10) Print "geladener Wert: " ; Ins End If If Pina.2 = 0 Then Print "T2" Input "Word: " , Inw Call Saveword(inw , 11) Print "gespeicherter Wert: " ; Inw Inw = Loadword(11) Print "geladener Wert: " ; Inw End If If Pina.4 = 0 Then Print "T3" Input "Byte: " , Inb Call Savebyte(inb , 12) Print "gespeicherter Wert: " ; Inb Inb = Loadbyte(12) Print "geladener Wert: " ; Inb End If Start Adc W = Getadc(5) Print W Stop Adc Ins = Loadsingle(10) Print "geladener Wert: " ; Ins Inw = Loadword(11) Print "geladener Wert: " ; Inw Inb = Loadbyte(12) Print "geladener Wert: " ; Inb Waitms 200 Loop End
Während des LOOP wird immer der EEPROM ausgelesen und ausgegeben.
Außerdem blinkt eine LED im sekundentakt.
eine Frage hätte ich aber noch:
Hab das mit der Adressorganisation noch nicht so intus...
Wenn ich in meinem Progi für single 123456789.0 eingebe steht dann 12345678.0 drinnen... dem um 1 adersse höheren Word-Werte passiert aber nix...
Wie groß sind denn in deinen Schreib-Subs die Variablen?
ich möchte den EEPROM lückenlos mit Word- und Single-Feldern füllen können...
Bis denne... Stefan
Also es ist so:
Bytes -> je 1Byte
Words -> je 2Byte
Singles -> je 4Bytes
Du kannst aus meinem Source die Variable "eead" nehmen, welche die Adresse für díe nächste Variable Automatisch erechnet, egal ob Single, Word oder Byte.
Danke , werde noch ein wenig rumprobieren.
Scheint alles ganz gut zu funktionieren.
bis jetzt kommt sich auch mit den Interrupts nix in die Quere...
Wenn ich noch fragen habe weiß ich ja wo ich hilfe finde )
Also danke nochmal
Lesezeichen