;*************************************************** ; Test TWI ; ATtiny43143 USI ; PortB PB7=SCL; PB5=SDA ; Rev.: 23032018 ;*************************************************** ; ;Assemblerdirektiven: ; .nolist .include "tn4313def.inc" .list ; ; Definitionen: ; Im SRAM reservierte Bytes ; .dseg ; Datensegment (SRAM) Start bei .org 0x0060 ; Adresse 0x0060 ; ; ; Konstanten-Definitionen: .equ daten = portb .equ zeit0 = 500 .equ zeit1 = 65535 ; ;Registerdefinitionen: .def inttemp = r12 ; Temporaerregister fuer Interrupt-Routinen .def intreg = r15 ; Zwischenspeicher fuer SREG bei ISRs .def temp = r16 ; diverse Universalregister .def temp1 = r17 .def temp2 = r18 ; .cseg ; Codesegment .org 0x0000 ; Startadresse rjmp reset ; Interrupt Vektoren Einsprungadressen (default) ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .org 0x0001 ; ext IRQ0 Flanke rjmp INT00 .org 0x0002 ; ext IRQ1 Flanke rjmp INT10 .org 0x0003 ; Timer 1 capt rjmp ICP10 .org 0x0004 ; Timer 1 comp match A rjmp OC100 .org 0x0005 ; Timer 1 overflow rjmp OVF10 .org 0x0006 ; Timer 0 overflow rjmp OVF00 .org 0x0007 ; UART Receive Complete rjmp URXC0 .org 0x0008 ; UART Data Register Empty rjmp UDRE0 .org 0x0009 ; UART Transmit Complete rjmp UTXC0 .org 0x000A ; Analog Comparator Interrupt rjmp ACI00 .org 0x000B ; Pin Change Interrupt Request B rjmp PCIBA .org 0x000C ; Timer 1 comp match B rjmp OC1BA .org 0x000D ; Timer 0 comp match A rjmp OC0AA .org 0x000E ; Timer 0 comp match B rjmp OC0BA .org 0x000F ; USI Start Condition rjmp USIST .org 0x0010 ; USI Overflow rjmp USIOV .org 0x0011 ; Eprom read ready rjmp ERDYA .org 0x0012 ; Watchdog Timer Overflow rjmp WDTAD .org 0x0013 ; Pin Change Interrupt Request A rjmp PCIAA .org 0x0014 ; Pin Change Interrupt Request D rjmp PCIDA ; ;Interrupt Service Routinen - Interrupt handler ;- - - - - - - - - - - - - - - - - - - - - - - - - INT00: ; ISR not in use reti INT10: ; ISR not in use reti ICP10: ; ISR not in use reti OC100: ; ISR not in use reti OVF10: ; ISR not in use reti OVF00: ; ISR not in use reti URXC0: ; ISR not in use reti UDRE0: ; ISR not in use reti UTXC0: ; ISR not in use reti ACI00: ; ISR not in use reti PCIBA: ; ISR not in use reti OC1BA: ; ISR not in use reti OC0AA: ; ISR not in use reti OC0BA: ; ISR not in use reti USIST: ; ISR not in use reti USIOV: ; ISR not in use reti ERDYA: ; ISR not in use reti WDTAD: ; ISR not in use reti PCIAA: ; ISR not in use reti PCIDA: ; ISR not in use reti ; reset: cli ; Interrupts sperren ldi temp, low(ramend) ; Stackpointer setzen out spl, temp ldi temp, high(ramend) out sph, temp ldi yl, low(0x0060) ; <<8 Start SRAM-Bereich low(0x0060) ldi yh, high(0x0060) ; &255 Start SRAM-Bereich high(0x0000) ldi temp, 0x00 init10x: ; SRAM mit Nullen beschreiben st y+, temp ; Speicherzellen loeschen cpi yl, low(ramend+1) ; RAM-Ende (low) erreicht? brne init10x ; nein -> Schleife cpi yh, high(ramend+1) ; RAM-Ende (high) erreicht? brne init10x ; nein -> Schleife rcall regclr ; Registerreset rcall portinit ; Init I/O-Ports sei ; generelle Interruptfreigabe rjmp main ; Sprung zum Hauptprogramm ; regclr: ret ; portinit: ldi temp, 0xFF ; PortB Ausgang I2C out ddrb, temp out portb, temp out ddrd, temp ldi temp, 0xFF out portd, temp ret ; main: rjmp i2cmain ; ;- - - - Verzoegerungsschleifen - - - - - - - wait1: rcall wait3 rcall wait3 rcall wait3 rcall wait3 ret ; wait2: ; Verzoegerungsschleife 2: push xl ; Register sichern auf Stapel push xh push temp ; Sicherung von Temporaerregistern... push temp1 ; und Statusregister auf Stapel push temp2 in temp2, SREG ; (bei Interrupts notwendig) push temp2 ldi xl, low(zeit0) ; laedt Zaehlregisterpaar ldi xh, high(zeit0) ; mit oben deklariertem Wert... rjmp repeatx ; ..."zeit0" ; wait3: ; Verzoegerungsschleife 3: push xl ; Register sichern auf Stapel push xh push temp ; Sichern von Temporaerregistern push temp1 ; und Statusregister auf Stapel push temp2 in temp2, SREG push temp2 ldi xl, low(zeit1) ; laedt Zaehlregisterpaar ldi xh, high(zeit1) ; mit oben deklariertem Wert... rjmp repeatx ; ..."zeit1" ; repeatx: ; 16-Bit-Subtraktionsschleife: sbiw xl:xh, 1 ; decrementiert Doppelregister brne repeatx ; zaehlt bis Null pop temp2 ; Wiederherstellung out SREG, temp2 ; von "geretteten" Registern etc. pop temp2 pop temp1 pop temp pop xh pop xl ret ; ;- - - - - - Zahlenumwandlung(1) binaer=>dezimal - - - - - - num: ; wandelt 8 Bit binär auf "temp1" ; ; nach ASCII dezimal und gibt "temp" auf LCD aus ; ; Format: 2 Ziffern mit fuehrender Null push temp ; Eingaberegister "temp1", push temp1 ; Ausgaberegister "temp" push temp2 mov temp2, temp1 ldi temp1, 0x30 ; num3: subi temp2, 10 ; Berechnung Zehner brcs num4 inc temp1 rjmp num3 ; num4: mov temp, temp1 rcall i2csnd ; Ausgabe Zehnerstelle subi temp2, -10 ; Berechnung Einer ldi temp1, 0x30 add temp1, temp2 mov temp, temp1 rcall i2csnd ; Ausgabe Einerstelle pop temp2 pop temp1 pop temp ret ; ;- - - - - - - Zahlenumwandlung(2) BCD=>binaer - - - - - - ; ; Eingaberegister "temp" bcdbin: ; r1 = Zehner,r0 = Einer clr temp ; Ergebnisregister loeschen ldi temp1, 0x0A ; Vorladewert 10 ; bcdbin1: tst r1 ; Zehner = 0 ? breq bcdbin2 ; ja =>Einer direkt bearbeiten add temp, temp1 ; nein=>jedesmal 10 zu Ausgabe add. dec r1 ; so lange Zehner erniedrigen, rjmp bcdbin1 ; bis r1 Null ; bcdbin2: add temp, r0 ; Einer addieren; Ausgabe auf temp ret ; ; i2cmain: cli rcall i2cinit rcall i2cstart ldi temp,0x70 ; Adresse A0,A1,A2=GND + W=0; R=1 rcall i2csnd ;brts end ; NACK? ldi temp,0xE0 ; Kommando rcall i2csnd ; end: rjmp loop ; loop: rjmp loop ; i2cinit: sbi portb, 7 ; SCL high sbi portb, 5 ; SDA high sbi ddrb, 7 ; Port B7 (SCL) als Ausgang sbi ddrb, 5 ; Port B5 (SDA) als Ausgang sbi ddrb, 0 ldi temp, 0xFF out USIDR, temp ; Datenregister mit FF initialisieren ldi temp,(1<