Code:
;;;Kleines Testprogramm
;;Tiny2313 als empfänger
;;Empfängt ein Byte und gibt dieses via usart aus
;;USI als SPI Master
.list
.include "tn2313def.inc"
.nolist
.equ XTAL=1000000
.equ t5ms = ( XTAL * 5 / 606 ) / 1000
.def temp1=r16
.def temp2=r17
.def temp3=r18
.def data=r19
.def lsb=r21
.def msb=r22
.def datain=r23
.org 0x0000
.equ spiddr=ddrb
.equ spiport=portb
.equ nsel=0
rjmp start
.org 0x020
loop:
mov data, lsb
rcall read_byte ;befindet sich anschließend in LSB
cp data, lsb
breq loop
mov temp1, lsb
rcall seroutdez
rcall delay1s
rjmp loop
start:
ldi temp1, low(ramend)
out spl, temp1 ;Stackpointer init
sbi spiddr, nsel
rcall rfninit ;RFM12 inittialisiert und bereit("hoffentlich")
rcall initrs232
rcall loop
;;Nsel auf low einen momment warten dann bit an SDI vom modul(mit dem höchsten bit starten)
; high low an sclk(serial clock) nächstes bit.....dann Nsel wieder auf high
rfninit:
;folgende init werte zum übertragen
;Empfänger:
;0x80E7 868mhz, RX fifo TX buffer 12pf
;0x8280 enable receiver
;0xA640 868mhz center freq
;0xC647 19,2kbaud
;0x9582 Max empfangsstärke 200khz pin als VDI pin
;0xC2AC digitaler fehlerbehebung
;0xCA81
;0xC483
;0x9850 TX controll
;0xE000
;0xC800
;0xC040
;KOmmando 0xB000 read 8 bits from fifoRX
;kommando 0xB8xx send 8 bits of data
ldi msb, 0x80
ldi lsb, 0xE7
rcall send_command
ldi msb, 0x82
ldi lsb, 0x80
rcall send_command
ldi msb, 0xA6
ldi lsb, 0x40
rcall send_command
ldi msb, 0xC6
ldi lsb, 0x47
rcall send_command
ldi msb, 0x95
ldi lsb, 0x82
rcall send_command
ldi msb, 0xc2
ldi lsb, 0xAC
rcall send_command
ldi msb, 0xCA
ldi lsb, 0x81
rcall send_command
ldi msb, 0xc4
ldi lsb, 0x83
rcall send_command
ldi msb, 0x98
ldi lsb, 0x50
rcall send_command
ldi msb, 0xE0
ldi lsb, 0x00
rcall send_command
ldi msb, 0xC8
ldi lsb, 0x00
rcall send_command
ldi msb, 0xC0
ldi lsb, 0x40
rcall send_command
ret
usi_init:
;;USIWM1 und 0 für SPI
;; 0 1
ret
send_byte:
;DATENBIT MUSS IN LSB Stehen
ldi msb, 0xB8
rcall send_command
ret
read_byte:
;;DATENBYTE befindet sich in LSB
ldi msb, 0xB0
ldi lsb, 0x00
rcall send_command
in lsb, USIDR
ret
send_command:
mov temp1, msb
cbi spiport,nsel
rcall SPITransfer
mov temp1, lsb
rcall SPITransfer
sbi spiport,nsel
ret
SPITransfer:
out USIDR,temp1
ldi r16,(1<<USIOIF)
out USISR,r16
ldi r17,(1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC)
SPITransfer_loop:
out USICR,r17
in r16, USISR
sbrs r16, USIOIF
rjmp SPITransfer_loop
in temp1,USIDR
ret
ret
initrs232:
.equ takt = 1000000 ; 16/8 MHz Systemtakt
.equ baud =2400 ; Baudrate
.equ ubrr_val = ((takt+baud*8)/(baud*16)-1) ; clever Runden
.equ baud_real = (takt/(16*(ubrr_val+1))) ; tatsächliche Baudrate
.equ baud_error = ((baud_real*1000)/baud-1000) ; Fahler in Promille
;
;
.if ((baud_error> 10) || (baud_error <-10)) ; max +/- 10 Promill Fehler
.error "Systematischer Fehler der Baudrate größer als 1 Prozent und damit zu hoch!"
.else
.message "Systematischer Fehler der Baudrate hält sich in Grenzen - OK!"
.endif
rcall serinit
rcall hallo
ret
seroutdez:
push temp1 ; die Funktion verändert temp1 und temp2,
push temp2 ; also sichern wir den Inhalt, um ihn am Ende
; wieder herstellen zu können
mov temp2, temp1 ; das Register temp1 frei machen
; abzählen wieviele Hunderter
; in der Zahl enthalten sind
;** Hunderter **
ldi temp1, '0'-1 ; temp1 mit ASCII '0'-1 vorladen
number_1:
inc temp1 ; ASCII erhöhen (somit ist nach dem ersten
; Durchlauf eine '0' in temp1)
subi temp2, 100 ; 100 abziehen
brcc number_1 ; ist dadurch kein Unterlauf entstanden?
; nein, dann zurück zu lcd_number_1
subi temp2, -100 ; 100 wieder dazuzählen, da die
; vorherhgehende Schleife 100 zuviel
; abgezogen hat
cpi temp1, 0 ;Führende null weg
breq number_2
rcall serout ; die Hunderterstelle ausgeben
;** Zehner **
ldi temp1, '0'-1 ; temp1 mit ASCII '0'-1 vorladen
number_2:
inc temp1 ; ASCII erhöhen (somit ist nach dem ersten
; Durchlauf eine '0' in temp1)
subi temp2, 10 ; 10 abziehen
brcc number_2 ; ist dadurch kein Unterlauf enstanden?
; nein, dann zurück zu lcd_number_2
subi temp2, -10 ; 10 wieder dazuzählen, da die
; vorherhgehende Schleife 10 zuviel
; abgezogen hat
cpi temp1, 0 ;Führende null weg
breq number_3
rcall serout ; die Zehnerstelle ausgeben
;** Einer **
number_3:
ldi temp1, '0' ; die Zahl in temp2 ist jetzt im Bereich
add temp1, temp2 ; 0 bis 9. Einfach nur den ASCII Code für
rcall serout ; '0' dazu addieren und wir erhalten dierekt
; den ASCII Code für die Ziffer
pop temp2 ; den gesicherten Inhalt von temp2 und temp1
pop temp1 ; wieder herstellen
ret ; und zurück
hallo:
ldi temp1, 'O'
rcall serout
ldi temp1, 'K'
rcall serout
ldi temp1, ' '
rcall serout
ldi temp1, 'R'
rcall serout
ldi temp1, 'S'
rcall serout
ldi temp1, ' '
rcall serout
ldi temp1, '2'
rcall serout
ldi temp1, '3'
rcall serout
ldi temp1, '2'
rcall serout
ret
serout:
sbis ucsra,udre ; udre-bit ist gesetzt, wenn der Sendepuffer leer ist
; UART Data Register Empty
rjmp serout
out udr, temp1 ; Zeichen senden
ret ; zurück aus der Subroutine
; Zeichen über RS232 einlesen
; temp1: gibt das Zeichen zurück
serin:
sbis ucsra, rxc
rjmp serin ; wir warten bis ein Byte angekommen ist
in temp1, udr ; Zeichen einlesen
;rcall serout ; und zurücksenden
ret
serinit:
; Baudrate für RS232 einstellen
ldi temp1, high(ubrr_val)
out ubrrh, temp1
ldi temp1, low(ubrr_val)
out ubrrl, temp1
ldi temp1, (1<<ucsz1) | (1<<ucsz0) ; ucsz2:0 = 0 1 1 -> 8 Bit Daten, kein Parity, 1 Stopbit
out ucsrc, temp1
sbi ucsrb, txen ; TXE-Bit (3) setzen
sbi ucsrb, rxen ; RXE-Bit (4) setzen
;sbi ucsrb, rxcie ; RXCIE-bit (7) setzen, damit ein irq ausgelöst werden kann, wenn ein Zeichen da ist
ret
Nun ja das ganze sieht aus wie kraut und rüben. Ich bin gerade in der "hauptsache es funktioniert mal irgendwas "-Phase
Lesezeichen