.include "m32def.inc"
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18
; Die Definitionen müssen an den jeweiligen AVR angepasst werden
.equ F_CPU = 4000000
.equ BAUD = 9600
.equ SCHIEBE_DDR = DDRB
.equ SCHIEBE_PORT = PORTB
.equ RCK = PB4 ; SS
.equ SCK = PB7 ; SCK
.equ SIN = PB5 ; MOSI
.equ PL = PB3
.equ CLK = PB7 ; SCK
.equ DIN = PB6 ; MISO
;Berechnungen
.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)
.equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1)))
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif
.dseg
.org 0x60
Daten: .byte 2 ; Speicherplatz für Eingangsdaten
;-----------------------------------------------------------------------------
;
; Programmsegment im FLASH
;
;-----------------------------------------------------------------------------
.cseg
ldi temp1, LOW(RAMEND) ; Stackpointer initialisieren
out SPL, temp1
ldi temp1, HIGH(RAMEND)
out SPH, temp1
; CLK und PL als Ausgänge schalten
ldi temp1,(1<<CLK) | (1<<PL)
out SCHIEBE_DDR,temp1
; SCK, MOSI, SS als Ausgänge schalten
;
in temp1, SCHIEBE_DDR
ori temp1, (1<<SIN) | (1<<SCK) | (1<<RCK)
out SCHIEBE_DDR,temp1
receive_loop:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;EINGABE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SPI Modul konfigurieren
;
ldi temp1, 0b01011000
out SPCR, temp1 ; keine Interrupts, MSB first, Master
; CPOL = 1, CPHA =0
; SCK Takt = 1/2 XTAL
ldi temp1,1
out SPSR,temp1 ; double speed aktivieren
out SPDR,temp1 ; Dummy Daten, um SPIF zu setzen
;-----------------------------------------------------------------------------
; Zwei Bytes einlesen
ldi ZL,low(Daten)
ldi ZH,high(Daten)
ldi temp1,2
rcall schiebe_eingang
;-----------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;Verarbeitung;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;Ausgabe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ldi temp1, (1<<SPE) | (1<<MSTR)
out SPCR, temp1 ; keine Interrupts, MSB first, Master
; CPOL = 0, CPHA =0
; SCK Takt = 1/2 XTAL
ldi temp1, (1<<SPI2X)
out SPSR, temp1 ; double speed aktivieren
out SPDR, temp1 ; Dummy Daten, um SPIF zu setzen
ldi temp1, ZL
rcall schiebe
rcall schiebeout
rjmp receive_loop
;
; Die Daten im Schieberegister in das Ausgaberegister übernehmen
;
; Dazu am RCK Eingang am Schieberegister einen 0-1-0 Puls erzeugen
;
SchiebeOut:
sbis SPSR, SPIF ; prüfe ob eine alte Übertragung beendet ist
rjmp SchiebeOut
sbi SCHIEBE_PORT, RCK
cbi SCHIEBE_PORT, RCK
ret
;-----------------------------------------------------------------------------
;
; 8 Bits aus temp1 an das Schieberegister ausgeben
;
Schiebe:
sbis SPSR, SPIF ; prüfe ob eine alte Übertragung beendet ist
rjmp Schiebe
out SPDR, Ausgang ; Daten ins SPI Modul schreiben, Übertragung beginnt automatisch
ret
int_rxc:
Ruck:
rjmp receive_loop
;-----------------------------------------------------------------------------
;
; N Bytes seriell einlesen
;
; temp1 : N, Anzahl der Bytes
; Z : Zeiger auf einen Datenbereich im SRAM
;-----------------------------------------------------------------------------
schiebe_eingang:
push temp2 ; Register sichern
; CLK ist im Ruhezustand schon auf HIGH, CPOL=1
cbi schiebe_port, pl ; Daten parallel laden
sbi schiebe_port, pl
schiebe_eingang_1:
sbis SPSR,7 ; prüfe ob eine alte Übertragung beendet ist
rjmp schiebe_eingang_1
schiebe_eingang_byte_schleife:
out SPDR,temp1 ; beliebige Daten ins SPI Modul schreiben
; um die Übertragung zu starten
schiebe_eingang_2:
sbis SPSR,7 ; auf das Ende der Übertragung warten
rjmp schiebe_eingang_2
in temp2, spdr ; Daten lesen
st z+,temp2 ; Datenbyte speichern
dec temp1 ; Anzahl Bytes um eins verringern
brne schiebe_eingang_byte_schleife ; wenn noch mehr Bytes zu lesen sind
pop temp2
ret