Funktioniert jetzt.
Die bisher im Netz zu findenden Sourcecodes sind immer sehr umfangreich. Deswegen habe ich den Quellcode auf das Minimum reduziert, keine Fehlerroutinen etc.
Interrupts waren nicht gewünscht.
Der Teil Slave muss noch verbessert werden - drei Schleifen Mainloop sind nicht wirklich elegant.
Über Rückmeldungen oder Fragen werde ich mich freuen.
U.
Master:
Code:
; zwei ATMega8 sind per TWI verbunden
.equ ZSP,0x13 ; r19 Zwischenspeicher für empfangene Zeichen
;-----------------------------------------------------------------------------
begin: rjmp main ; RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
reti ; INT0 External Interrupt Request 0
reti ; INT1 External Interrupt Request 1
reti ; TIMER2 COMP Timer/Counter2 Compare Match
reti ; TIMER2 OVF Timer/Counter2 Overflow
reti ; TIMER1 CAPT Timer/Counter1 Capture Event
reti ; TIMER1 COMPA Timer/Counter1 Compare Match A
reti ; TIMER1 COMPB Timer/Counter1 Compare Match B
reti ; TIMER1 OVF Timer/Counter1 Overflow
reti ; TIMER0 OVF Timer/Counter0 Overflow
reti ; SPI, STC Serial Transfer Complete
reti ; USART, RXC USART, Rx Complete
reti ; USART, UDRE USART Data Register Empty
reti ; USART, TXC USART, Tx Complete
reti ; ADC ADC Conversion Complete
reti ; EE_RDY EEPROM Ready
reti ; ANA_COMP Analog Comparator
reti ; TWI 2-wire Serial Interface
reti ; SPM_RDY Store Program Memory Ready
;------------------------------------------------------------------------------
main: ldi Temp,hi8(RAMEND) ; Main program start
out SPH,Temp ; Set Stack Pointer to top of RAM
ldi Temp,lo8(RAMEND)
out SPL,Temp
;..................
rcall twiInitMaster
;------------------------------------------------------------------------------
mainloop: ; zu sendende Daten liegen im Register ZSP
rcall twiStart
ldi r16,0b11111110 ; Slave-Adresse + W
rcall twiWriteByte
mov r16,ZSP ; Zeichen wird in Register 16 an TWI-Schreibroutine übergeben
rcall twiWriteByte
rcall twiStopp
rjmp mainloop
;-----------------------------------------------------------------------------
twiInitMaster:
push r16
; Clock
ldi r16,10 ;((F_CPU/TWI_CLOCK)-16)/2
out TWBR,r16
;TWI-Status-Register (Vorteiler)
ldi r16,0
out TWSR,r16
; Enable
ldi r16,0b11000100 ;_TWINT _TWEA _TWEN
out TWCR,r16
pop r16
ret
;------------------------------------------------------------------------
twiStart:
push r16
ldi r16,0b10100100 ; TWINT TWSTA TWEN
out TWCR,r16
rcall twiTWINTwarten ; warten bis TWINT gesetzt
pop r16
ret
;------------------------------------------------------------------------
twiStopp:
push r16
ldi r16,0b10010100 ; TWINT TWSTO TWEN
out TWCR,r16
pop r16
ret
;------------------------------------------------------------------------
twiWriteByte:
push r16 ; Daten in Reg 16 übergeben
out TWDR,r16 ; Daten bereitlegen
ldi r16,0b10000100 ; TWINT TWEN
out TWCR,r16 ; senden
rcall twiTWINTwarten ; warten bis TWINT gesetzt
pop r16
ret
;------------------------------------------------------------------------
twiTWINTwarten:
in r16,TWCR
sbrs r16,7 ; TWINT
rjmp twiTWINTwarten
ret
;------------------------------------------------------------------------------
Slave:
Code:
.include "AVR.H"
.equ Temp,0x10 ; r16 wird zur Übergabe an Unterprogramme benutzt
;-----------------------------------------------------------------------------
begin: rjmp main ; RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
reti ; INT0 External Interrupt Request 0
reti ; INT1 External Interrupt Request 1
reti ; TIMER2 COMP Timer/Counter2 Compare Match
reti ; TIMER2 OVF Timer/Counter2 Overflow
reti ; TIMER1 CAPT Timer/Counter1 Capture Event
reti ; TIMER1 COMPA Timer/Counter1 Compare Match A
reti ; TIMER1 COMPB Timer/Counter1 Compare Match B
reti ; TIMER1 OVF Timer/Counter1 Overflow
reti ; TIMER0 OVF Timer/Counter0 Overflow
reti ; SPI, STC Serial Transfer Complete
reti ; USART, RXC USART, Rx Complete
reti ; USART, UDRE USART Data Register Empty
reti ; USART, TXC USART, Tx Complete
reti ; ADC ADC Conversion Complete
reti ; EE_RDY EEPROM Ready
reti ; ANA_COMP Analog Comparator
reti ; TWI 2-wire Serial Interface
reti ; SPM_RDY Store Program Memory Ready
;------------------------------------------------------------------------------
main: ldi Temp,hi8(RAMEND) ; Main program start
out SPH,Temp ; Set Stack Pointer to top of RAM
ldi Temp,lo8(RAMEND)
out SPL,Temp
;..................
rcall twiInitSlave
;------------------------------------------------------------------------------
mainloop: ; warten bis TWINT
in r16,TWCR
sbrs r16,7 ;TWINT
rjmp mainloop
;der Slave wurde adressiert
ldi r16,0b11000100 ; TWINT TWEA TWEN ->ACK an Master
out TWCR,r16
ml2: in r16,TWCR
sbrs r16,7 ;TWINT
rjmp ml2
in r20,TWDR ; Daten sind eingetroffen
ldi r16,0b11000100 ; TWINT TWEA TWEN ->ACK an Master
out TWCR,r16
ml3: in r16,TWCR
sbrs r16,7 ;TWINT
rjmp ml3
;Stoppbedingung muss quittiert werden
ldi r16,0b11000100 ; TWINT TWEA TWEN ->ACK an Master
out TWCR,r16
; die empfangenen Daten liegen jetzt in Register R20 zur weiteren Verarbeitung
rjmp mainloop
;------------------------------------------------------------------------------
twiInitSlave: ;ohne Interrupt
push r16
ldi r16,0b11111110 ;TWI_Slave_Adresse ohne General Call
out TWAR,r16 ; Adressregister
ldi r16,0b01000100 ; TWEA TWEN
out TWCR,r16 ; Enable
pop r16
ret
Lesezeichen