stm32f103 generelles Problem

Gast #4894129
Lesenswert?

1
....
2

3
  init_vs1053();
4
  vs_zl_buffer=0;
5
  vs_hellotest();
6
  wait;//1000ms
7

8
/**/
9

10
  SPI1->CR1 &=~(0b111<<3);//fast spi
11
  SPI1->CR1 |=  (3<<3);//fast spi
12
  
13
...

vs1053 wird initialisiert und spielt anschließend den vs1053-hello-code 
hörbar ab. Anschließend werden mp3-Dateien abgespielt.

Dann soll der spi-prescaler reduziert werden. Jetzt sind nicht nur die 
mp3s weg, auch der hellocode - obwohl zeitlich früher - wird nicht mehr 
abgespielt.

Wie kann das sein?

bei SPi2 geht es korrekt/presc==2, bei spi1 obiges Phänomen. Warum?
#4894446
Lesenswert?

1
  SPI1->CR1 &=~(0b111<<3);//fast spi
2
  SPI1->CR1 |=  (3<<3);//fast spi

Das sind zwei Schreibzugriffe. Vermutlich knallt der erste, fass die 
doch mal zu einem Zugriff zusammen.

Achtung: Taktumschaltung während einer SPI Transaktion kann auch aus 
anderen Gründen knallen, z.B. weil interne Teiler/Zähler überlaufen. So 
könnten auch unschöne Glitches entstehen.
Gast #4894558
Lesenswert?

Jim M. schrieb:
> Das sind zwei Schreibzugriffe.

Erstmal Danke für den Hinweis.

???
- vorhandener Wert in Bit-Folge soll geändert werden:
1. Bit-Folge auf Null setzen
2. Bit-Folge auf gewünschten Wert setzen

Wie schaffst du das in einem Schreibzugriff?

Das oben beeschriebene Problem ist geklärt. Lag daran dass die #defines 
zur Umstellung spi1/2 fehlerhaft waren.
 Spi2 läuft mit presc=clk/2 Spi1 nur mit clk/16. Da anderer Bus wäre 
logisch mindestens mit clk/4.

Ich werde das ganze jetzt mit dem la untersuchen.
(Firma: TU Darmstadt) #4894673
Lesenswert?

Jim M. schrieb:
> Trivialste Grundlagen der Programmierung:
>
> SPI1->CR1 = (SPI1->CR1 & ~(7<<3)) | (3<<3);
>
> Ein einzelner Read-Modify-Write Zyklus.

Das das als einzelner Zyklus implementiert wird, ist durch nichts 
garantiert. Ebenso werden die meisten Compiler die Formulierung in zwei 
Zeilen auch nichts anderes implementieren.
Gast #4894788
Lesenswert?

Uwe B. schrieb:
> Das das als einzelner Zyklus implementiert wird, ist durch nichts
> garantiert.

Doch, das ist dadurch garantiert, dass die gelesene/geschriebene 
Speicheradresse als volatile deklariert ist. Der Compiler muss hier 
genau einen Lese- und genau einen Schreib-Zugriff erzeugen.
Gast #4894817
Lesenswert?

grundschüler schrieb:
> sicher?
> da meckert nichts und es funktioniert auch...

Meine Lieblingsargumentation... Gleich dahinter kommen noch folgende:

- "gestern ging es aber noch!"
- "ich habe daran NICHTS gemacht/verändert"
- "so hat es aber bisher IMMER funktioniert"
- "wer braucht Abblockkondensatoren? Geht doch auch ohne!"
- "EAGLE ist MINDESTENS so gut wie Altium. Wenn nicht sogar besser!"
- usw., gibt noch eine ganze Menge

Übrigens:

Was du meinst ist folgendes: "Mein Compiler schluckt das weil GCC auch 
Binärzahlen versteht. Da ich aber ein guter Programmierer bin, schreibe 
ich meinen Code so, dass compilerspezifische Besonderheiten darin nicht 
unnötig vorkommen" :-)

--> in C verwendet man HEX. Ist ja eigentlich auch nichts anderes als 
Binär wenn man jeweils 4 Stellen zusammenfasst.

wenn man UNBEDINGT binär haben möchte (ich programmiere seit über 20 
Jahren C, habe es noch nie wirklich gebraucht):
1
#define B(x) ( \
2
  0##x >>  0 & 0001 | \
3
  0##x >>  2 & 0002 | \
4
  0##x >>  4 & 0004 | \
5
  0##x >>  6 & 0010 | \
6
  0##x >>  8 & 0020 | \
7
  0##x >> 10 & 0040 | \
8
  0##x >> 12 & 0100 | \
9
  0##x >> 14 & 0200 )

Uwe schrieb:
> Doch, das ist dadurch garantiert, dass die gelesene/geschriebene
> Speicheradresse als volatile deklariert ist. Der Compiler muss hier
> genau einen Lese- und genau einen Schreib-Zugriff erzeugen.

Sehe ich genauso.
#4895594
Lesenswert?

Uwe B. schrieb:
> Das das als einzelner Zyklus implementiert wird, ist durch nichts
> garantiert. Ebenso werden die meisten Compiler die Formulierung in zwei
> Zeilen auch nichts anderes implementieren.

Das sind Register und die sind volatile. Damit macht der Compiler 
jeden Lese- und Schreibzugriff ganz genau so wie Du ihn hinschreibst. 
Dies wird spätestens durch den GCC garantiert.

Deshalb wird der GCC bei der Zwei-Zeilen-Version immer zwei 
Schreibzugriffe machen, was bei Hardware Registern unerwünschte 
Nebenwirkungen haben kann.

Schau Dir selbst mal das Disassembly an.

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