Forum: Mikrocontroller und Digitale Elektronik Software SPI Funktion funktioniert nicht immer - Logic Analyzer


von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Ich hab ein (für mich) seltsames Problem und zwar hab ich eine SPI 
Funktion, die 8 bit überträgt, diese Funktion sieht so aus:
1
void SPISendByte(uint8_t data){
2
  uint8_t counter = 0;
3
  for(counter = 0; counter < 8; counter++){
4
    uint8_t currentValue = (data >> (7-counter)) & 1;
5
    if(currentValue == 1)
6
      PD_ODR |= (1<<MOSI);
7
    else
8
      PD_ODR &=~(1<<MOSI);
9
    delay(4);
10
    PD_ODR |= (1<<SCK);
11
    delay(12);
12
    PD_ODR &=~(1<<SCK);
13
    delay(2);
14
    PD_ODR &=~(1<<MOSI);
15
    delay(2);
16
  }
17
}

Beim ersten Aufruf im Programm:
1
SPISendByte(0x80);

kommt nur das beim Logic Analyzer an (siehe Anhang). Wenn ich im 
Debug-Modus manuell durchsteppe wird der ganze if-Block 8-mal 
durchlaufen, der Analyzer zeigt aber nur 7 steigende Flanken an. Das 
Problem tritt nur beim allerersten Aufruf im Programm auf, bei jedem 
weiteren zeigt der LA korrekterweise 8 steigende Flanken an. Am 8. Clock 
im Bild erkennt man, dass danach ein 2. Funktionsaufruf erfolgt da der 
Abstand zum letzten Clock minimal länger ist. Ist mein Analyzer, mein MC 
oder meine Software kaputt?

: Bearbeitet durch User
von Sinus T. (micha_micha)


Lesenswert?

Da bei dir offensichtlich der Clock wenn idle ==0 ist, musst du 
irgenwann vor dem Aufruf deiner Routine Clock=low setzen, denn es kann 
keine erste low-high-Flanke geben, wenn Clock vorher schon high ist.

von Joe F. (easylife)


Lesenswert?

Dann setze deine Clock beim Start halt mal auf 0.
Die ist ja schon high, wenn CS low geht, daher siehst du die erste 
"high-Flanke", bei der MOSI auch 1 ist nicht.

von Joe F. (easylife)


Lesenswert?

Das
1
  uint8_t counter = 0;
2
  for(counter = 0; counter < 8; counter++){
3
    uint8_t currentValue = (data >> (7-counter)) & 1;
4
    if(currentValue == 1)
5
      PD_ODR |= (1<<MOSI);
6
    else
7
      PD_ODR &=~(1<<MOSI);

kann man übrigens auch kürzer haben:
1
  uint8_t mask;
2
  for(mask = 0x80; mask > 0; mask >>= 1){
3
    if(data & mask)
4
      PD_ODR |= (1<<MOSI);
5
    else
6
      PD_ODR &=~(1<<MOSI);

: Bearbeitet durch User
von Max M. (maxmicr)


Lesenswert?

Vielen Dank für die schnellen Antworten! Gute Nacht :)

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.