;************************************************************************** ; http://mikrocontroller-blog.de/module/displays/hd44780-1602-lcd-modul-mit-i2c-schnittstelle/ ;************************************************************************** ; ; PCF8574 ; --------- ; |* | ; A0 |1 16| VCC ; A1 |2 15| SDA ; A2 |3 14| SCL ; P0 |4 13| INT ; P1 |5 12| P7 ; P2 |6 11| P6 ; P3 |7 10| P5 ; GND |8 9| P4 ; | | ; --------- ; ; ---------------------------------------- ; PCF8574 : START | 0 | 1 | 0 | 0 | 0 | A2 | A1 | A0 |R/w| ; ---------------------------------------- .set Adresse = 0B0100_0000 ; Address 40 PCF8574 Read ;.set Adresse = 0B0100_1110 ; Address 47 PCF8574 Read ; ; 100 kHz I2C-Bus-Schnittstelle ;************************************************************************* /* Datenbyte 0xAA übertragen __ ______ ______ ______ ______ ___ SDA \____/ \____/ \____/ \____/ \_______________/ Start 7 6 5 4 3 2 1 0 ACK Stop ____ __ __ __ __ __ __ __ __ __ _____ SCL \____/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \__/ \___/ */ ;************************************************************************** I2C_Star_Address: ;-------------------------------------------------------------------------- cbi PortB, SDA ; Start condition rcall Wait_4uS ; ------------------------------ cbi PortB, SCL ; Tackt => Low rcall Wait_4uS ; ------------------------------ push Temp1 ldi Temp1, Adresse ; I2C Adresse PCF8574T rcall I2C_Write ; pop Temp1 ; ------------------------------ ret ;************************************************************************* I2C_Write: ; Temp1 ==> PCF8574 ;-------------------------------------------------------------------------- push Temp1 ; Daten Byte ==> PCF8574 push Temp2 ; Bit-Zähler ldi Temp2, $08 ; schleife für 8 Bit seriell ; ------------------------------ Loop_I2C_Write: ; Temp1 = Datan Byte sbrc Temp1, 7 ; Überspringen, wenn Temp1-Bit7 = Low sbi PortB, SDA ; sonst SDA-Bit ==> High lsl Temp1 ; Verschiebe Temp1 nach links C.7654321_ brcs SDA_Bit_Low ; Verzweigen, wenn Carry gesetzt cbi PortB, SDA ; sonst SDA-Bit ==> Low SDA_Bit_Low: ; ------------------------------ rcall Wait_4uS sbi PortB, SCL ; Tackt => High ; ------------------------------ rcall Wait_4uS cbi PortB, SCL ; Tackt => Low ; ------------------------------ rcall Wait_4uS dec Temp2 brne Loop_I2C_Write ; ------------------------------ pop Temp2 pop Temp1 ; rcall Acknow ; Acknow hier bereits enthalten ; ret ;-------------------------------------------------------------------------- ;Acknow: ; Bestätigen ;-------------------------------------------------------------------------- cbi DDRB, SDA ; SDA => Input sbi PortB, SDA ; SDA => Input High ; ------------------------------ rcall Wait_4uS ; ------------------------------ sbi PortB, SCL ; Tackt => High ; ------------------------------ rcall Wait_4uS ; ------------------------------ sec ; Überprüfe Datenpins auf Low sbis PinB, SDA ; Überspringen, SDA-Bit = High clc ; return flag = ACK OK cbi PortB, SCL ; Tackt => Low ; ------------------------------ rcall Wait_4uS ; ------------------------------ sbi DDRB, SDA ; SDA => Output ret ;************************************************************************** I2c_Stop: ; ;-------------------------------------------------------------------------- cbi PortB, SDA ; Stop Befehl: SDA Bit => Love rcall Wait_4uS ; ------------------------------ sbi PortB, SCL ; Tackt => High rcall Wait_4uS ; ------------------------------ sbi PortB, SDA ; Stop Befehl: SDA Bit => High rcall Wait_4uS ; ------------------------------ ret ;*************************************************************************