Sehr seltsames Verhalten von mega1284p + 74hc595 beim Sprung in Funktion

OP Persönliche Seite #2328895
Lesenswert?
• ▲
▼
Ich habe an einem Mega1284p 2 Shift Register (74hc595) angeschlossen und 
möchte die per HW-SPI ansprechen.

Die Funktion für die SRs habe ich aus einem anderen Projektordner von 
mir geholt, wo sie, in etwas anderer Form funktioniert. Bin das 
Datenblatt nochmal durchgegangen, kann aber keinen Fehler finden.

An PB1 ist RCK ("Enable")
PB5 Mosi ist SER
PB7 SCK ist SCK
Das Zweite Shift Register hängt mit SER auf QH' vom Ersten.

Ich habe mir mitm Oszi SCK und SER angesehen, wenn ich in einer Schleife 
die Funktion "srw" aufrufe, da tut sich gar nichts an den Pins.

Das sehr seltsame Verhalten jetzt ist:
1. Ich setzte Test LED auf AUS
2. Aufruf von srw()
3. Toggle LED (Led ist jetzt an)
4. Aufruf von srw()
5. Toggle LED (bis dahin kommt er nicht mehr, LED bleibt an, sollte aus)

Nun hab ich das Toggle direkt vor SPDR = data in der Funktion srw 
gesetzt und habe folgendes:

1. Setze Test auf AUS
2. srw() (LED jetzt an)
3. srw() LED geht nicht mehr an

Er bleibt also wohl beim Aufruf von srw hängen.

Hier der Code:
1
void srw(unsigned char data) {
2
  SPDR = data;
3
  while(!(SPSR & (1<<SPIF)));
4

5
  PORTB |= (1<<PB1);
6
  _delay_us(10);
7
  PORTB &= ~(1<<PB1);
8
  return;
9
}
10

11
int main(void) {
12
  DDRB |= (1<<PB1)|(1<<PB5)|(1<<PB7);
13
  PORTB &= ~(1<<PB1);  // disable SR
14
  
15
  DDRB |= (1<<PB0);  // test led
16
  PORTB |= (1<<PB0);  // led off
17
  
18
  SPCR = (1<<SPE)|(1<<MSTR);
19
  SPSR = (1<<SPI2X);
20
  
21

22
  srw(0x0f);
23
  srw(0xff);
24
    
25
  
26
  for(;;) {
27

28
  }
29
}

Ich hoffe meine Beobachtungen hierzu waren richtig, ich kann mir keinen 
Reim drauf machen und bin kurz vorm Verzweifeln...
Gast #2328914
Lesenswert?
• ▲
▼
Da du das SPDR Register nicht ausliesst, wird das SPIF-Flag nicht von 
der Hardware zurückgesetzt. Wenn du die Funktion srw etwas änderst 
könnte es klappen:

unsigned char srw(unsigned char data) {
  SPDR = data;
  while(!(SPSR & (1<<SPIF)));

  PORTB |= (1<<PB1);
  _delay_us(10);
  PORTB &= ~(1<<PB1);
  return SPDR;
}

Ich hoffe das hilft. Ich habs nicht selbst getestet.

Mfg Christian
OP Persönliche Seite #2329265
Lesenswert?
• ▲
▼
>"If SS is configured as an input, it must be held high to ensure Master
>SPI operation."
SS ist bei mir ja mittlerweile auch output.

Mit Pullup Int+Ext hab ichs an SS probiert, immer noch der selbe Fehler. 
Habs jetzt sogar aufm Steckbrett mit komplett leerem C-Projekt nur mit 
Code für die SRs probiert...

Die Shift Register funktionieren 100%ig, wenn ich von Hand Takt und 
Daten aufm Steckbrett anlege, gehts.
Gast #2329290
Lesenswert?
• ▲
▼
Du hast den Code wie Christian geschrieben hat geändert ?
Ich hätte an Deiner Stelle probeweise die SPI-ISR eingebaut, denn dann 
wär' ich mir um das gelöschte SPIF sicher, außerdem böte so 'ne ISR die 
Möglichkeit zum Testen 'ne LED zu setzen um damit der Lösung näher zu 
kommen.

Und nochmal den tatsächlich verwendeten Code posten, vielleicht sieht 
dann jemand noch was.

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