falscher Rückgabewert aus SoftSPI

OP #2007682
Lesenswert?

Hallo Zusammen!
Ich verwende das unten stehende Programm, um die SoftSPI am RFM12 
auszulesen. Am LogicAnalyzer kann ich gut sehen, wann und wie ausgelesen 
wird und was hätte auch im uC ankommen müssen.
Leider wird nicht der korrekte Wert unter der Variablen abgelegt sondern 
immer nur 0xFFFF. Woran kann das liegen? Ich suche mir daran schon seit 
Ewigkeiten einen Wolf, bis ich es nun schließlich endlich als Ursache 
identifizieren konnte!
1
unsigned int rf12_rxstatus(void)              {
2
  unsigned int werti=0;
3
  unsigned char i;
4
    uint8_t i_sreg = SREG;      // SREG sichern
5
    cli();                      // Interrupts unterbinden
6

7
  cbi(RF_PORT, CS);
8
    cbi(RF_PORT, SDI);
9

10
  for (i=0; i<16; i++) {  
11
    werti<<=1;
12
    if (RF_PIN&(1<<SDO))
13
      werti|=1;
14
    sbi(RF_PORT, SCK);
15
    _delay_us(0.3);
16
    cbi(RF_PORT, SCK);
17
  }
18
  sbi(RF_PORT, CS);
19
    SREG = i_sreg;
20
  return werti;
21
}
22

23
ISR (INT0_vect) {
24
  [...]
25
    rf12_int0_handler();
26
  [...]
27
}
28

29
void rf12_int0_handler() {
30
  uint16_t status_reg = 0;
31
  status_reg = rf12_rxstatus();
32
  [...]
33
  
34
  char buffa[30];
35
  sprintf(buffa, "Ergebnis: 0x%X\r\n",status_reg);
36
  uart_puts(buffa);
37
}
38

39
uint8_t main(void) {
40
  Activate_INT0;
41
  while(!) {
42
    nop();
43
  }
44
}
OP #2007731
Lesenswert?

Floh schrieb:
>>     _delay_us(0.3);
> übrigends glaub ich nicht, dass das funktioniert. Was sagt der Compiler?

Der Compiler nimmt's gelassen. Laut delay.h:
     void   _delay_us (double __us)
wird also gleich zu _delay_us(0) optimiert. Der High-Impuls dauert bei 
mir etwa 0.6us. ICH HAB'S ABER AUCH BLOß AUS 'NER LIBRARY KOPIERT... 
schäm
Die Sache mit dem SREG hab ich mir (aus alten ASM Zeiten) so angewöhnt. 
So kann ich solche Funktionen auch z.B. aus einer ISR anspringen, ohne 
das mir die INTs freigegeben werden.

Ich verstehe aber trotzdem nicht, warum bei SDO Dauer-Low 0xFFFF zurück 
gegeben wird. Stimmen denn die Übergaben der Variablenkopien und sind 
deren Typen kompatibel?
#2007750
Lesenswert?

Obwohl ein paar Unschönheiten enthalten sind, sollte zumindest die 
Routine rf12_rxstatus funtionieren. Stimmt denn der Rest des Programms, 
speziell die defines für RF_PORT, RF_PIN, CS, SDI, SDO und SCK? Sind die 
Datenrichtungsregister richtig eingestellt (SDO als Eingang)?
OP #2007774
Lesenswert?

In der Lib sind wahrlich noch mehrere Unschönheiten wie
1
RF_DDR  = (1<<SDI)|(1<<SCK)|(1<<CS);
anstelle von
1
RF_DDR  |= (1<<SDI)|(1<<SCK)|(1<<CS);
 Ich hab auch den Sample-Zeitpunkt geändert. Danke Floh!
Aber daran allein hat es hier nicht gelegen! Ich hab nochmal den 
Messkopf in die Hand genommen: ICH HASSE DAS BLÖDE JTAG-INTERFACE!!! 
Ich hab JTAG schon über die Software ausgeschaltet wenn PINx auf Low. 
Aber wenn der Stecker von Dragon noch drauf steckt, zieht der die 
Pegel(!!), die ich über Widerstände zum RFM gelegt hatte. LA natürlich 
am RFM angesteckt, an dem natürlich noch das Richtige rauskommt, nur 
eben nicht mehr beim uC rein...

ICH DAAAANKE EUCH !!

so, genug rumgebrüllt. ;o)
#2008443
Lesenswert?

Gregor B. schrieb:
> Floh schrieb:
>>>     _delay_us(0.3);
>> übrigends glaub ich nicht, dass das funktioniert. Was sagt der Compiler?

Warum sollte es nicht?

> Der Compiler nimmt's gelassen. Laut delay.h:
>      void   _delay_us (double __us)
> wird also gleich zu _delay_us(0) optimiert.

Kommt halt auf den Prozessortakt an. Bei z.B. 3,3 Mhz sind 0,3 µs ja 
gerade mal ein Taktzyklus.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren