Ich steuere ein MOSFET jede 10 ms im Timer Interrupt an.
Es kommt zeitweise zur falschen Ansteuerung im mode=2 (Zeile mit //Fehler).
Gemessen mit Oszilloskop.
Habe dann den code geändert (2 Zeilen ohne Fehler)
Nach der Änderung keine Fehler mehr.
Aber ich verstehe den Grund nicht.
Oder kann es sein, dass in dieser Zeile
mode = slave_in[3] & 0x07;
der Interrupt zuschlägt und dann die Variable mode einen falschen Wert bekommt.
1
volatileunsignedcharmode;// Modus Ansteuerung MOSFET
Nun das eine ist ein Read-Modify-Write auf BYP_SCO1_LAT (nicht atomar),
Das andere sind 2 Zuweisungen ohne vorheriges Lesen (atomar).
RMW-Zugriffe auf IO-Bits können Seiteneffekte auf andere Bits im selben Byteregister haben.
Ich steuere ein MOSFET jede 10 ms im Timer Interrupt an.
Es kommt zeitweise zur falschen Ansteuerung im mode=2 (Zeile mit
//Fehler).
Gemessen mit Oszilloskop.
Wie sieht denn der Fehler aus?
Habe dann den code geändert (2 Zeilen ohne Fehler)
Syntaktisch korrekt, aber die Formatierung sollte man nicht so machen. Das sit schlecht lesbar und damit fehleranfällig. Wenn, dann so.
1
if(mode>1)BYP_SCO1_LAT=1;elseBYP_SCO1_LAT=0;
oder so
1
if(mode>1){
2
BYP_SCO1_LAT=1;
3
}else{
4
BYP_SCO1_LAT=0;
5
}
Nach der Änderung keine Fehler mehr.
Aber ich verstehe den Grund nicht.
Ich vermute, daß die Sequenz komplett atomar sein muss, damit sich deine Logik nicht verklemmt. Denn mode wird auch in deiner ISR verwendet. Eher so.
1
cli();// Interrupts sperren, muss an PIC angepasst werden
2
mode=slave_in[3]&0x07;// Neuen Wert vom Master
3
4
// BYP_SCO1_LAT = (mode>1); // Fehler
5
if(mode>1)BYP_SCO1_LAT=1;// kein Fehler
6
elseBYP_SCO1_LAT=0;
7
sei();// Interrupts freigeben, muss an PIC angepasst werden
Normal wird jede zweite Halbwelle eingeschaltet.
Im Fehler fehlt manchmal eine Halbwelle oder es werden zwei Halbwellen ohne Pause nacheinander ausgegeben.
Hast du schon versucht den mode Update auf den Sequenz Start zu Synchronisieren? (Die read-modify-write Probleme sind historisch, als die PICs zum lesen und schreiben nur ein Port Register hatten, und der externe Portzustand beim RmW in das Latch leckte. Neuere Modelle haben separate port und latch Register)