In der routine read_byte wird meines erachtens nichts nennenswertes verändert man könnte jetzt natürlich noch die register pushen. Aber in dem aktuellen zusammenhang dürfte hier kein Problem auftreten. Ja es ist das richtige hex file
aber danke für den TIpp. ist mir auch schon passiert....-.-
@LotadaC
Ok dann müsste meine aktuelle pinbelegung eigentlich stimmen. Noch ist mir unklar in wie weit ich nIRQ bzw den nINT/VDI pin nutzen kann.
Ich habe mir vorher andere module bestellt gehabt. ganz einfache für 2 euro der satz aus china. Da der eigenbau eines Protokols leider gescheitert war und via USART eine Fehllerrate unter der würde einer jeden FUnkverbindung zu stande kahm, landeten sie in der "Is da aber scheise"-Kiste
. Nun dann rtecherichirte ich ...Die RFM12 sollten so einfach anzusteuern sein. Ich laß von SPI (erster gedanke " Ein TRaum")...nun ja und nun siehts nicht so prikelnd aus.
Ansich sollen die Module ohne weiteres 100m machen. Wäre natürlich super für mein Projekt. Allgemein zählt hier natürlich wieder der gedanke das es nicht darum geht eine funktsionsfähige wetterstation hier zu haben welche man auch für 10 euro in jedem baumarkt bekommt, sondern der selbstbaufaktor mit unendlichen erweiterungsmöglichkeiten.
Nun bin ich mir aber durch endlose probiererei darüber im klaren das entweder sich das statusregister nicht auslesen lässt, oder die kommunikation mit dem modul nicht funktioniert.
hier ein code welcher nur das statusregister nach der initialisierung via usart ausgeben soll. Leider auch recht erfolglos. Das Register liefert immer 0.
CodeBox Assembler
;tn2313 USART communicatrionstest RFM12
.include "tn2313def.inc"
.org 0x000
rjmp init
.org 0x0020
.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 datah=r24
.def datal=r23
.def datain=r25
.org 0x0000
.equ spiddr=ddrb
.equ spiport=portb
.equ nsel=0
.def counter=r20
.equ debugport=portd ;Nur zu testzwecken
.equ debugddr=ddrd
.org 0x020
init:
ldi temp1, low(ramend)
out spl, temp1
rcall serinit
;rcall rfninit
rcall hallo
sbi ddrb, 7
;sbi ddrb, 6
sbi ddrb, 5
main:
rcall delay1s
rcall wert
wait:
sbic pinb, 6
rjmp wait
rcall readstatusrfm12
mov temp1, datah
rcall seroutdez
mov temp1, datal
rcall seroutdez
rjmp main
rjmp main
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
;******************************************************************
;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
wert:
ldi temp1, 'W'
rcall serout
ldi temp1, 'e'
rcall serout
ldi temp1, 'r'
rcall serout
ldi temp1, 't'
rcall serout
ldi temp1, ';'
rcall serout
ldi temp1, ' '
rcall serout
ret
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
;0x95A2 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
readstatusrfm12:
clr lsb
clr msb
rcall send_command
int0_init:
ldi temp1,(1<<ISC01)|(0<<ISC00)
out mcucr,temp1
ldi temp1, (1<<INT0)
out GIMSK,temp1
ret
;**********************************************
;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
pop lsb ;16.12.2016
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
nop nop nop nop ;Zu testzwecken nach Dirk ein kleines delay
nop nop nop nop
rcall SPITransfer
in datah, USIDR
mov temp1, lsb
rcall SPITransfer
in datal, USIDR
sbi spiport,nsel
ret
;****************************************************************
;INTERRUPTHANDLERS
;****************************************************************
Ext0_int_handle:
;;Daten stehen bereit
;;Auslesen
rcall read_byte
reti
.include "stddelay.inc"
Ich denke sollte ich hier mit eurer hilfe das Modul zum laufen bringen werde ich auf jeden fall eine funktionstüchtige routine sauberst dokumentiert hier im forum veröffentrlichen. Dieses leiden soll nicht noch einmal jemanden passieren
Ich bin auch schon am überlegen das ganze mal an einem mega8 zu testen welcher ja ein "echtes" SPI mit SS besitzt. Wobei das natürlich auch nicht das problem aus der welt schafft den mehr platz als für einen tiny44 hab ich im gehäuße für den außenfühler leider nicht. Aber die Funktion der Module wäre merst einmal gesichert.
noch einen schönen Sonntag an alle
Daniel