I2C_Wait: ; ============================= ; Warteschleifen-Generator ; 4000 Zyklen: ; ----------------------------- ; warte 3999 Zyklen: ldi R29, $1F WGLOOP0: ldi R30, $2A WGLOOP1: dec R30 brne WGLOOP1 dec R29 brne WGLOOP0 ; ----------------------------- ; warte 1 Zyklus: nop ; ============================= ret I2C_Start: sbi PortB,SDA rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait cbi PortB,SDA rcall I2C_Wait ret I2C_Stop: cbi PortB,SCL rcall I2C_Wait cbi PortB,SDA rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait sbi PortB,SDA rcall I2C_Wait ret I2C_Read_Ack: cbi PortB,SCL ; zuerst (!) SCL auf LOW ... rcall I2C_Wait cbi DDRB,SDA ; ... und erst dann SDA als Eingang rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL ; SCL auf LOW rcall I2C_Wait sbi DDRB,SDA ; SDA wieder als Ausgang ret I2C_Send_Ack: cbi PortB,SCL rcall I2C_Wait cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL ret I2C_Send_no_Ack: cbi PortB,SCL rcall I2C_Wait sbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL ret I2C_Send: ldi temp1,7 I2C_Send_weiter: cbi PortB,SCL rcall I2C_Wait rol data sbi PortB,SDA brcs I2C_Send_Carry_weiter cbi PortB,SDA I2C_Send_Carry_weiter: sbi PortB,SCL rcall I2C_Wait cpi temp1,0 breq I2C_Send_Ende dec temp1 rjmp I2C_Send_weiter I2C_Send_Ende: ret I2C_Bit_lesen: clc ; Carry löschen sbic PinB,SDA sec ; sonst Carry setzen rol data ret I2C_Read: cbi PortB,SCL ; zuerst (!) SCL auf LOW ... rcall I2C_Wait cbi DDRB,SDA ; ... und erst dann SDA als Eingang rcall I2C_Wait ldi data,0 ldi temp1,7 I2C_Read_weiter: sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait cpi temp1,0 breq I2C_Read_Ende dec temp1 rjmp I2C_Read_weiter I2C_Read_Ende: sbi DDRB,SDA sbi PortB,SDA ret