PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RFM12b an tiny2313 USI



dannyboy1994
13.12.2016, 16:51
Hallo community. Ich bin derzeit dabei mir eine kleine Wetterstation zu bauen, bei welcher mir ein tiny44 die außentemperatur und Luftfeuchtigkeit über ein RFM12 Modul senden soll. Ein Tiny2313 soll das Ganze dann auf einem LCD und über den USART ausgeben. Nun stehe ich gerade am Anfang des ganzen und versuche mir funktionstüchtige routinen zu schreiben. Einmal eine für den tiny(reiner empfänger) und einen für den tiny44(reiner sender)

Das Ganze soll der USI realisiert werden.
Hier einmal mein aktueller stand beim tiny2313 Empfänger. Das drum herum ist erst einmal nebensächlich sondern eher die vorgehensweise beim empfang.
Könnte ein ambitioniertes Midglied des Forums einmal drüber schaun und mir evtl unter die arme greifen. Auch habe ich das gefühl das ich die ansteuerung des Moduls noch nicht so ganz verstanden habe.



;;;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

mfg Daniel

PS: Was mir gerade noch einfällt

wenn ich 8 bits per SPI an das RFM übertrage mit vorhergehendem msb 0x82
werden diese 8 bits dann sofort vom modul übertragen?
kann ich diese 8 bits beim empfänger mit dem senden von 0xB000 direkt auslesen und sie aus dem USIDR entnehmen?
kann ich das Modul einmal konfigurieren und dann durchgehend warten lassen bis etwas kommt, oder fängt es dann nur müll ein?
wie ist das mit dem VDI pin bzw nINT. Muss ich diese nutzen? oder kann ich auch softwareseitig sicher stellen wann neue daten vorhanden sein müssten.

Wenn ich den FIFO lese während das MOdul etwas empfängt, bekomme ich dann bitsalat oder bleiben die daten im FIFO so lange bestehen bis alle 8 bits empfangen sind und werden dann in den FIFO verschoben. Ich möchte möglichst mit einer minimalen beschaltung auskommen. Das nutzen eines externen intterupts wäre evtl noch eine nette sache. z.B intterupt wenn daten empfangen wurden...Dann auslesen und den MC in den sleep mode


Fragen über fragen...ich hoffe jemand kann für erleuchtung sorgen

PPS: Die Senderoutine wurde wie folgt geändert

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
Grund dafür isT:
-Energiesparen durch deaktivieren des senders
- Ich habe gelsen das man erst eine Präambel senden soll dann das Synchronbyte und der receiver auf der gegenseite erst das Byte nach dem Synchronbyte in seinen FIFO übernimmt

dannyboy1994
14.12.2016, 19:20
nun nach weiteren gefühlten 10 stunden vergebener arbeit habe ich nun die Programme für Sender und empfänger noch einmal geändert

sender:


;;;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:


.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...
Programmiert den Hier keiner mehr in Assembler

avr_racer
19.12.2016, 20:32
Hallo,

um es ein wenig übersichtlicher zu gestalten lager die Programmteile aus die im Moment nicht genutzt werden und binde sie später per Include ein.

So wie cih dich verstehe versuchst du die RS232 bzw die UART zum laufen zu bringen. Im zweiten Post erstes Programm wird nach der Startsequenz ein RCALL LOOP aufegrufen welches aber in dem LOOP mit einem RJMP beendet wird. Erstmal weiter nicht tragisch nur solltest du zu Testzwecken es eher:

Start:
....
RJMP LOOP

oder du schreibst es einfach ganz normal drunter weg

Start:
...
...
...
RJMP LOOP ;oder lääst das nach der Initialisierung in die loop laufen also ohne RJMP

die .org 0x020 kannst du weg lassen wenn du halt fortlaufend arbeitest brauch man nur wenn du mit nem BOOTLOADER arbeiten willst ..... sonst weg damit.. erstmal

loop:
mov data, lsb
sleep
cp data, lsb
breq loop
mov temp1, lsb
rcall seroutdez
rjmp loop




;;;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
.def counter=r20

.equ spiddr=ddrb
.equ spiport=portb
.equ nsel=0

.org 0x0000
rjmp start
.org 0x0001
rjmp Ext0_int_handle
reti
reti
reti
reti
.org 0x0006
rjmp Timer0OFL
reti
reti
reti
reti

start:
ldi temp1, low(ramend)
out spl, temp1 ;Stackpointer init

rcall initrs232
rcall hallo
rjmp loop ;kannst auch weg lassen

loop:
mov data, lsb
sleep
cp data, lsb
breq loop
mov temp1, lsb
rcall seroutdez
rjmp loop

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

;************************************************* *****************
;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
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) ; 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



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


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"

mal versucht den Code so zu ändern das der Ablauf einigermaßen erkennbar ist, wann von wo nach wo und zurück gesprungen wird.
Zusätzlich die Hardware geprüft ?? Also damit mein ich hast du mal tiny2313 und PC verbunden zum testen ? TX und RX geprüft ? Nicht das du die beiden 1:1 gesteckt hast richtig ist TX-RX / RX-TX.

geb dir mal den Hinweis hier rauf https://www.roboternetz.de/community/threads/67800-Tiny-2313-Bibliothek

dannyboy1994
24.12.2016, 01:33
wir sind nun auf makerconnect.com schon eine Weile mit dem Kampf beschäftigt. Der thread dort heißt RFM12b an tiny44 via USI. Es wurde versucht per soft SPI zu lösen per mega8-hardware SPI. Leider hat nun bis jetzt nichts den durchbruch gebracht. Ich weis auch nicht ob meine init stimmt. Ich poste hier gerne noch mal den aktuellen stand der routine. Deinen Link habe ich mir soeben angesehen. Sehr ausführlich Dokumentierte Arbeit. Wenn es dir nichts ausmacht würde ich sie sehr gerne verwenden, dar so viele nütziche und zeitsparende inits darin integriert sind.
Ein Frohes Fest und einen guten rutsch ins neue jahr.

avr_racer
24.12.2016, 10:53
Dafür ist solch Bibliothek da ;)

Aber mach mal bitte ein Schaltplan wo der RFM 12B (AVRxyz) genau dranhängt mit wem dieser AVR kommuniziert(Schnittstelle) und der AVR welcher per UART und LCD was ausgebn soll

Danke wünsche ich ebensfalls Frohe Weihnachten und ein guten Rutsch.