Salut, quäle mich jetzt schon Tage mit dem I2C rum und komme nicht weiter. Nutze IAR EWARM und ein EvalBoard mit LPC1768 von Steinert. Darauf ist ein 24LC01 verbaut, das ich ansprechen möchte. I2C bekommt über PCONP Saft, Clocks eingestellt, P0.19/P0.20 auf I2C konfiguriert, I2SCLL & I2SCLH auf 250 konfiguriert (bei 50MHz APB Takt). Ich schalte I2EN ein, haue die Startbedingung raus, I2CONSET_SI wird gesetzt, ich lande in der ISR. I2STAT ist 0x08. Alles prima. Sowie ich aber - wie im NXP Besipiel und dem Datenblatt beschrieben - I2CONCLR_SIC setze, um das SI-Bit zu löschen, schaltet sich das I2C ab, d.h. I2EN wird auf 0 gesetzt. Kann sich da jemand einen Reim drauf machen?
Wollte auch zuerst I2C zu Fuss zum Laufen bringen und ging nicht. Habe dann die CMSIS Funktionen genommen (sind bei IAR angepasst dabei) damit ging es sofort. Man könnte mal die Disassembly ansehen, was denn gefehlt hat.
den Link hatte ich gestern schon gefunden. Ist es aber nicht. Ich habe mir BitBanding Aliase d.h. Pointer auf die einzelnen Bits im I2CONCLR Register angelegt, damit ich nur per
1 | *myPointerSIC = 1; |
z.B. das SI Bit löschen kann. Das scheint aber nicht zu klappen. :-( Jetzt poke ich immer einen 8bit wert rein. Bin gerade am umbauen... dauert noch.
So, es geht jetzt. Kann erstmal das 24LC01 byteweise schreiben/lesen. Keine Ahnung, warum Bitbanding bei I2C nicht geht, bei UART, SPI... nehme ich es auch und da tut es.
So, für die Nachwelt: die im UM10360 beschriebene State-Machine (Kap.19.10) ist m.E. nach unvollständig. Kap. 19.10.5.3 (state 0x08): write 0x28 to I2CONCLR to clear SI Flag and STA flag Kap. 19.10.5.4 (state 0x10): write 0x28 to I2CONCLR to clear SI Flag and STA flag Es fehlt wohl das Auslösen der Repeated Start Bedingung. Am Beispiel 24LC01 (Lesen eines Bytes): S $A0 A $[adresse] A S $A1 A $[data] N P S = Start Bedingung P = Stop Bedingung A = Ack vom EEPROM N = kein Ack vom µC $[adresse] = Leseadresse im EEPROM Speicherbereich $[data] = das vom EEPROM gelesene Byte Die zweite Startbedingung (S vor $A1) muss man in State 0x28 selbst generieren: Kap. 19.10.6.3 (state 0x28):
1 | CASE 0x28: |
2 | IF bytes-to-send == last-byte THEN |
3 | IF byte-to-receive > 0 THEN |
4 | write 0x24 to I2CONSET // set AA and STA |
5 | ELSE |
6 | write 0x14 to I2CONSET // set AA and STO |
7 | ENDIF |
8 | ELSE |
9 | write data byte to I2DAT |
10 | write 0x04 to I2CONSET // set AA |
11 | ENDIF |
12 | write 0x08 to I2CONCLR // clear SI |
13 | BREAK |
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.