hallo, wie genau funktioniert das sdo-polling beim RFM12 modul beim Senden und Empfangen? Ich mache jetzt schon ewig damit rum, komme aber auf keinen grünen zweig. Montan sieht meine Senderoutine (hard-spi) so aus: 1. sendeteil komplett einschalten (cs auf low, 0x8228 in reg. laden, cs auf high 2. cs auf low 3. warten, dass sdo high wird, solange nix machen 4. 0xb8aa in reg laden 5. warten, dass sdo high wird, solange nix machen 5. 0xaa in reg laden 6. warten, dass sdo high wird, solange nix machen 7. 0xaa in reg laden 8. warten, dass sdo high wird, solange nix machen 9. synchronmuster in reg laden 0x2DD4 10. warten, dass sdo high wird, solange nix machen 11. nutzdaten senden (je acht bit) 12. warten, dass sdo high wird, solange nix machen 13. 0xaa in reg laden 14. warten, dass sdo high wird, solange nix machen 15. sendetrakt aus (beeinhaltet cs auf high) funktioniert auch soweit ganz gut, würd ich sagen. Die Bilder auf dem Oszi sehen ok aus. Hab quasi das logikdiagramm ausm artikel RFM12 nachprogrammiert und das sieht wie gesagt ok aus. Jetzt zur empfangsroutine: wann genau bekomme ich beim empfangen vom RFM-Modul ein High-Signal am SDO? wie genau funktioniert hier das polling? Bekomme einfach kein high-signal am sdo... Aber einfach durchrauschen ohne auf das rfm modul zu reagieren klappt natürlich auch nicht...
1 | void rfm_TX(uint8_t *data) |
2 | {
|
3 | rfm_tx_enable(1); //sendetrakt komplett ein |
4 | rfm_enable(); |
5 | rfm_ready(); |
6 | spi_master_write_16(0xB8AA); //takteinlaufbyte |
7 | rfm_ready(); |
8 | spi_master_write_8(0xAA); //takteinlaufbyte |
9 | rfm_ready(); |
10 | spi_master_write_8(0xAA); //takteinlaufbyte |
11 | rfm_ready(); |
12 | spi_master_write_16(0x2DD4); //synchronmuster |
13 | for (int i=0; i<2; i++) |
14 | {
|
15 | rfm_ready(); |
16 | spi_master_write_8(*data); //nutzdaten: 1byte |
17 | }
|
18 | rfm_ready(); |
19 | spi_master_write_8(0xAA); //dummy-byte |
20 | rfm_ready(); |
21 | rfm_tx_enable(0); //sender ausschalten. (beeinhaltet rfm_disable) |
22 | }
|
23 | void rfm_RX(uint8_t *data) |
24 | {
|
25 | rfm_rx_enable(1); |
26 | rfm_writecmd(0xCA81); //FIFO leeren |
27 | rfm_writecmd(0xCA83); //FIFO freigeben |
28 | |
29 | rfm_enable(); |
30 | rfm_ready(); |
31 | spi_master_write_16(0xB0000); |
32 | rfm_ready(); |
33 | *data = spi_master_read(0x00); |
34 | rfm_disable(); |
35 | rfm_enable(); |
36 | |
37 | rfm_ready(); |
38 | spi_master_write_16(0xB000); |
39 | rfm_ready(); |
40 | *data = spi_master_read(0x00); |
41 | rfm_disable(); |
42 | rfm_enable(); |
43 | |
44 | rfm_ready(); |
45 | |
46 | blink(0, 100); |
47 | |
48 | rfm_rx_enable(0); |
49 | }
|
so siehts aus, funzt aber nicht. Ich schätze es hängt am empfang... Achja: ich sende zuerst einmal fest 2 byte, deswegen die for schleife
nachtrag: fehler lag am (auch / nur?!) am sender: die Zeile
1 | spi_master_write_16(0x2DD4); //synchronmuster |
muss aufgeteilt werden in
1 | spi_master_write_8(0x2D); //synchronmuster |
2 | rfm_ready(); |
3 | spi_master_write_8(0xD4); //synchronmuster |
da ich cs permanent auf low halte während ich das senderegister beschreibe kann ich nach einmaliges 0xb8xx mir dieses sparen, muss aber nach jedem byte sdo abfragen!
Das Modul steht bei mir auch bald auf dem Plan. Danke für die Beschreibung. cs ist bei dir nSEL, also chip-select, oder?
ja, genau, cs = chip select! Inzwischen läuft die Sache wirklich gut. Es war noch ein fehler im code des empfängers: der befehl zum auslesen des FIFO ist im Artikel mit 0xb8000 angegeben. Eigentlich ist es so, dass mit den ersten 8 bit 0xb0 schon der befehl zum auslesen des FIFO ans rfm modul geschickt wird. die restlichen 8bit sind dann nur dazu da, damit der µc (beim hardware SPI) einen takt an sck anlegt. das ganze sieht bei mir so aus (testweise mit 2 byte ohne irgendwelche längenangaben oder fehlerprüfsummen...)
1 | void rfm_RX(uint8_t *data) |
2 | {
|
3 | rfm_rx_enable(1); |
4 | rfm_writecmd(0xCA81); //FIFO leeren |
5 | rfm_writecmd(0xCA83); //FIFO freigeben |
6 | rfm_enable(); |
7 | |
8 | rfm_ready(); |
9 | spi_master_write_8(0xB0); |
10 | *data = spi_master_read(0x00); |
11 | rfm_disable(); |
12 | rfm_enable(); |
13 | |
14 | rfm_ready(); |
15 | spi_master_write_8(0xB0); |
16 | *data = spi_master_read(0x00); |
17 | rfm_disable(); |
18 | rfm_enable(); |
19 | |
20 | rfm_ready(); |
21 | rfm_rx_enable(0); |
22 | blink(LED_rt, 100); |
23 | }
|
1 | void spi_master_write_8(uint8_t cmd) |
2 | {
|
3 | SPDR = cmd; |
4 | while(!(SPSR & (1<<SPIF))) |
5 | ;
|
6 | }
|
7 | void spi_master_write_16(uint16_t cmd) |
8 | {
|
9 | uint8_t cmd_msb = 0; |
10 | uint8_t cmd_lsb = 0; |
11 | |
12 | cmd_msb = (cmd >> 8) & 0xFF; |
13 | cmd_lsb = cmd & 0xFF; |
14 | |
15 | SPDR = cmd_msb; |
16 | while(!(SPSR & (1<<SPIF))) |
17 | ;
|
18 | |
19 | SPDR = cmd_lsb; |
20 | while(!(SPSR & (1<<SPIF))) |
21 | ;
|
22 | }
|
23 | uint8_t spi_master_read(uint8_t cmd) |
24 | {
|
25 | uint8_t empfang = 0; |
26 | |
27 | SPDR = cmd; |
28 | while(!(SPSR & (1<<SPIF))) |
29 | ;
|
30 | empfang = SPDR; |
31 | |
32 | return empfang; |
33 | }
|
1 | void rfm_writecmd(uint16_t cmd) |
2 | {
|
3 | rfm_enable(); // RFM12 anwählen |
4 | spi_master_write_16(cmd); |
5 | rfm_disable(); //RFM12 abwählen |
6 | }
|
Höllisch aufpassen muss man dann eben auch noch mit dem chipselect, weil dieser maßgeblich am sdo-polling beteiligt ist. Und fsk beim polling unbedingt auf H-Pegel!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.