OK, nur damit wir uns richtig verstehen:
1. Du willst den System I2C Bus der CC1 für Deine Peripherie mitbenutzen, z. B. einen PCF8574 hinhängen
2. Dafür hast Du ein Assembler-Programm, das die System-Routinen I2C_Start, I2C_Write, I2C_Read_Last usw. aufruft.
Dein Assembler-Programm sieht dann (immer) in etwa so aus:
3. Problem ist die System Routine I2C_Write, die auch noch mal in I2CStart enthalten ist.Code:; EEPROM vom I2C Bus abmelden jsr I2C_ReadLast ; I2C Bus starten und mein device selektieren ldx xxx (z. B. $A1) jsr I2C_Start ; meine Daten zu diesem device senden ldx xxx (z. B. $A3) jsr I2C_Write ; vielleicht nochmal was senden ; mein Device abmelden jsr I2C_Stop ; das EEPROM wieder anmelden xxxx
Das sieht im Original so aus:
4. Diese beiden Routinen musst Du jetzt in Deinen Assembler-Source kopieren und anstelle der beiden Systemroutinen aufrufen.Code:;------------------------------------------------ ; void I2C_Start ( unsigned char devadr ); global _I2C_Start signat _I2C_Start,4216 ;------------------------------------------------ ; Startbedingung nach Init, Write oder Stop moeglich ; Vorbedingung: SCL lo (nach Write) oder ; SCL hi und SDA hi (nach Init und Stop) ; SCL und SDA als Ausgang, SDA nach low ziehen ; = Startbedingung ; warten _I2C_Start BSET SDA,DIR ; SDA hi ausgeben BSET SDA,PORT ; Vorbereiten der Startbed. BSET SCL,PORT ; SCL hi falls lo BCLR SDA,PORT ; SDA lo -> STARTBEDINGUNG BCLR SCL,PORT ; ; nach jeder Startbedingung wird sofort ; das Controlbyte geschrieben, ; also weiter bei I2C_Write ;------------------------------------------------ ; void I2C_Write ( unsigned char byte ); global _I2C_Write signat _I2C_Write,4216 ;------------------------------------------------ _I2C_Write BSET SDA,DIR ; SDA out TXA ; STA writebuf ; merken fuer retry LDX #8 ; init loop putnextbit ROLA BCC lobit ; BSET SDA,PORT ; hi bit BRA writeclock lobit BCLR SDA,PORT ; lo bit writeclock BSET SCL,PORT ; scl hi BCLR SCL,PORT ; scl lo DEX BNE putnextbit ; loop ; ACK-Bit lesen ; Achtung: ACK ist low-aktiv BCLR SDA,DIR ; sda als Eingang BSET SCL,PORT ; scl hi BRSET SDA,PORT,retrywrite; no ACK -> retry BCLR SCL,PORT RTS ; hierher nur bei control byte, ; wenn EEPROM noch nicht bereit retrywrite BCLR SCL,PORT ; LDX writebuf BRA _I2C_Start
5. Dann muss Du Dir den Teil "ACK-Bit lesen..." anschauen: Genau der Befehl
BRSET SDA, PORT, retrywrite
stört Dich: Wenn kein ACK da ist, wird unentwegt dasselbe Byte nochmal geschrieben.
6. Jetzt musst Du Dir überlegen, was in diesem Fall BEI DEINER SCHALTUNG passieren soll.
6.1 Du Kannst Dir zum Beispiel sagen: "Mir ist's egal ob das Byte quittiert wird": dann lässt Du den BRSET einfach weg.
6.2 Oder Du könntest den Befehl über eine Schleife paar (hundert) mal wiederholen, und erst dann aufhören.
6.3 Oder Du könntest das Ergebnis (ACK oder NOACK) an die aufrufende CCBASIC Routine zurückgeben, und die überlegt sich das dann.







Zitieren

Lesezeichen