Forum: Mikrocontroller und Digitale Elektronik Seltsame Probleme die sporadisch auftreten


von Dirk F. (dirkf)


Lesenswert?

Hallo,
XC8 compiler PIC18F46Q71.

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
volatile unsigned char mode;          // Modus Ansteuerung MOSFET
2
3
//  Tabelle MOSFET Taktung------------------
4
 const char signal[8][12] = {
5
 {0,0,0,0,0,0,0,0,0,0,0,0},     // Mode 0  = Aus
6
 {1,1,1,1,1,1,1,1,1,1,1,1},     // Mode 1  = 200% U-Nenn 2xÜbererregung
7
 {1,0,1,0,1,0,1,0,1,0,1,0},     // Mode 2  = 100% U-Nenn Halbwelle       
8
 {1,0,0,1,0,0,1,0,0,1,0,0},     // Mode 3  = 75% U-Nenn          
9
 {1,0,0,0,1,0,0,0,1,0,0,0},     // Mode 4  = 50% U-Nenn  
10
 {1,0,0,0,0,0,1,0,0,0,0,0},     // Mode 5  = 34% U-Nenn  
11
 {1,0,0,0,0,0,0,0,0,0,0,0},     // Mode 6  = 17% U-Nenn 
12
 {1,1,0,0,1,1,0,0,1,1,0,0}      // Mode 7  = 100% U-Nenn  Vollwelle
13
 };
14
 
15
int main(void)
16
{
17
18
while (1)
19
    { 
20
    mode = slave_in[3] & 0x07;          // Neuen Wert vom Master
21
        
22
    // BYP_SCO1_LAT  = (mode>1);    // Fehler
23
    if (mode>1) BYP_SCO1_LAT =1;    // kein Fehler
24
    else        BYP_SCO1_LAT =0;
25
    }
26
}
27
28
29
// Im Timer Interrupt jede 10 ms:
30
31
        // Nächsten Wert für Takt IGBT aus Array holen
32
        MCU_SW1_LAT = signal[mode][pulse_pos]; 
33
        pulse_pos++;                        // Nächster Wert aus Array
34
        if (pulse_pos == 12) pulse_pos = 0; // Array Ende, dann von Anfang

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

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.

Beitrag #7897433 wurde vom Autor gelöscht.
von Dirk F. (dirkf)


Angehängte Dateien:

Lesenswert?

Peter D. schrieb:
> auf andere Bits im selben
> Byteregister haben.

Könnte sein. Beide liegen im selben Port:

von Falk B. (falk)


Lesenswert?

Dirk F. schrieb:
> 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; else BYP_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
    else        BYP_SCO1_LAT =0;
7
    sei();  // Interrupts freigeben, muss an PIC angepasst werden

Siehe Interrupt.

von Falk B. (falk)


Lesenswert?

Dirk F. schrieb:
>> auf andere Bits im selben
>> Byteregister haben.
>
> Könnte sein. Beide liegen im selben Port:

Da hast du dein Problem.

https://www.mikrocontroller.net/articles/Interrupt#Atomarer_Datenzugriff

von Dirk F. (dirkf)


Lesenswert?

Falk B. schrieb:
> Wie sieht denn der Fehler aus?

Normal wird jede zweite Halbwelle eingeschaltet.
Im Fehler fehlt manchmal  eine Halbwelle   oder es werden zwei 
Halbwellen ohne Pause  nacheinander ausgegeben.

von Johann K. (klammerj)


Lesenswert?

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)

von Dirk F. (dirkf)


Lesenswert?

Johann K. schrieb:
> Neuere Modelle haben
> separate port und latch Register)

Der PIC18F46Q71  ist ein neues Modell.
Es geht hier aber nur ums schreiben ins LATCH.

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.