Hallo Stefan,
ich weiß zwar nicht, ob Du hier noch mitliest, aber egal.

Ich habe mich heute mit USI Master auseinandergesetzt und, es ist doch nicht ganz so wild, ich glaube die nackte Routine ergibt etwa 160 Bytes.

Testumgebung :

Tiny 25 als Master.
Mein I2C Display als Slave Nr.1 zur Ausgabe
DS1621 I2C Temperatursensor als Slave Nr.2
Eine Real Time Clock als Slave Nr.3

Der Aufbau läuft seit einer Stunde und zeigt mir schön in Sekundentakt die Temeratur und Uhrzeit abweschseln an \/

Der Master läuft mit 1MHz und 100 kHz Bustakt

ich poste einfach mal das Program:
Code:
;			USI_TWI_master Routinen
;**************************************************


.macro TRANSFER_8_BIT
	ldi param1,(1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)
	rcall USI_TWI_master_transfer
.endmacro

.macro TRANSFER_1_BIT
	ldi param1,(1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0xE<<USICNT0)
	rcall USI_TWI_master_transfer
.endmacro

.equ WRITE = 0
.equ READ = 1
.equ ACK = 1
.equ NACK = 0


; I2C Master init 
;keine Parameter, keine Rueckgabewerte
;************************************************************************
USI_TWI_master_init:
	ldi tmp1,(1<<PORT_USI_SDA)|(1<<PORT_USI_SCL);Pullups an SDA u. SCL an
	out PORT_USI,tmp1
	out DDR_USI,tmp1;SDA u. SCL als Ausgaenge
	ser tmp1 ;Lade Dataregister mit High Bytes
	out USIDR,tmp1
	;USI Interrupts inaktiv, USI im 2 Wire Modus Software Clock
	ldi tmp1,(1<<USIWM1)|(1<<USICS1)|(1<<USICLK)
	out USICR,tmp1
	ldi tmp1,(1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC);Lösche USI Flags
	out USISR,tmp1	;und resete den Counter
	ret
;************************************************************************


;			USI_TWI_master_start
;   Sendet Startbedingung und die Slaveadresse
;	Parameter, Slaveadresse im Register param1
;	Rueckgabe 1 beim Erfolg 0 beim Fehler ueber Register param1
;************************************************************************
USI_TWI_master_start:
	sbi PORT_USI,PIN_USI_SCL;zieht SCL High
USI_TWI_master_start_1:
	sbis PIN_USI,PIN_USI_SCL;warte bis SCL High ist
	rjmp USI_TWI_master_start_1
	rcall delay
	cbi PORT_USI,PIN_USI_SDA ; zieht SDA LOW
	rcall delay
	cbi PORT_USI,PIN_USI_SCL ;SCL wieder LOW 
	sbi PORT_USI,PIN_USI_SDA ;SDA High
	out USIDR,param1; Slaveadresse/Data in den USI Dataregister schreiben
	;mastertransfer aufrufen 
	TRANSFER_8_BIT
	cbi DDR_USI,PIN_USI_SDA	;SDA auf Eingang
	TRANSFER_1_BIT 
	ret
;***********************************************************************


;	USI_TWI_master_write
;	Sendet ein Byte am den Master
;	Parameter: Data im Register param1
;	Rueckgabe 1 beim Erfolg 0 beim Fehler ueber Register param1
;***********************************************************************
USI_TWI_master_write:
	out USIDR,param1; Data in den USI Dataregister schreiben
	;mastertransfer aufrufen für die
	TRANSFER_8_BIT ;Byte Uebergabe
	cbi DDR_USI,PIN_USI_SDA	;SDA auf Eingang
	TRANSFER_1_BIT;um ACK/Nack Abzuholen 
	ret
;***********************************************************************

;	USI_TWI_master_read
;	Liest ein Byte vom Slave aus
;	Parameter: Sende ACK/Nack im param1 1 == ACK senden; 0 == kein ACK senden(Nack)
;	Rueckgabe gelesene Daten in param1
USI_TWI_master_read:
	tst param1 ;Schaue ob zum Schluss NACK oder ACK soll
	breq USI_TWI_master_read_prepare_NACK
	set ;T Flag setzen
	rjmp USI_TWI_master_read_1
USI_TWI_master_read_prepare_NACK:
	clt ;T Flag loeschen
USI_TWI_master_read_1:
	cbi DDR_USI,PIN_USI_SDA ;SDA auf Eingang setzen
	TRANSFER_8_BIT
	push param1 ;gelesene Daten sichern
	brtc USI_TWI_master_read_send_NACK ;wenn T Flag geloescht ist erfolgt ein NACK
	;sonst muss ein ACK erfolgen
	clr param1
	rjmp USI_TWI_master_read_end
USI_TWI_master_read_send_NACK:
	ser param1
USI_TWI_master_read_end:
	out USIDR,param1
	TRANSFER_1_BIT
	pop param1
	ret
;***********************************************************************
	

;			USI_TWI_master_transfer
; sorgt für die Komunikation mit dem slave
;mit param1 wird übergeben ob ein Byte empfange/gesendet wird, oder nur 1 Bit für ACK/NACK
 
USI_TWI_master_transfer:
	out USISR,param1;der Counter wird vorgeladen
USI_TWI_master_transfer_1:
	rcall delay
	sbi USICR,USITC ;Positive Flanke an SCL erzeugen 
USI_TWI_master_transfer_2:	
	sbis PIN_USI,PIN_USI_SCL	; warten bis SCL High ist
	rjmp USI_TWI_master_transfer_2
	rcall delay
	sbi USICR,USITC;negative Flanke an SCL erzeugen
	sbis USISR,USIOIF;testen ob Counter ubergelaufen ist
	rjmp USI_TWI_master_transfer_1	;wenn nicht mit dem nächstem Bit 
	rcall delay		;wenn gelesen wird
	in param1,USIDR;Daten holen 
	ldi tmp1,0xFF
	out USIDR,tmp1
	sbi DDR_USI,PIN_USI_SDA; SDA auf Ausgang stellen
	ret
;***********************************************************************


;			USI_TWI_master_stop:
;Sendet die Stop Bedingung
;***********************************************************************
USI_TWI_master_stop:
	cbi PORT_USI,PIN_USI_SDA
	sbi PORT_USI,PIN_USI_SCL
USI_TWI_master_stop_1:
	sbis PIN_USI,PIN_USI_SCL
	rjmp USI_TWI_master_stop_1
	rcall delay
	sbi PORT_USI,PIN_USI_SDA
	rcall delay
	ret
;***********************************************************************

; 			delay
;Eine kurze Pause von insgesammt 10 Takten
;Bei 1 MHz ergibt das 100 kHz Mastertakt
;;keine Parameter, keine Rueckgabewerte
;***********************************************************************
delay:
	;Rcall hat 3 Takte gedauert
	nop	;1 Takt
	nop ;1 Takt
	nop ;1 Takt
	ret ; 4 Takte
;***********************************************************************
Du mußt Dir 2 Register definieren tmp1, und param1, die nicht gesichert werden.

Ich habe es anhand der o.g. appnote geschrieben, aber so ziemlich umgekrämpelt, weil es mir nicht so gefallen hat.
Die ist etwa genauso zu benutzen, wie die Routine von Peter Fleury, da komm ich besser mit klar, als diese komische Pufferlösung von Atmel.
Ein Miniprogramm um den DS1621 Wandeln zu lassen und auszulesen könnte damit etwa so aussehen:
Code:
.include "tn25def.inc"

.equ PORT_USI = PORTB
.equ DDR_USI = DDRB
.equ PIN_USI = PINB
.equ PORT_USI_SDA = PORTB0
.equ PORT_USI_SCL = PORTB2
.equ PIN_USI_SDA = PINB0
.equ PIN_USI_SCL = PINB2

.equ I2C_DISPLAY = 0x14
.equ THERMO = 0x90
.def nachkomma = r1
.def tmp1 = r16
.def tmp2 = r17
.def param1 = r18
.def param2 = r19
.def temperatur = r21
 
.cseg

.org 0x0000 
	rjmp reset

reset:
	clr ausgabe
	ldi tmp1,RAMEND
	out SPL,tmp1
	rcall USI_TWI_master_init
	;Thermometer einschalten
	ldi param1,THERMO+WRITE
	rcall USI_TWI_master_start
	ldi param1,0xEE
	rcall USI_TWI_master_write
	rcall USI_TWI_master_stop
	;Thermometer eingeschaltet

loop:
        ;Temperatur auslesen
	ldi param1,THERMO+WRITE
	rcall USI_TWI_master_start
	ldi param1,0xAA
	rcall USI_TWI_master_write
	ldi param1,THERMO+READ
	rcall USI_TWI_master_start
	ldi param1,ACK
	rcall USI_TWI_master_read
	mov temperatur,param1
	ldi param1,NACK
	rcall USI_TWI_master_read
	mov nachkomma,param1
	rcall USI_TWI_master_stop
	;Temperatur ausgelesen
loop1:
        loop1
Noch etwas unaufgeräumt, ich denke bis zum Wochenende werde ich Zeit finden und alles besser dokumentieren.

Ich hoffe, das Du was mit tun kannst

Gruß Sebastian