Forum: Mikrocontroller und Digitale Elektronik Atmega8 RFM12 spi problem


von pepperpill (Gast)


Lesenswert?

Hallo Leute,

bin gerade dabei eine Funkstrecke mit 2 Atmega8 und 2 RFM12 aufzubauen, 
würde das ganze per Hardware SPI realisieren. Habe hier aber momentan 
ein Problem..

Und zwar schicke ich mit dem einen Atmega ein Byte, welches der andere 
empfangen und dann eine Led blinken lassen soll.

Jedoch habe ich hier mit SPI ein problem. Wenn ich den ISP stecker vom 
zu empfänger Atmega abnehme funktioniert das empfangen mit dem RFM12 
auch nicht mehr.
Ich habe mittlerweile herausgefunden, dass das Problem beim MISO liegt, 
dieser arbeitet anscheinend nur richtig wenn der Miso vom brenner 
angeschlossen ist, hat jemand eine ahnung wieso?

Anbei noch mein Code, welcher wegen dem ganzen herumprobieren etwas 
unübersichtlich geworden ist.

Hier die rfm12.h
1
#ifndef RFM12_RECV_H_
2
#define RFM12_RECV_H_
3
4
#include "main.h"
5
6
#define LED1_OUTPUT() DDRD|=(1<<6)
7
#define LED1_OFF() PORTD&=~(1<<6)
8
#define LED1_ON() PORTD|=(1<<6)
9
#define LED2_OUTPUT() DDRD|=(1<<5)
10
#define LED2_OFF() PORTD&=~(1<<5)
11
#define LED2_ON() PORTD|= (1<<5)
12
13
14
#define DDR_SPI  DDRB
15
#define  DD_MISO  PB4
16
#define  DD_MOSI  PB3
17
#define  DD_SCK  PB5
18
#define DD_SS  PB2
19
20
#define PORT_SS  PORTB
21
#define P_SS  PB2
22
23
24
//rfm12 Anschlüsse
25
#define RFM12_FFIT (PIND&(1<<PD3))
26
#define RFM12_VDI (PINB&(1<<PB0))
27
#define RFM12_nIRQ (!(PIND&(1<<PD2)))
28
29
#define FFIT_DDR DDRD
30
#define FFIT_PORT PORTD
31
#define FFIT_P PD3
32
33
#define VDI_DDR DDRB
34
#define VDI_PORT PORTB
35
#define VDI_P PB0
36
37
#define nIRQ_DDR DDRD
38
#define nIRQ_PORT PORTD
39
#define nIRQ_P PD2
40
41
#define FSK_DDR DDRD
42
#define FSK_PORT PORTD
43
#define FSK_P PD7
44
45
46
void SPI_MasterInit(void);
47
uint8_t SPI_MasterTransmit(uint8_t cData);
48
void RF12_INIT(void);
49
uint16_t RFM12_WRT_CMD(uint16_t data);
50
void RFM12_SEND(uint8_t c);
51
uint8_t RFM12_RECV();
52
void RFM12_STATUS(void);
53
void Delay_ms(uint16_t ms);
54
55
#endif /* RFM12_RECV_H_ */

Hier die rfm12.c
1
-----------------------
2
ATMEGA8           RFM12
3
-----------------------
4
SCK               SCK
5
MISO              SDO
6
MOSI              SDI
7
SS                nSEL
8
INT0              nIRQ
9
PD6               LED1
10
PD5               LED2
11
PD4               Module-Power
12
13
PD7               FSK
14
PD3               DCLK,FFIT
15
PB0               NINT, VDI
16
**********************************************************************/
17
#include "main.h"
18
#include "rfm12.h"
19
#include "uart.h"
20
21
void SPI_MasterInit(void)
22
{
23
  /* Set MOSI and SCK and SS output, all others input */
24
  DDR_SPI = (1 << DD_MOSI) | (1 << DD_SCK) | (1 << DD_SS);
25
  /* Enable SPI, Master,  */
26
  SPCR = (1 << SPE) | (1 << MSTR);
27
}
28
29
uint8_t SPI_MasterTransmit(uint8_t cData)
30
{
31
  uint8_t  b = 0;
32
  /* Start transmission */
33
  SPDR = cData;
34
  /* Wait for transmission complete */
35
  while(!(SPSR & (1<<SPIF)));
36
  b = SPDR;
37
38
  return  b;
39
}
40
/* Ende: SPI für RFM12 */
41
42
/* RFM12 */
43
uint16_t RFM12_WRT_CMD(uint16_t data)
44
{
45
  uint16_t  b = 0;
46
47
  PORT_SS &= ~(1 << P_SS);   //Slave select LOW
48
   
49
  b = SPI_MasterTransmit(data >> 8) << 8;
50
  b |= SPI_MasterTransmit(data & 0x00FF);
51
52
  PORT_SS |= (1 << P_SS);    //Slave deselect HIGH
53
54
  return  b;
55
}
56
57
void RF12_INIT(void){
58
  
59
  SPI_MasterInit();
60
61
  FFIT_DDR &= ~(1 << FFIT_P);  // Eingang
62
  FFIT_PORT &= ~(1 << FFIT_P);  // PullUp Aus
63
  //VDI auf Eingang (Valid Data Indicator)
64
  VDI_DDR &= ~(1 << VDI_P);  // Eingang
65
  VDI_PORT &= ~(1 << VDI_P);  // PullUp Aus
66
  //nIRQ auf Eingang, wird low wenn Status abgeholt werden muss
67
  nIRQ_DDR &= ~(1 << nIRQ_P);  // Eingang
68
  nIRQ_PORT &= ~(1 << nIRQ_P);  // PullUp Aus
69
  //FSK mit PullUp auf High PortPin B3
70
  FSK_DDR &= ~(1 << FSK_P);  // Eingang
71
  FSK_PORT |= (1 << FSK_P);  // PullUp An
72
    
73
  RFM12_WRT_CMD(0x80D7);//EL,EF,11.5pF
74
  RFM12_WRT_CMD(0x82D9);//!er,!ebb,ET,ES,EX,!eb,!ew,DC
75
  RFM12_WRT_CMD(0xA640);//434MHz
76
  RFM12_WRT_CMD(0xC647);//4.8kbps
77
  RFM12_WRT_CMD(0x94A0);//VDI,FAST,134kHz,0dBm,-103dBm
78
  RFM12_WRT_CMD(0xC2AC);//AL,!ml,DIG,DQD4
79
  RFM12_WRT_CMD(0xCA81);//FIFO8,SYNC,!ff,DR
80
  RFM12_WRT_CMD(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN
81
  RFM12_WRT_CMD(0x9850);//!mp,9810=30kHz,MAX OUT
82
  RFM12_WRT_CMD(0xE000);//NOT USE
83
  RFM12_WRT_CMD(0xC800);//NOT USE
84
  RFM12_WRT_CMD(0xC400);//1.66MHz,2.2V
85
}
86
87
void RFM12_SEND(uint8_t c)
88
{
89
  uint16_t status = 0;
90
91
  while (!RFM12_nIRQ); //Warten auf int
92
  status = RFM12_WRT_CMD(0x0000);   //Status abholen
93
  RFM12_WRT_CMD(0xB800 + c); //Zeichen senden
94
}
95
96
uint8_t RFM12_RECV()
97
{  
98
  uint16_t   w = 0;
99
  uint16_t   status = 0;
100
  uint8_t   b = 0;
101
  
102
  RFM12_WRT_CMD(0xCA81);  //FIFO initalisieren
103
     
104
  RFM12_WRT_CMD(0xCA83); //FIFO aktivieren
105
  while (!RFM12_nIRQ)//Warten auf int    
106
107
  status = RFM12_WRT_CMD(0x0000);   //Status abholen
108
    
109
  w = RFM12_WRT_CMD(0xB000);  //Daten abholen
110
111
  b = w & 0x00FF;    
112
113
  RFM12_WRT_CMD(0xCA81);  //FIFO deaktivieren
114
  return b;
115
}
116
117
void Delay_ms(uint16_t ms)
118
{
119
  for(uint16_t t=0; t<=ms; t++)
120
    _delay_ms(1); 
121
}

Vielen Dank für eure Hilfe!!!

von pepperpill (Gast)


Lesenswert?

Pullups und Pulldowns am Miso bewirken übrigens auch nichts, ohne den 
miso pin vom brenner klappt das mit dem spi iwie nicht!

von Johann (Gast)


Lesenswert?

Funktioniert ohne den ISP stecker das senden an das Modul via SPI auch 
nicht oder klappt das?

Bin ehrlich gesagt überfragt

von pepperpill (Gast)


Lesenswert?

Ja wenn der Stecker ab ist, funktioniert das senden... nur mit miso 
gibts probleme.

Habe nochmal nachgemessen, mit ISP stecker sind an MISO 3,3Volt, ohne 
0Volt.

Weiß hier wirklich niemand Rat?

von holger (Gast)


Lesenswert?

>Habe nochmal nachgemessen, mit ISP stecker sind an MISO 3,3Volt, ohne
>0Volt.
>
>Weiß hier wirklich niemand Rat?

Masseleitung vergessen und der Brenner stellt diese dann her?

von pepperpill (Gast)


Lesenswert?

Hey Holger,

nein, die Masseleitung ist da der Controller funktioniert sonst auch 
einwandfrei, es reicht auch wenn ich nur MISO vom ISP verbinde.

von Krapao (Gast)


Lesenswert?

Welchen Pull-Up hattest du versucht, intern oder extern? Wenn extern, 
welcher Wert? Welchen "ISP-Brenner" verwendest du, wieso ist dessen MOSI 
nicht im tri-state? Das Atmega8 Targetboard arbeitet mit Vcc 3.3V? Ist 
das Targetboard ein Selbstbau (Schaltplan?) oder ein bekanntes Board?

von pepperpill (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Krapao,

habe interne und externe pullup(10k) probiert. Benutze den DIAMEX 
PROG-S.
Habe die Schaltung in einem Steckbrett aufgebaut, Schaltplan hänge ich 
an.

Hoffe du kannst mir mit diesen Informationen weiterhelfen.

von Krapao (Gast)


Lesenswert?

>  while (!RFM12_nIRQ)//Warten auf int
                     ^^
Hier fehlt hier ein ; oder ein {} in der RFM12_RECV(). Vielleicht 
verbessert sich mit dem richtigen Code das Timing und das mit dem ISP 
ist nur eine Beobachtung aber nicht die Ursache.

von pepperpill (Gast)


Lesenswert?

Hey Krapao,

das scheint echt die Lösung zu sein!! Bis jetzt funktioniert alles, 
vielen Dank, wär ich nie drauf gekommen!

von pepperpill (Gast)


Lesenswert?

Hallo,

irgendwie scheint das ganze jetzt doch nicht mehr zu Funktionieren. Ich 
lasse an beiden Atmega's anfangs eine Led blinken, dass klappt auch. 
Jedoch die SPI kommunikation danach nicht mehr.

Nur nachdem ich die Atmegas mehrmals neuprogrammiere funktioniert alles 
ca 1-2 mal reibungslos, dann geht wieder gar nichts.

An bei nochmal der Aktuelle Sourcecode der sich ein wenig geändert hat.
1
-----------------------
2
ATMEGA8           RFM12
3
-----------------------
4
SCK               SCK
5
MISO              SDO
6
MOSI              SDI
7
SS                nSEL
8
INT0              nIRQ
9
PD6               LED1
10
PD5               LED2
11
PD4               Module-Power
12
13
PD7               FSK
14
PD3               DCLK,FFIT
15
PB0               NINT, VDI
16
**********************************************************************/
17
#include "main.h"
18
#include "rfm12.h"
19
#include "uart.h"
20
21
void SPI_MasterInit(void)
22
{
23
  /* Set MOSI and SCK and SS output, all others input */
24
  DDR_SPI = (1 << DD_MOSI) | (1 << DD_SCK) | (1 << DD_SS);
25
  /* Enable SPI, Master,  */
26
  SPCR = (1 << SPE) | (1 << MSTR);
27
}
28
29
uint8_t SPI_MasterTransmit(uint8_t cData)
30
{
31
  uint8_t  b = 0;
32
  /* Start transmission */
33
  SPDR = cData;
34
  /* Wait for transmission complete */
35
  while(!(SPSR & (1<<SPIF)));
36
  b = SPDR;
37
38
  return  b;
39
}
40
/* Ende: SPI für RFM12 */
41
42
/* RFM12 */
43
uint16_t RFM12_WRT_CMD(uint16_t data)
44
{
45
  uint16_t  b = 0;
46
47
  PORT_SS &= ~(1 << P_SS);   //Slave select LOW
48
   
49
  b = SPI_MasterTransmit(data >> 8) << 8;
50
  b |= SPI_MasterTransmit(data & 0x00FF);
51
52
  PORT_SS |= (1 << P_SS);    //Slave deselect HIGH
53
54
  return  b;
55
}
56
57
void RF12_INIT(void){
58
  
59
  SPI_MasterInit();
60
61
  FFIT_DDR &= ~(1 << FFIT_P);  // Eingang
62
  FFIT_PORT &= ~(1 << FFIT_P);  // PullUp Aus
63
  //VDI auf Eingang (Valid Data Indicator)
64
  VDI_DDR &= ~(1 << VDI_P);  // Eingang
65
  VDI_PORT &= ~(1 << VDI_P);  // PullUp Aus
66
  //nIRQ auf Eingang, wird low wenn Status abgeholt werden muss
67
  nIRQ_DDR &= ~(1 << nIRQ_P);  // Eingang
68
  nIRQ_PORT &= ~(1 << nIRQ_P);  // PullUp Aus
69
  //FSK mit PullUp auf High PortPin B3
70
  FSK_DDR &= ~(1 << FSK_P);  // Eingang
71
  FSK_PORT |= (1 << FSK_P);  // PullUp An
72
    
73
  RFM12_WRT_CMD(0x80D7);//EL,EF,11.5pF
74
  RFM12_WRT_CMD(0x82F9);//!er,!ebb,ET,ES,EX,!eb,!ew,DC
75
  RFM12_WRT_CMD(0xA640);//434MHz
76
  RFM12_WRT_CMD(0xC647);//4.8kbps
77
  RFM12_WRT_CMD(0x94A0);//VDI,FAST,134kHz,0dBm,-103dBm
78
  RFM12_WRT_CMD(0xC2AC);//AL,!ml,DIG,DQD4
79
  RFM12_WRT_CMD(0xCA81);//FIFO8,SYNC,!ff,RD
80
  RFM12_WRT_CMD(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN
81
  RFM12_WRT_CMD(0x9850);//!mp,9810=30kHz,MAX OUT
82
  RFM12_WRT_CMD(0xE000);//NOT USE
83
  RFM12_WRT_CMD(0xC800);//NOT USE
84
  RFM12_WRT_CMD(0xC400);//1.66MHz,2.2V
85
}
86
87
void RFM12_SEND(uint8_t c)
88
{
89
  uint16_t status = 0;
90
91
  while (!RFM12_nIRQ); //Warten auf int
92
  status = RFM12_WRT_CMD(0x0000);   //Status abholen
93
  RFM12_WRT_CMD(0xB800 + c); //Zeichen senden
94
}
95
96
void RFM12_SEND_PACKET(uint8_t txdata)
97
{
98
  LED1_ON();
99
    RFM12_WRT_CMD(0x0000);//read status register
100
    RFM12_WRT_CMD(0x8239);//!er,!ebb,ET,ES,EX,!eb,!ew,DC
101
    RFM12_SEND(0xAA);//PREAMBLE
102
    RFM12_SEND(0xAA);//PREAMBLE
103
    RFM12_SEND(0xAA);//PREAMBLE
104
    RFM12_SEND(0x2D);//SYNC HI BYTE
105
    RFM12_SEND(0xD4);//SYNC LOW BYTE
106
  
107
    RFM12_SEND(txdata);//DATA BYTE 0
108
  
109
    RFM12_SEND(0xAA);//DUMMY BYTE
110
    RFM12_SEND(0xAA);//DUMMY BYTE
111
    RFM12_SEND(0xAA);//DUMMY BYTE
112
    RFM12_WRT_CMD(0x8201);
113
    LED1_OFF();
114
}
115
116
void RFM12_STATUS(void)
117
{
118
119
  uint16_t  w;
120
121
  if (RFM12_nIRQ) {
122
123
    w = RFM12_WRT_CMD(0x0000);  //Status abholen
124
//  char s[17];
125
//    uart_puts("  RFM12 Status: ");
126
//    uart_puts(utoa(w, s, 2 ));
127
128
  }
129
}
130
131
uint8_t RFM12_RECV()
132
{  
133
  uint16_t   w = 0;
134
  uint16_t   status = 0;
135
  uint8_t   b = 0;
136
  RFM12_WRT_CMD(0x82D9);
137
  RFM12_WRT_CMD(0xCA81);  //FIFO initalisieren
138
     
139
  RFM12_WRT_CMD(0xCA83); //FIFO aktivieren
140
  while (!RFM12_nIRQ);//Warten auf int    
141
142
  status = RFM12_WRT_CMD(0x0000);   //Status abholen
143
    
144
  w = RFM12_WRT_CMD(0xB000);  //Daten abholen
145
146
  b = w & 0x00FF;    
147
148
  RFM12_WRT_CMD(0xCA81);  //FIFO deaktivieren
149
  return b;
150
}
151
152
void Delay_ms(uint16_t ms)
153
{
154
  for(uint16_t t=0; t<=ms; t++)
155
    _delay_ms(1); 
156
}

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.