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.
CodeBox Assembler
Dies ist die software des empfängers
Und das die des Senders
CodeBox Assembler
Leider funktioniert nichts. das Empfängermodul zeigt mir via USART nicht mal das "hallo" an..
Desweiteren gibt es einige offene Fragen die mich quälen:
-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
Ich hoffe ihr könnt mir helfen. Ich stecke nämlich fest...
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.
CodeBox Assembler
;;;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"
Dies ist die software des empfängers
Und das die des Senders
CodeBox Assembler
.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 nichts. das Empfängermodul zeigt mir via USART nicht mal das "hallo" an..
Desweiteren gibt es einige offene Fragen die mich quälen:
-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
Ich hoffe ihr könnt mir helfen. Ich stecke nämlich fest...