- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 5 von 5

Thema: RFM12b an tiny2313 USI

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1

    RFM12b an tiny2313 USI

    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.

    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

    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
    Code:
    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
    Geändert von dannyboy1994 (13.12.2016 um 18:22 Uhr)

Ähnliche Themen

  1. RN-MikroFunk - Fertiges Projekt eines Miniaturboards inkl Funkmodul RFM12b
    Von Frank im Forum Eigene fertige Schaltungen und Bauanleitungen
    Antworten: 16
    Letzter Beitrag: 22.06.2016, 17:28
  2. Programmierung von RFM12b mit RN-MikroFunk
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 18.12.2015, 18:50
  3. Arduino mit Rfm12b empfängt nicht
    Von Der Einsteiger im Forum Arduino -Plattform
    Antworten: 0
    Letzter Beitrag: 28.07.2015, 15:00
  4. Bascom Funksteckdosen mit RN AVR-Universal (und RFM12b) ansteuern
    Von Frank im Forum Bascom / C / ASM / Sketch / Codesammlung / Programmschnipsel
    Antworten: 0
    Letzter Beitrag: 18.01.2013, 17:33
  5. Rfm12B und Xmega128A3
    Von ChRiZ im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 22.03.2011, 09:09

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen