Code:
;;;Kleines Testprogramm
;;Tiny2313 als empfänger
;;Empfängt ein Byte und gibt dieses via usart aus
;;USI als SPI Master
;;interruptausgang von RFM an INT0
;;SPI standartverdrahtung
;;
.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
.def counter=r20
rjmp start
.org 0x0001
rjmp Ext0_int_handle
.org 0x0006
rjmp Timer0OFL
.org 0x020
loop:
mov data, lsb
sleep
cp data, lsb
breq loop
mov temp1, lsb
rcall seroutdez
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 int0_init
rcall inittimer0
sei
rcall loop
;**********************************************
;UNTERPROGRAMME
;**********************************************
send_byte:
push lsb
;sender einschalten
ldi msb, 0x82
ldi lsb, 0x20
rcall send_command
;DATENBIT MUSS IN LSB Stehen
ldi msb, 0xB8
push lsb
ldi lsb, 0xAA ;präambel
rcall send_command
rcall send_command
;;nun das synchronbyte
ldi lsb, 0x2D
rcall send_command
ldi lsb, 0xD4
rcall send_command
;;nun die nutzdaten
pop lsb
rcall send_command
;Zeit geben
rcall delay100ms
;sender wider ausschalten und empfänger an
ldi msb, 0x82
ldi lsb, 0x80
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
;******************************************************************
;RS232 Routine
;******************************************************************
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
; Zeichen über RS232 einlesen und als Echo zurücksenden
; temp1: gibt das Zeichen zurück
serinit:
; Baudrate für RS232 einstellen
ldi temp1, high(ubrr_val) ; zuerst Baudrate Highbyte (davon Lownibble)
out ubrrh, temp1
ldi temp1, low(ubrr_val) ; Lowbyte schreiben und prescaler damit triggern
out ubrrl, temp1
; frameformat setzen
ldi temp1, (1<<ucsz1) | (1<<ucsz0) ; ucsz2:0 = 0 1 1 -> 8 Bit Daten, kein Parity, 1 Stopbit
out ucsrc, temp1
; Transmitter einschalten, PortD Bit1 wird überschrieben
sbi ucsrb, txen ; TXE-Bit (3) setzen
; Receiver einschalten, PortD Bit0 wird überschrieben
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
;***********************************************************
;INITS
;***********************************************************
;;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
int0_init:
ldi temp1,(1<<ISC01)|(0<<ISC00)
out mcucr,temp1
ldi temp1, (1<<INT0)
out GIMSK,temp1
ret
inittimer0:
sbr temp1, TOIE0
out TIMSK, temp1
ldi temp1,0b00000111 ;max prescaler...bei 1mhz 255*1024=262144 takte
; was bei 1 mhz 1/4sek ist
out TCCR0B, temp1
ret
;****************************************************************
;INTERRUPTHANDLERS
;****************************************************************
Ext0_int_handle:
;;Daten stehen bereit
;;Auslesen
rcall read_byte
reti
Timer0OFL:
inc counter
cpi counter, 229
brne schlafen
cpi counter, 229
breq wach
reti
schlafen:
sleep
ret
wach:
clr counter
ret
.include "stddelay.inc"
Empfänger:
Code:
.include "tn44def.inc"
.def temp1=r16
.def temp2=r17
.def temp3=r18
.def datain=r19
.equ spiport=porta
.equ spiddr=ddra
.def lsb= r20
.def msb=r21
.equ XTAL=1000000
.equ t5ms = ( XTAL * 5 / 606 ) / 1000
.equ nsel=3
loop:
inc r22
mov lsb, r22
rcall send_byte
rcall delay1s
rjmp loop
start:
ldi temp1, high(ramend)
out sph, temp1
ldi temp1, low(ramend)
out spl, temp1 ;Stackpointer init
sbi spiddr, nsel
rcall rfninit ;RFM12 inittialisiert und bereit("hoffentlich")
rcall loop
;;;;;;;;;;;;;;;;;;;;;UNTERPROGRAMME
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
send_byte:
push lsb
;sender einschalten
ldi msb, 0x82
ldi lsb, 0x20
rcall send_command
;DATENBIT MUSS IN LSB Stehen
ldi msb, 0xB8
push lsb
ldi lsb, 0xAA ;präambel
rcall send_command
rcall send_command
;;nun das synchronbyte
ldi lsb, 0x2D
rcall send_command
ldi lsb, 0xD4
rcall send_command
;;nun die nutzdaten
pop lsb
rcall send_command
;Zeit geben
rcall delay100ms
;sender wider ausschalten und empfänger an
ldi msb, 0x82
ldi lsb, 0x80
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
.include "stddelay.inc"
Leider funktioniert garnichts. keine einzige usart ausgabe...nicht einmal das hallo...
Lesezeichen