.include "2313def.inc" .def temp1 = r16 .def data = r17 .def tx = r18 .equ SCL = 0 .equ SDA = 1 .cseg rjmp start ; Reset Handler reti ; IRQ0 Handler reti ; IRQ1 Handler reti ; Timer1 Capture Handler reti ; Timer1 Compare Handler reti ; Timer1 Overflow Handler reti ; Timer0 Overflow Handler reti ; UART RX Complete Handler reti ; UDR Empty Handler reti ; UART TX Complete Handler reti ; Analog Comparator Handler start: ldi temp1,RAMEND ; LOW-Byte der obersten RAM-Adresse out SPL,temp1 sbi UCR,TXEN ;TX aktivieren ldi temp1,4000000/(9600*16)-1 ;Baudrate (z.B. 9600) einstellen (bei 4MHz) out UBRR,temp1 sbi DDRB,SCL ; SCL ist Ausgang sbi DDRB,SDA ; SDA ist Ausgang sbi PortB,SCL sbi PortB,SDA rjmp MainLoop ; Ab ins Programm!!! reti serout: sbis USR,UDRE ;Warten, bis UDR für das nächste Byte bereit ist rjmp serout out UDR, tx ret ;zurück zum Hauptprogramm 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,SCL rcall I2C_Wait cbi PortB,SDA rcall I2C_Wait cbi PortB,SCL 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 ; hier lesen ;ldi tx,66 ;sbis PinB,SDA ;ldi tx,65 ;rcall serout 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: cbi PortB,SCL rcall I2C_Wait sbrc data,7 sbi PortB,SDA sbrs data,7 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,6 sbi PortB,SDA sbrs data,6 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,5 sbi PortB,SDA sbrs data,5 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,4 sbi PortB,SDA sbrs data,4 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,3 sbi PortB,SDA sbrs data,3 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,2 sbi PortB,SDA sbrs data,2 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,1 sbi PortB,SDA sbrs data,1 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait cbi PortB,SCL rcall I2C_Wait sbrc data,0 sbi PortB,SDA sbrs data,0 cbi PortB,SDA sbi PortB,SCL rcall I2C_Wait ret I2C_Bit_lesen: clc ; Carry löschen sbis 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 sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi PortB,SCL rcall I2C_Wait rcall I2C_Bit_lesen cbi PortB,SCL rcall I2C_Wait sbi DDRB,SDA ret MainLoop: ; Start rcall I2C_Start ; I2C-Adresse senden ldi data,0b10100000 rcall I2C_Send ; Ack.-Bit lesen rcall I2C_Read_Ack ; 1. ROM-Adresse senden ldi data,0b00000000 rcall I2C_Send ; Ack.-Bit lesen rcall I2C_Read_Ack ; 2. ROM-Adresse senden ldi data,0b00000000 rcall I2C_Send ; Ack.-Bit lesen rcall I2C_Read_Ack ; Daten-Byte senden ldi data,0b01010011 rcall I2C_Send ; Ack.-Bit lesen rcall I2C_Read_Ack ; Stop rcall I2C_Stop rcall I2C_Wait rcall I2C_Wait rcall I2C_Wait ; Start rcall I2C_Start ; I2C-Adresse senden ldi data,0b10100001 rcall I2C_Send ; Ack.-Bit lesen rcall I2C_Read_Ack ; I2C-Daten-Byte lesen rcall I2C_Read ; Ack.-Bit nicht senden --> Ende des Lesens rcall I2C_Send_no_Ack ; Stop rcall I2C_Stop mov tx,data rcall serout rjmp MainLoop