Hallo, versuche mit Bascom ein LTC 2945 von Linear Technologys zu lesen. Um einfach zu beginnen lese ich zunächst das Config Register aus. Dort soll per Default H05 drinnstehen. Ich bekomme als Ausgabe aber immer eine "0". Hardware habe ich mehrfach geprüft, ich bin mir sicher hier keinen Fehler zu haben. Fällt Euch was auf; sehr Ihr einen Fehler ? Habt Ihr einen funktionierenden Beispielcode ? Err liefert übrigens immer 0 $regfile = "m128def.dat" $crystal = 16000000 $hwstack = 40 $swstack = 16 $framesize = 32 $baud = 9600 Config Lcd = 20 * 2 Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2 Config Sda = Porta.6 Config Scl = Porta.7 Const Basewrite = &HCE Const Baseread = &HCF Dim Vin_msb As Byte , Vin_lsb As Byte , Var3 As Byte , Var4 As Byte , Etwas As Byte Cursor On Wait 1 Cls Lcd "Test" Waitms 500 Cls '######################################################### Do I2cstart Locate 2 , 1 If Err = 0 Then Lcd "ERR = 0" If Err = 1 Then Lcd "ERR = 1" Waitms 1000 I2cwbyte Basewrite Locate 2 , 1 If Err = 0 Then Lcd "ERR = 0" If Err = 1 Then Lcd "ERR = 1" Waitms 1000 I2cwbyte &H00 Locate 2 , 1 If Err = 0 Then Lcd "ERR = 0" If Err = 1 Then Lcd "ERR = 1" Waitms 10 I2cstart Waitms 1000 I2cwbyte Baseread Locate 2 , 1 If Err = 0 Then Lcd "ERR = 0" If Err = 1 Then Lcd "ERR = 1" Waitms 1000 I2crbyte Etwas , Nack Locate 2 , 1 If Err = 0 Then Lcd "ERR = 0" If Err = 1 Then Lcd "ERR = 1" Waitms 1000 I2cstop Locate 2 , 1 If Err = 0 Then Lcd "ERR = 0" If Err = 1 Then Lcd "ERR = 1" Waitms 1000 Locate 1 , 1 Lcd "tmp = " ; Etwas Waitms 2000 Cls Waitms 2000 Loop End
also zwischen den I2C-Kommandos waitms 1000 ist nicht so ideal i2cstart waitms 1000 I2cwbyte Basewrite waitms 1000 I2cwbyte &H00 etc. ... das würde mich wundern, wenn der Busteilnehmer da kein Timeout macht.
@weinbauer, der I2C Bus macht soetwas per Design mit. Das ist nicht das Problem. Hab's auch gerade noch ausprobiert... Danke für die 1. Hilfe.
Pullups dran ? Das ist 'ne Soft-I2C, ohne ext. Pullups funktioniert die nicht. Mit Config I2CDelay auch mal den Takt runter setzen.
ja, 2,7 k Pullups. I2CDelay probiert, bringt nix ;-((((( ich verzweifle langsam.
@MWS adr1=H adr0=L gibt die basedresse CE. Das ist also richtig. habe ich die Sequenzen zum Lesen des Controllregisters (Adresse 00H) so richtig gemacht?
Zum nachlesen... Das Datenblatt. Seite 15, 16 und 20 sind woh die entscheidenden Seiten;-). Hab ich schon 20 mal durchgelesn...
Linear schrieb: > habe ich die Sequenzen zum Lesen des Controllregisters (Adresse 00H) > so richtig gemacht? Sieht ok aus. Würd' mal versuchsweise die HW-I2C nehmen, nicht vergessen die I2C_TWI.lib einzubinden.
Ok, schaffe ich heute nicht mehr... Vielleicht morgen. Ich melde mich zurück. Danke.
Zeig mal paar Bilder mit Signalpegeln. Und wenn Du keinen hast, dann kauf Dir einen.
was auch so n Ding ist bei der Soft-TWI von Bascom, der I2C-Start wird als Restart ausgeführt, das hat mir auch mal n paar graue Haare beschert.
Hallo Weinbauer, wie hast Du das Restart Problem denn gelöst? Was ist der unterschied zwischen Start und Restart?
Linear schrieb: > Was ist der unterschied zwischen Start und Restart? Ist recht einfach nachzulesen. Versuch's mal so, auch mit Soft-I2C:
1 | I2cstart |
2 | I2cwbyte Basewrite |
3 | I2cwbyte &H00 |
4 | I2cstop |
5 | I2cstart |
6 | I2cwbyte Baseread |
7 | I2crbyte Etwas , Nack |
8 | I2cstop |
Solange Du keine anderen Devices am I2C-Bus hast, gibt das nicht das Problem, dass sich ein anderer Teilnehmer den Bus nach dem ersten Stop klauen kann. Lass auch die Printausgaben weg, selbst wenn Du denkst, dass I2C dafür spezifiziert ist. Wenn Du Err auswerten willst, mach's nachher, speichere Dir Err dafür jeweils in mehrere Variablen. Und sag' auch mal, was Du für eine Bascom-Version hast, ist die aktuell ?
Hallo MWS, da hast Du wohl recht. Wenn ich code zwischen die Zeilen schreibe gehts durcheinander. Habe jetz mal Hardware TWI gemacht. Bei I2cwbyte Baseread hängt er sich auf und ERR geht auf 1. Im Datenblatt zu dem Chip verzichtet man auf die markierte Zeile: I2cstart I2cwbyte Basewrite I2cwbyte &H00 ***I2cstop***** I2cstart I2cwbyte Baseread I2crbyte Etwas , Nack I2cstop die machen einfach einen 2. I2Cstart... Ich tappe weiter im Dunkeln... $regfile = "m128def.dat" $crystal = 16000000 $hwstack = 40 $swstack = 16 $framesize = 32 $baud = 9600 $lib "i2c_twi.lbx" Config Lcd = 20 * 2 Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2 Config Sda = Portd.1 Config Scl = Portd.0 Const Basewrite = &HCE Const Baseread = &HCF 'Config Twi = 400000 ' wanted clock frequency here 100 kHz Dim Vin_msb As Byte , Vin_lsb As Byte , Var3 As Byte , Var4 As Byte , Etwas As Byte Dim I As Byte 'Enable Interrupts 'Enable Interrupts I2cinit Config Twi = 100000 Twbr = 12 'bit rate register Twsr = 0 Cursor On Lcd "start " '######################################################### Do I2cstart Lcd "i2cstart " 'Waitms 100 'Locate 2 , 1 'If Err = 0 Then Lcd "ERR = 0 Start" 'If Err = 1 Then Lcd "ERR = 1 Start" 'Waitms 100 I2cwbyte Basewrite Lcd "basewrite " 'Locate 2 , 1 'If Err = 0 Then Lcd "ERR = base0" 'If Err = 1 Then Lcd "ERR = base1" 'Waitms 100 I2cwbyte &H00 Lcd "I2cwbyte &H00 " 'Locate 2 , 1 'If Err = 0 Then Lcd "ERR = 0" 'If Err = 1 Then Lcd "ERR = 1" 'Waitms 100 'I2cstop I2cstart 'I2crepstart 'Waitms 100 Lcd "i2cstart #2 " I2cwbyte Baseread 'Lcd "Baseread " 'Locate 2 , 1 'If Err = 0 Then Lcd "ERR = 0" 'If Err = 1 Then Lcd "ERR = 1" 'Waitms 100 'For I = 1 To 31 'Locate 2 , 1 'I2crbyte Etwas , Ack 'Lcd "tmp = " ; Etwas 'lcd " i= " ; I 'Waitms 250 'Cls 'Next I Lcd "Error?" ; Err 'I2crbyte Etwas , Ack I2crbyte Etwas , Nack 'Lcd "I2crbyte Etwas , Nack " Waitms 50 'Locate 2 , 1 'If Err = 0 Then Lcd "ERR = 0" 'If Err = 1 Then Lcd "ERR = 1" 'Waitms 100 Cls I2cstop Waitms 50 'Locate 2 , 1 'If Err = 0 Then Lcd "ERR = 0" ' 'If Err = 1 Then Lcd "ERR = 1" 'Waitms 100 Locate 2 , 1 Cls Lcd "tmp = " ; Etwas Waitms 2000 Waitms 2000 Loop End
Warum konfigurierst Du den Bus erst auf 100kHz und setzt ihn dann durch Beschreiben von TWBR wieder auf 400kHz ? Du hast die Bascom-Version nicht genannt, ist's 'ne ältere ? Wenn ja, mach' ein Update. Ich würd' jegliche Verzögerung oder zuviel Code zwischen den I2C-Befehlen erst mal vermeiden, aber mir Err merken, also:
1 | I2cstart |
2 | E1 = Err |
3 | I2cwbyte Basewrite |
4 | E2 = Err |
5 | I2cwbyte &H00 |
6 | E3 = Err |
7 | ' usw. |
und dann eben nach Beendigung der I2C-Routinen ausgeben. Sollte kein Fehler auftreten, dann würd' ich versuchen, mehrere Bytes zu lesen, bis ich 'nen Fehler bekomme. Glaub' ich hab' was von auto-increment der Register gelesen, vielleicht kommt man damit weiter. Ansonsten, zur weiteren Fehlersuche wär' jetzt ein LA praktisch, ein Schaltplan wär' auch nicht verkehrt, vielleicht sehen Andere, was Du übersiehst.
Und noch'n Hinweis: der ATM128 besitzt eine Compatibility-Fuse auf ATM103. Hast Du die gesetzt, wäre das recht unpraktisch, denn der ATM103 verfügt über keine I2C-Unit.
Hallo MWS, ich nutze die aktuelle 2075.002 Bascom Version. Die compatibility Fuse ist nicht gesetzt (super Hinweis dennoch!). Ich wollte den Bus runtertakten auf 100 khz um das alles etwas defensiver zu konfigurieren, Durcheinander kommt vom vielen Probieren.. Habe jetzt alles wieder auf soft i2c umgebaut. Es läuft durch, aber es wird immer nur eine 0 ausgelesen. Im Konfig Register sollte 05H drinstehen. Ich probiere es weiter, tausche mal den I2C und auch meinen Atmega. Danke für die guten Tipps !! Super!!
Hallo, getestet, bei keinem Befehl erscheint ein Error. Status immer 0! Nur der empfangene Wert ist falsch.... Code: $regfile = "m128def.dat" $crystal = 16000000 $hwstack = 40 $swstack = 16 $framesize = 32 $baud = 9600 '$lib "i2c_twi.lbx" Config Lcd = 20 * 2 Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.3 , Rs = Portc.2 Config Sda = Portd.1 Config Scl = Portd.0 Const Basewrite = &HCE Const Baseread = &HCF Dim Vin_msb As Byte , Vin_lsb As Byte , Var3 As Byte , Var4 As Byte , Etwas As Byte Dim I As Byte , Err1 As Byte , Err2 As Byte , Err3 As Byte , Err4 As Byte , Err5 As Byte , Err6 As Byte , Err7 As Byte Dim Mehr As Word Cursor On Cls Lcd "start " Waitms 2000 '######################################################### Do I2cstart Err1 = Err I2cwbyte Basewrite Err2 = Err I2cwbyte &H00 Err3 = Err I2cstart Err4 = Err I2cwbyte Baseread Err5 = Err I2crbyte Etwas , Nack Err6 = Err I2cstop Err7 = Err Locate 1 , 1 Lcd Err1 ; Err2 ; Err3 ; Err4 ; Err5 ; Err6 ; Err7 Locate 2 , 2 Lcd "tmp = " ; Etwas Waitms 2000 Cls Loop End
Linear schrieb: > getestet, bei keinem Befehl erscheint ein Error. > Status immer 0! Bei der Bascom HW-I2C dürften Fehler besser gemeldet werden, Fehlerbehandlung der Soft-I2C ist etwas rudimentärer. Linear schrieb: > schaltbild IntVcc mit Vdd werden sicher nicht mit einem Spannungsbereich versorgt, mit genau welcher Spannung gehst Du da rein ? Das gehört in der Zeichnung an VCC der Pullups/des µC verbunden, wie ist's denn in Realität ? Hier: http://www.karosium.com/2011/09/equalizing-battery-bank-charger-v2.html (ganz zum Schluss) ist Code, der den LTC4151 anspricht. Hat zwar 'nen anderen Registeraufbau, jedoch als Beispiel ist's verwendbar um sagen zu können, dass diese Linear-Bausteine wohl keine Extrawürste benötigen, auch werden in beiden Datenblättern die I2C-Sequenzen identisch dargestellt.
MWS schrieb: > Linear schrieb: >> getestet, bei keinem Befehl erscheint ein Error. >> Status immer 0! > > Bei der Bascom HW-I2C dürften Fehler besser gemeldet werden, > Fehlerbehandlung der Soft-I2C ist etwas rudimentärer. > > Linear schrieb: >> schaltbild > > IntVcc mit Vdd werden sicher nicht mit einem Spannungsbereich versorgt, > mit genau welcher Spannung gehst Du da rein ? 5 Volt aus nem 7805 Das ist genau das Schaltbild aus der Application note/Datenblatt. So ist es auch aufgebaut. Das gehört in der > Zeichnung an VCC der Pullups/des µC verbunden, wie ist's denn in > Realität ? Der Atmega wird mit der gleichen Spannung wie der LTC verbunden. Die Pullups gehen an diese Vcc. > > Hier: > http://www.karosium.com/2011/09/equalizing-battery... > (ganz zum Schluss) ist Code, der den LTC4151 anspricht. Hat zwar 'nen > anderen Registeraufbau, jedoch als Beispiel ist's verwendbar um sagen zu > können, dass diese Linear-Bausteine wohl keine Extrawürste benötigen, > auch werden in beiden Datenblättern die I2C-Sequenzen identisch > dargestellt. Schau ich mir an. Kurios ist aber das laut Datenblatt nach dem command ( identisch mit Registeradresse) kein i2cstop erfolgt, sonder direkt ein neuer I2cstart..... Danke!
Linear schrieb: > Kurios ist aber das laut Datenblatt nach dem command ( identisch mit > Registeradresse) kein i2cstop erfolgt, sonder direkt ein neuer > I2cstart..... Was soll da kurios sein ? Das ist ein Restart ohne den Bus freizugeben. Ein Stop würde "Bus frei" signalisieren, dann könnte ein anderer Teilnehmer dazwischen funken. Ich hatt's oben zum Testen vorgeschlagen, weil bei Deiner Konfiguration ein Dazwischenfunken nicht passieren kann.
Na sagen wir mal ungewöhnlich. Meist erfolgt vorher immer eine Busfreigabe. Aber egal wie ich es mache funktionierts nicht. Ich tausche jetzt einmal Hardware...
Linear schrieb: > Meist erfolgt vorher immer eine Busfreigabe. "Meist" und "Immer" ? :D Da bist Du falsch informiert, nach Adressieren des Bausteins und des anzusprechenden Registers wird nix freigegeben. Wie bereits geschrieben könnte dann ein anderer Baustein den Bus belegen und beliebige Daten senden, während der ursprüngliche Baustein auf Befehle wartet. Das ergäbe ein Kuddelmuddel. Lesen eines einzelnen Bytes aus einem 24AA256, serielles EEProm:
1 | I2cstart |
2 | I2cwbyte Ser_EEProm_Wr |
3 | I2cwbyte SEA_H |
4 | I2cwbyte SEA_L |
5 | I2cstart |
6 | I2cwbyte Ser_EEProm_Rd |
7 | I2crbyte EEP_Byte , Nack |
8 | I2cstop |
@MWS Moin, ich hatte mich streng an den Protokollablauf laut Datenblatt orientiert. Dort wird es auch so gemacht wie Du im letzten Post beschreibst, also alles ok so. Jetzt die gute Nachricht: Ich habe den Fehler endlich gefunden. Wie fast immer saß das Problem "hinterm Lötkolben, oder vor der Tastatur". LTC hatte mir ein Sample mit der Bezeichnung LTC2945-1 und LTC2945 gesendet. den -1 hatte ich verbaut (Beschriftung nur mit dicker Lupe zu lesen) und der hat sein SDA standardmäßig invertiert. Das habe ich auf dem Oszilloskop dann heute morgen um 4:00 gesehen und fast zeitgleich beim Überprüfen dann auch am Aufdruck erkannt. Ich habe flugs einen Inverter Gatter dazwischen geschaltet und es funktionierte sofort. Sowohl mit soft I2C als auch mit TWI. Auch wenn ich den Bus mit I2CSTOP kurz freigebe und weiter lese gibt es keinerlei Probleme. Anbei nochmal ein Bild vom gesamten Versuchsaufbau. Jetzt gehts endlich weiter mit dem eigentlichen Thema U/I/P -Meter für mein uralt Netzteil;-) Ich danke allen nochmal für dir intensive Hilfe, insbesondere MWS. Hoffe ich kann mich mal revangieren. Danke und schönen Wochenstart ! DS
Linear schrieb: > Wie fast immer saß das Problem "hinterm Lötkolben, oder vor der > Tastatur". Der Klassiker :D Schön, dass es jetzt läuft. Danke, wünsch' ich auch.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.