Hi @all.

Ich habe eine Frage wegen einer I2C-Routine in Assembler für USIP. Leider wenn ich die SPA und SCl im Avr-Studio Teste springt der Interrupt nicht an.

Was habe ich falsch gemacht? oder liegt das am Avr-Studio?

Nochetwas: Irgendwie springt der (nachdem man das Interrupt manuell eingesetzt hat, und Daten gesendet hat, nie zurück. Was ist dort falsch?

Hier mal der Source:
Code:
; This program emulates an I2C bus expander PCF8574 on address 0x40.
; Fuses:
; RSTDISBL programmed (0) - External Reset disabled
; BODEN unprogrammed (1) - Brown out detector disabled
; PLLCK unprogrammed (1) - PLL disabled
; CKOPT unprogrammed (1) - internal capacitors for an Xtal oscillator disabled
; SUT=10 - long start-op time 65ms
; CKSEL=0100 - Internal RC Oscillator 8MHz

.include "tn26def.inc"

; port A - parallel data

; port B
.equ	SDA		=0
.equ	PAR_STROBE	=1	;control
.equ	SCL		=2
.equ	PAR_ERROR	=3	;status
.equ	PAR_INIT	=4	;control
.equ	PAR_BUSY	=5	;status
.equ	PAR_ACK		=6	;status

.def	Flags		=r16
; meaning of individual bits
.equ	START_DETECTED	=7	;set by the USI Start handler when the start
				;condition detected

.def	Temp1		=r17	;local temporary variable
.def	DeviceAddress	=r18

.org	0x0000

		rjmp	reset		;Reset handler
		reti			;IRQ0 handler
		reti			;Pin change handler
		reti			;Timer1 compare match 1A
		reti			;Timer1 compare match 1B
		reti			;Timer1 overflow handler
		reti			;Timer0 overflow handler
		rjmp	usi_strt	;USI Start handler
		reti			;USI Overflow handler
		reti			;EEPROM Ready handler
		reti			;Analog Comparator handler
		reti			;ADC Conversion Handler

reset:		ldi	Temp1,RAMEND
		out	SP,Temp1

		ldi	Temp1,0x00
		out	PORTA,Temp1
		out	DDRA,Temp1
		out	PORTB,Temp1
		out	DDRB,Temp1

; USI settings:
; Start Condition Interrupt Enable
; Counter Overflow Interrupt Enable
; Two-wire mode
; Shift Register Clock Source - External, positive edge
; 4-bit Counter Clock Source - External, both edges
		ldi	Temp1,(1<<USISIE)+(0<<USIOIE)+(1<<USIWM1)+(0<<USIWM0)+(1<<USICS1)+(0<<USICS0)+(0<<USICLK)
		out	USICR,Temp1
		sei

main_loop:	cbi	DDRB,SDA
		cbr	Flags,(1<<START_DETECTED)
		ldi	Temp1,(1<<USIPF)
		out	USISR,Temp1
; wait for the start condition
main_1:		sbrs	Flags,START_DETECTED
		rjmp	main_1
; start condition detected
start_cond:	cbr	Flags,(1<<START_DETECTED)
		ldi	Temp1,(1<<USIOIF)+0x0F	;1 SCL edge
		out	USISR,Temp1
; skip the first falling SCL edge after the start condition
main_2:	;	sbic	USISR,USIPF	;stop condition detected?
	;	rjmp	main_loop
		sbrc	Flags,START_DETECTED ;start condition detected?
		rjmp	start_cond
		sbis	USISR,USIOIF
		rjmp	main_2
		ldi	Temp1,(1<<USIOIF)+0x00	;10 SCL edges
		out	USISR,Temp1
; wait until the master sends the Device Address
main_3:	;	sbic	USISR,USIPF	;stop condition detected?
	;	rjmp	main_loop
		sbrc	Flags,START_DETECTED ;start condition detected?
		rjmp	start_cond
		sbis	USISR,USIOIF
		rjmp	main_3
		in	DeviceAddress,USIDR
		mov	Temp1,DeviceAddress
		andi	Temp1,0xFE	;ignore the R/W bit
		cpi	Temp1,0x40	;PCF8574 device address
		brne	main_loop
; valid Device Address received from the master,
; read or write?
		sbrc	DeviceAddress,0	;R/W bit
		rjmp	read

; prepare the ATtiny26 to send the ACK bit to the master
write_loop:	ldi	Temp1,(1<<USIOIF)+0x0E	;2 SCL edges
		out	USISR,Temp1
		cbi	PORTB,SDA
		sbi	DDRB,SDA
; wait until the master reads the ACK bit
write_1:	sbis	USISR,USIOIF
		rjmp	write_1
		cbi	DDRB,SDA
; the master sends data to the ATtiny26
		ldi	Temp1,(1<<USIOIF)+0x00	;16 SCL edges
		out	USISR,Temp1
		ldi	Temp1,0		;ACK=0
		out	USIDR,Temp1	;bit 0 will be send as ACK
; wait until the master sends the Data Byte
write_2: ;	sbic	USISR,USIPF	;stop condition detected?
	;	rjmp	main_loop
		sbrc	Flags,START_DETECTED ;start condition detected?
		rjmp	start_cond
		sbis	USISR,USIOIF
		rjmp	write_2
		in	Temp1,USIDR
		com	Temp1
		out	DDRA,Temp1
		rjmp	write_loop

; prepare the ATtiny26 to receive the ACK bit from the master
read:		ldi	Temp1,(1<<USIOIF)+0x0E	;2 SCL edges
		out	USISR,Temp1
		cbi	PORTB,SDA
		sbi	DDRB,SDA
; wait until the master reads the ACK bit
read_1:		sbis	USISR,USIOIF
		rjmp	read_1
;
; the master reads data from the ATtiny26
read_loop:	in	Temp1,PINA
		out	USIDR,Temp1
		ldi	Temp1,(1<<USIOIF)+0x00	;16 SCL edges
		out	USISR,Temp1
		sbi	PORTB,SDA
		sbi	DDRB,SDA
; wait until the master reads the Data Byte
read_2:		sbis	USISR,USIOIF
		rjmp	read_2
		cbi	DDRB,SDA
; prepare the ATtiny26 to receive the ACK bit from the master
		ldi	Temp1,(1<<USIOIF)+0x0E	;2 SCL edges
		out	USISR,Temp1
; wait until the master sends the ACK bit
read_3:	;	sbic	USISR,USIPF	;stop condition detected?
	;	rjmp	main_loop
		sbrc	Flags,START_DETECTED ;start condition detected?
		rjmp	start_cond
		sbis	USISR,USIOIF
		rjmp	read_3
		in	Temp1,USIDR
		sbrs	Temp1,0		;test the ACK bit	
		rjmp	read_loop
; no acknowledge, wait for a stop or start condition
read_4:	;	sbic	USISR,USIPF	;stop condition detected?
	;	rjmp	main_loop
		sbrc	Flags,START_DETECTED ;start condition detected?
		rjmp	start_cond
		rjmp	read_4


; USI Start handler - called when the start condition detected
usi_strt:	push	Temp1
		in	Temp1,SREG
		push	Temp1
		ldi	Temp1,(1<<USISIF)
		out	USISR,Temp1
		sbr	Flags,(1<<START_DETECTED)
		pop	Temp1
		out	SREG,Temp1
		pop	Temp1
		reti
Grüße

s.o.