-         
+ Antworten
Ergebnis 1 bis 4 von 4

Thema: I²C ICs abfragen zwecks GETACK

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    10.02.2004
    Beiträge
    29

    I²C ICs abfragen zwecks GETACK

    Olla!

    Kurze Frage: Es gibt doch das Problem, dass wenn ein I²C-IC angesprochen werden soll, der aber nicht im Netz hängt, das System beim GETACK stehenbleibt, weil es in eine Endlosschlaufe geht.

    Jetzt habe ich irgendwo gelesen, wie man das per ASM umgehen kann, bzw. wie der GETACK Befehl auszusehen hat um nach einer bestimmten Zeit aus der Schlaufe zu springen. Kanns mir denn jemand hier kurz skizzieren oder einen anderen Tipp geben, wie ich erkenne, ob der entsprechende IC im Netz ist bzw. Strom hat ??

    Super, danke

    MedanoCC

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    07.01.2004
    Ort
    München
    Alter
    66
    Beiträge
    214
    Das Problem tritt auf, wenn Du den System I2C Bus der CC1 benutzt, und dafür die System I2C-Routinen verwendest (I2C_START usw, liegen bei Adressen $08xx).

    Wenn Du es vermeiden willst, musst Du eine eigene Routine "WRITE" zum Schreiben verwenden: die muss dasselbe macht wie das Original, aber bei fehlendem ACK nicht wiederholen. Dazu musst Du allerdings auch die I2C_START kopieren. Insgesamt dürften das dann mindestens 30 Bytes Code sein -- ganz schön viel.
    Details dazu findest Du im Source-Listing der CC1 Routinen.

    Wenn Du nur ein mal am Anfang prüfen musst, ob der I2C Baustein überhaupt da ist, könntest Du das ganze am Anfang des BASIC Programms einmalig als SYS Routine laufen lassen, und im laufenden Betrieb dann die System-Routinen verwenden, um Platz zu sparen.

    Eine andere Methode kenne ich nicht.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    10.02.2004
    Beiträge
    29
    Hi!

    Danke für Deine Antwort. Die Frage ist jedoch noch für mich, wie dann die Routine aussehen muss, da ich ja eine Schlaufe machen muss, die dann jedoch nicht unendlich sondern kontrolliert, d.h. nach einer bestimmten Zeit abbrechen muss. Wie sieht das denn dann aus ? Kann auch ein Basic-Script sein.

    Könntest Du das vorgehen kurz skizieren ?


    Danke - MedanoCC

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    07.01.2004
    Ort
    München
    Alter
    66
    Beiträge
    214
    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:
    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
    3. Problem ist die System Routine I2C_Write, die auch noch mal in I2CStart enthalten ist.
    Das sieht im Original so aus:
    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
    4. Diese beiden Routinen musst Du jetzt in Deinen Assembler-Source kopieren und anstelle der beiden Systemroutinen aufrufen.

    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.

+ Antworten

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •