Forum: Mikrocontroller und Digitale Elektronik RFM12B init SDO kein signal


von Lukas G. (lukas88)


Lesenswert?

Hallo users,


Ich werkle nun seit Wochen an einem RFM12B herum, und bekomme es einfach 
nicht hin es zu initialisieren. Das Modul soll mit einem Attiny13 
zusammenarbeiten das auf mit dem Internen Oszilator auf 4.8 MHz läuft. 
Ich bekomme bei SDO kein hing puls vom RFM also bleibt mein Programm bei


rf12_trans_wait:
 sbis   PINB, 3     ;Wenn SDO noch nicht 1 is
 rjmp   rf12_trans_wait ;nochmal schaun, obs 1 is

stehen. Wenn ich dies Zeile auskommentiere/Lösche, läuft das Programm 
weiter, das RFM wird aber nicht konfiguriert. Ist mein erstes Projekt, 
in dem Kommunikation mit einem Anderen Chip/Modul per SPI von nöten ist, 
entsprechend läuft es etwas zäh. Ich messe mit dem Oszi nach, kann aber 
nicht wirklich testen, ob meine Konfiguration beim RFM wirklich 
angekommen sind.

Verbindungen:

SS         = PB0 ;Output active low
SDO        = PB3 ;Input
SCK        = PB2 ;Output
SDI        = PB4 ;Output

DDRB =0b11110101

Mein Bisheriger Code:

.nolist
.include "includes/tn13def.inc"
.list

;**************************************************************
;Konstanten
;**************************************************************

; SPI
.equ SPI_DDR_PORT   = DDRB
.equ SPI_PORT       = PORTB
.equ SS         = 0 ;Output active low
.equ SDO        = 3 ;Input
.equ SCK        = 2 ;Output
.equ SDI        = 4 ;Output

.equ SPI_DDR_Standart_dir =0b11110101 ;Inputs : INT0 an PB1 SDO an PB3

;GENERAL
.equ C_FREQ =4800000
.equ STUFFBIT =0xAA


;**************************************************************
;Registerdefinitionen
;**************************************************************


.def status = r16
.def temp= r17
.def timer_count = r18
.def led_status =r19
.def lsb  = r20
.def msb  = r21

.def sendbyte = r22

;**************************************************************
;Vektorentabelle
;**************************************************************


.org 0x0000
rjmp init

.org 0x0003
rjmp int_timer


int_timer:

cpi     timer_count,255
breq    timer_zero
inc     timer_count
reti
timer_zero:
clr     timer_count
reti


wait_100ms:
clr     timer_count
wait_100ms_loop:
cpi     timer_count,8
breq    exit_timer
rjmp        wait_100ms_loop
exit_timer:
ret


rf12_trans:
cbi    PORTB, 0    ;CS auf 0(aktiv)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop


rf12_trans_wait:
 sbis   PINB, 3     ;Wenn SDO noch nicht 1 is
 rjmp   rf12_trans_wait ;nochmal schaun, obs 1 is

ldi    temp, 16          ;16 Datenbits sinds
rf12_trans_loop:
 lsl    lsb              ;Ins derzeitige LSB 0 schreiben und schieben
 rol    msb              ;Weiterschieben und MSB ins Carry
 cbi    PORTB, 4    ;SDI auf 0
 brcc   rf12_trans_0    ;Wenn Carry eh gecleart is, so lassen
 sbi    PORTB, 4    ;Andernfalls SDI auf 1
rf12_trans_0:
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 sbis   PINB,3             ;Wenn SDO auf 1
 ori    lsb, 1           ;Ins derzeitige LSB 1 schreiben

 sbi    PORTB, 2    ;Clock-Impuls erzeugen
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop
 nop                    ;A bisserl Zeit lassen
 nop

 cbi    PORTB, 2

 dec    temp              ;Bit Zähler runterzählen
 brne   rf12_trans_loop ;Wenn nicht abgelaufen, wiederholen

 sbi    PORTB, 0     ;CS auf 1(inaktiv)
 cbi    PORTB, 4    ;SDI auf 0
ret



;**************************************************************
;Initialisierung
;**************************************************************


rfm_init:

cbi    PORTB, 0     ;CS auf 0(aktiv)

rcall wait_100ms

ldi     msb,0x80
ldi     lsb,0x98

rcall rf12_trans

ldi     msb,0x82
ldi     lsb,0x39
rcall rf12_trans

ldi     msb,0xA4
ldi     lsb,0xB0

rcall rf12_trans

ldi     msb,0xC6
ldi     lsb,0x23

rcall rf12_trans

ldi     msb,0x91
ldi     lsb,0x80

rcall rf12_trans

ldi     msb,0xC2
ldi     lsb,0x2C

rcall rf12_trans

ldi     msb,0xCA
ldi     lsb,0x80

rcall rf12_trans

ldi     msb,0xCE
ldi     lsb,0xD4

rcall rf12_trans

ldi     msb,0xC4
ldi     lsb,0xF7

rcall rf12_trans

ldi     msb,0x98
ldi     lsb,0x00

rcall rf12_trans

ldi     msb,0xCC
ldi     lsb,0x57

rcall rf12_trans
ret


init:


ldi     temp,SPI_DDR_Standart_dir
out     DDRB,temp


ldi     temp, 0b000000001
out     PORTB,temp



ldi     temp, LOW(RAMEND)
out     SPL, temp

 ;Timer

ldi     temp,0b00000100 ;256 Prescale 73 Overflows per sec a 73HZ
out     TCCR0B,temp

ldi     temp,0b00000010 ; Interrupt bei Overflow
out     TIMSK0,temp

clr     timer_count

;Interrupts an INT0

ldi     temp,(1<<ISC01)|(1<<ISC00) ; INT0 und INT1 auf fallende Flanke 
konfigurieren
out     MCUCR,temp

ldi     temp,0b01000000 ; INT0 aktivieren
out     GIMSK,temp

ldi     temp,0b01000000 ; INT0 aktivieren
out     GIFR,temp

clr     timer_count


sei ;Interrupts an
rcall rfm_init



;**************************************************************
;Hauprogramm
;**************************************************************


main:




rjmp main

von Michael U. (amiga)


Lesenswert?

Hallo,

habe da jetzt nicht wirklich rübergeschaut.
Hier mal die RFM12-Routinen aus einem fast 10 Jahre alten Projekt von 
mir:
1
;************************ RFM12 Sende-Routinen *****************************
2
3
;***************************** RFM12 Send CMD ******************************
4
; Sub: Sendet 16Bit Kommando aus Z
5
; Parameter:  Z Kommando
6
; Return:    Y Status ???
7
; Scratch-Reg:  Z, TEMP_0, TEMP_1
8
;***************************************************************************
9
10
// nFFS: 1-10k Pullup an Vcc !!!
11
12
RFM12_send_cmd:
13
    cbi    RFM12_PORT,RFM12_CS
14
15
    ldi    TEMP_1,16      ; Anzahl Bits
16
17
RFM12_send_cmd_loop:
18
    cbi    RFM12_PORT,RFM12_SDI    
19
    sbrc  ZH,7
20
    sbi    RFM12_PORT,RFM12_SDI    
21
22
    nop
23
    nop
24
    sbi    RFM12_PORT,RFM12_SCK
25
    nop
26
    nop
27
    nop
28
    nop
29
    nop
30
    nop
31
    nop
32
    nop
33
    nop
34
    nop
35
    nop
36
    nop
37
    cbi    RFM12_PORT,RFM12_SCK    
38
39
    lsl    ZL
40
    rol    ZH
41
42
    dec    TEMP_1
43
    brne  RFM12_send_cmd_loop
44
45
    sbi    RFM12_PORT,RFM12_CS
46
    
47
    ret
48
49
;***************************** RFM12 Init **********************************
50
; Sub: Initialisiert den RFM02
51
; Parameter:  -
52
; Return:    -
53
; Scratch-Reg:  Z, TEMP_0, TEMP_1
54
;***************************************************************************
55
56
RFM12_init:
57
58
    load_p  Z,0x0000      ; Status read
59
    rcall  RFM12_send_cmd
60
61
    load_p  Z,0xC080      ; CLK-Frequenz 2,5MHz, Batterie-Level 2,2V
62
    rcall  RFM12_send_cmd
63
64
    load_p  Z,0x80D7      ; TX-Reg. enable, RX-FIFO enable, C = 11,5pF
65
    rcall  RFM12_send_cmd
66
67
    load_p  Z,0xC2AB      ; Clock Recovery auto, DQD Thresold 3
68
    rcall  RFM12_send_cmd
69
70
    load_p  Z,0xCA81      ; FIFO-Level 8 Bit, Sync-Word aktiv, Disable High Sens Reset 
71
    rcall  RFM12_send_cmd
72
73
    load_p  Z,0xE000      ; WakeUp aus 
74
    rcall  RFM12_send_cmd
75
76
    load_p  Z,0xC800      ; Low Duty Cycle aus, 
77
    rcall  RFM12_send_cmd
78
79
    load_p  Z,0xC4F3      ; AFC unabhängig von VDI, AFC-Range + 3-4, AFC out enable, AFC ein
80
    rcall  RFM12_send_cmd
81
82
    load_p  Z,0xA620      ; Frequenz
83
    rcall  RFM12_send_cmd
84
85
    load_p  Z,0x948C      ; VDI ein, VDI fast, Bandbreite 200kHz, LNA -6db, RSSI .79db 
86
    rcall  RFM12_send_cmd
87
88
    load_p  Z,0xC610      ; Baudrate 19200
89
    rcall  RFM12_send_cmd
90
91
    ret
92
93
;************************** RFM12 Empfang Daten ****************************
94
; Sub: Liest Datenbyte vom RFM12
95
; Parameter:  -
96
; Return:    TEMP_0 Anzahl
97
; Scratch-Reg:  TEMP_0, TEMP_1
98
;***************************************************************************
99
100
RFM12_read_fifo:
101
    load_p  Y,DATA_BUF
102
    mov    TEMP_2,TEMP_0    ; Anzahl merken
103
104
    load_p  Z,0x82C8      ; Receiver ein, Base Band ein, Quarz ein
105
    rcall  RFM12_send_cmd
106
107
    load_p  Z,0xCA81      ; FIFO-Level 8 Bit, Sync-Word aktiv, Disable High Sens Reset 
108
    rcall  RFM12_send_cmd
109
110
    load_p  Z,0xCA83      ; FIFO-Level 8 Bit, Sync-Word aktiv, Disable High Sens Reset, Enable FfIFI fill
111
    rcall  RFM12_send_cmd
112
113
    cbi    RFM12_PORT,RFM12_SCK
114
    cbi    RFM12_PORT,RFM12_SDI
115
116
RFM12_read_fifo_loop:
117
    cbi    RFM12_PORT,RFM12_CS
118
119
RFM12_read_fifo_wait:
120
    sbis  RFM12_PIN,RFM12_SDO
121
    rjmp  RFM12_read_fifo_wait
122
123
    ldi    TEMP_1,8
124
    ldi    TEMP_0,0xB0          ; Receive FIFO read
125
126
RFM12_read_fifo_cmd:
127
    cbi    RFM12_PORT,RFM12_SDI
128
    sbrc  TEMP_0,7
129
    sbi    RFM12_PORT,RFM12_SDI
130
131
    nop
132
    nop
133
    sbi    RFM12_PORT,RFM12_SCK
134
    nop
135
    nop
136
    nop
137
    nop
138
    nop
139
    nop
140
    cbi    RFM12_PORT,RFM12_SCK
141
    lsl    TEMP_0
142
    nop
143
    dec    TEMP_1
144
    brne  RFM12_read_fifo_cmd
145
146
RFM12_read_fifo_daten_start:    
147
    clr    TEMP_0
148
    ldi    TEMP_1,8
149
150
RFM12_read_fifo_daten:
151
    lsl    TEMP_0
152
    sbic  RFM12_PIN,RFM12_SDO
153
    sbr    TEMP_0,0b00000001
154
155
    sbi    RFM12_PORT,RFM12_SCK
156
    nop
157
    nop
158
    nop
159
    nop
160
    cbi    RFM12_PORT,RFM12_SCK
161
    dec    TEMP_1
162
    brne  RFM12_read_fifo_daten
163
164
    st    Y+,TEMP_0
165
    sbi    RFM12_PORT,RFM12_CS
166
167
    dec    TEMP_2
168
    brne  RFM12_read_fifo_loop
169
170
    load_p  Z,0x8208      ; Empfänger aus, Quarz bleibt an
171
    rcall  RFM12_send_cmd
172
173
    ret

Hier noch die defines der Pins dazu:
1
.equ  RFM12_PORT    = PORTC
2
.equ  RFM12_PIN    = PINC
3
4
.equ  RFM12_SDI    = PC0
5
.equ  RFM12_SCK    = PC1
6
.equ  RFM12_SDO    = PC2
7
.equ  RFM12_CS    = PC3
8
9
.equ  RFM12_IRQ_PIN  = PIND
10
.equ  RFM12_IRQ_IN  = PD2

Komplett findest Du die Sachen hier auf meiner alten Homepage:
http://www.avr.roehres-home.de/sensoren/i_usb_empfaenger.html

Gruß aus Berlin
Michael

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

hier in der Abhandlung sind etliche Beispiele zu finden. Ich hatte mir 
seinerzeit eines ausgesucht, das tatsächlich funktioniert hat.

Beitrag "bidirektionale RS232 Funkbrücke mit RFM12"

SDO wird nur im TX-mode abgefragt:
"TXREGISTER BUFFERED DATATRANSMISSION
In this operating mode (enabled by bit el, in the Configuration Setting 
Command) the TX data is clocked into one of the two
8-bit data registers. The transmitter starts to send out the data from 
the first register (with the given bit rate) when bit et is set with the 
Power Management Command. The initial value of the data registers (AAh) 
can be used to generate preamble. During this mode, the SDO pin can be 
monitored to check whether the register is ready (SDO is high) to 
receive the next byte from the microcontroller."

MfG

: Bearbeitet durch User
von Lukas G. (lukas88)


Lesenswert?

Hallo Michael,

Danke für deinen Code. Beim ersten betrachten fällt mir auf,das bei

RFM12_send_cmd der Status des SDO nicht abgefragt wird. Demnach muss ich 
mit dem Senden der nächsten Bits nicht auf die Bestätitung des RFMs 
warten und kann die Bits einfach senden? Oder übersehe ich da was?

besten dank Lukas

von Michael U. (amiga)


Lesenswert?

Hallo,

das ist SPI, auch wenn ich bei den RFM-Modulen mit Hardware-SPI 
Timingprobleme hatte und deshalb auch zu Fuß mit den Bits gewackelt 
habe.
Der RFM übernimmt mit dem Takt (welche Flanke müßte ich im Datenblatt 
suchen) das Datenbit von SDI und legt an SDO sein Bit an zum einlesen. 
Das ist entweder das Statuswort oder Daten oder auch nur "Müll", den man 
ignorieren kann.
Also /CS aktiv, Datenbit ran, Clock Impuls, SDO einlesen und aufheben, 
wenn man die Antwort braucht.
SDO hat noch eine Sonderfunktion in bestimmten Fälle: der RFM12 legt das 
oberste Statusbit an SDO an wenn man ihn aktiviert. Das hat den Vorteil, 
daß man Status nicht komplett einlesen muß, wenn man z.B. nur abfragen 
will, ob er irgendwas zu melden hat, sondern nur dann, wenn es gesetzt 
ist.

Gruß aus Berlin
Michael

von Lukas G. (lukas88)


Lesenswert?

Hallo Michael,

Heute Morgen das Programm umgeschrieben, ohne SDO und beim ersten Anlauf 
geklappt.  Ich kann die Frequenzteilung des RFM am CLK verändern, durch 
die Teilereinstellung. Also versteht das RFM was ich tun will, und kann 
es entsprechend konfigurieren .

rf12_trans:
    cbi    PORTB, 0    ;CS auf 0(aktiv)
    nop
    nop

    ldi    temp, 16

rf12_trans_loop:
    lsl    lsb              ;Ins derzeitige LSB 0 schreiben und schieben
    rol    msb              ;Weiterschieben und MSB ins Carry
    cbi    PORTB, 4    ;SDI auf 0
    brcc   rf12_trans_0    ;Wenn Carry eh gecleart is, so lassen
    sbi    PORTB, 4    ;Andernfalls SDI auf 1
rf12_trans_0:
    sbi    PORTB, 2    ;Clock-Impuls erzeugen
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop                 ;A bisserl Zeit lassen
    cbi    PORTB, 2
    dec    temp              ;Bit Zähler runterzählen
    brne   rf12_trans_loop ;Wenn nicht abgelaufen, wiederholen

    sbi    PORTB, 0     ;CS auf 1(inaktiv)
    cbi    PORTB, 4    ;SDI auf 0
ret

;Frequenz umschalten per Taster

Interrupt an INT0

int_1:

ldi     msb,0xC0
ldi     lsb,0xE0 ;Quarz auf 10 MHz stellen

rcall rf12_trans
reti


 Besten dank für die Hilfe!



mfg Lukas

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

Frequenzumstellung am Ausgabepin war damals auch meine erste Übung, 
konnte man schnell sehen, ob überhaupt was sinnvolles passierte.

Viel Erolg weiterhin, meine RFM-Sensoren laufen ja nun erst seit gut 9 
Jahren. Letztens mußte ich beim Sensor im Keller doch glatt die Batterie 
(CR123A) wechseln, nach gerade mal rund 3 1/3 Jahren... ;-)

Gruß aus Berlin
Michael

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.