Forum: Mikrocontroller und Digitale Elektronik ATmega1284P 6tes Bit toggelt von alleine


von Andreas H. (heilinger)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe seit längerem ein Problem mit meinem ATmega1284P. Ich hatte 
dieses Problem schonmal erklärt 
TitelBeitrag "ATmega1284P 6tes Bit wird gelöscht"]], 
jedoch nicht den Ursprung des Problems gefunden und möchte einen neuen 
Anlauf starten.

Kurze Erklärung, für diejenigen die sich den alten Thread nicht 
durchlesen wollen.

Ich habe eine Flowregelung für ein Proportionalventil programmiert, die 
unregelmäßig springt. Ich habe ein Tool, um mir 4 Variablen in Echtzeit 
auf dem PC ausgeben zu lassen. Dort erkenne ich, dass aus irgendeinem 
Grund das 6. Bit in Variablen gelöscht und auch wieder gesetzt wird.

Anhand eines bildlichen Beispiels möchte ich dies erklären:
Das Bild im Anhang zeigt die springende Variable, die in der Funktion an 
3 verschiedenen Stellen an den PC gesendet wird. Die x-Achse ist in 
Millisekunden dargestellt. In diesem Takt läuft auch mein Interrupt 
(1kHz), der die Funktion aufruft.
1
    u8_SendTX0[1] = (Tu8) ((u16_PWMAir10bit64fach)    & 0xFF);         //low Byte
2
    u8_SendTX0[2] = (Tu8)(((u16_PWMAir10bit64fach)    & 0xFF00) >> 8); //high Byte
3
4
  if (u16_ADD_ & 0x8000)                                             // PWM - verkleinern
5
  {
6
    if (u16_PWMAir10bit64fach > (IFLOW_PWMIN - u16_ADD_))
7
      u16_PWMAir10bit64fach = u16_PWMAir10bit64fach + u16_ADD_;
8
    else
9
      u16_PWMAir10bit64fach = IFLOW_PWMIN;
10
  }
11
  else                                                               // PWM - vergroessern
12
  {
13
    if (u16_PWMAir10bit64fach < (IFLOW_PWMAX - u16_ADD_))
14
      u16_PWMAir10bit64fach = u16_PWMAir10bit64fach + u16_ADD_;
15
    else
16
      u16_PWMAir10bit64fach = IFLOW_PWMAX;
17
  }
18
19
    u8_SendTX0[3] = (Tu8) ((u16_PWMAir10bit64fach+1)   & 0xFF);         //low Byte
20
    u8_SendTX0[4] = (Tu8)(((u16_PWMAir10bit64fach+1)   & 0xFF00) >> 8); //high Byte
21
22
  u16_DummyFlowAir = PWM_MAX - (u16_PWMAir10bit64fach / 64);
23
24
  if (u8_AIRVersorgungOK == 1)
25
    OCR1A = u16_DummyFlowAir;                                        //Anpassung des AIR-PWM-Signals, OCR1A = 1023 bedeutet PWM aus
26
  else
27
    OCR1A = PWM_MAX;                                                 //Prop-Ventil schließen, damit kein Gas zurück in ZGV
28
29
    u8_SendTX0[5] = (Tu8) ((u16_PWMAir10bit64fach+2)      & 0xFF);          //low Byte
30
    u8_SendTX0[6] = (Tu8)(((u16_PWMAir10bit64fach+2)      & 0xFF00) >> 8);  //high Byte


Das Array u8_SendTX0 sende ich an den PC. Im Bild im Anhang seht ihr nun 
die Variable "PWMAir10bit64fach" 3 mal abgebildet:

in grün, dort wo sie in u8_SendTX0[1+2] geschrieben wird
in blau, dort wo sie in u8_SendTX0[3+4] geschrieben wird
in rot,  dort wo sie in u8_SendTX0[5+6] geschrieben wird

Der oben gepostete Code zeigt alle Stellen, in denen die lokale Variable 
"PWMAir10bit64fach" vorkommt. Die Funktion wird aus einem Interrupt 
aufgerufen, kann also nicht durch einen Interrupt-Aufruf gestört werden.

Im Bild sieht man nun, dass die Variable an den beiden später 
aufgenommenen Stellen deutlich fällt und wieder steigt, und zwar von ca. 
27300 auf 19100 und zurück. Dies entspricht genau dem Löschen und wieder 
Setzen des 6. Bits im höherwertigen Byte der Variable.

Dieses Phänomen kommt unregelmäßig bis gar nicht vor und ist daher 
schwer zu reproduzieren. Da mein Kollege und ich keinen Fehler in der 
Software finden konnten, haben wir uns mal die 5V-Spannungen am uC mit 
einem scope angeschaut, siehe Bild2 im Anhang.

Dort sind Spannungsspitzen zu erkennen, die mit dem PWM-Signal des 
Proportionalventils wandern. Das PWM-Signal hat eine Frequenz von ca. 
20kHz. Wie stark die Spannungsspitzen sind, möchte ich noch nicht ganz 
beurteilen, da ich mir mit dem jetztigen Messaufbau evtl. HF-Störungen 
eingefangen haben könnte.
Die Schaltung, mit der das Ventil angesteuert wird, seht ihr in Bild3.
Das RC-Glied am Portpin haben wir hinzugefügt, um steilere Flanken am 
PWM-Signal zu erzeugen. Kann es aber sein, dass bei leerem C der Strom 
auf ca. 200mA ansteigt (knapp. 4V zwischen Portpin und Transitor) und 
dadurch den uC so sehr belastet, was den Spannungseinbruch erzeugt. Wie 
gesagt, die Spannungsspitzen wandern mit dem PWM-Signal. Ich habe zwar 
die Fuse Brown-out-detection = 4,3V gesetzt und der uC wird nicht 
geresettet, allerdings sehe ich im Datenblatt unter 26.2, dass der uC 
bei 20Mhz mindestens 4.5V brauch, um sicher zu arbeiten.
Dazu kommt noch, dass der Portpin für die Ventilansteuerung PD5 ist, 
also der 6. Pin an Port D.

Nun meine Frage, kann eine zu hohe Strombelastung an einem Portpin dazu 
führen, dass intern ein einzelnes Bit gelöscht wird?

Leider bekomme ich den Fehler nicht reproduziert, sonst würde ich das 
gleiche ohne den C nochmals ausprobieren.

von Uwe (Gast)


Lesenswert?

Mach doch einfach mal R1 raus und guck ob das problem noch da ist.

von Andreas H. (heilinger)


Lesenswert?

Wenn ich R1 rausmache, wird das Ventil auch nicht mehr angesteuert und 
somit läuft die Flowregelung auch nicht mehr bzw. läuft an nen Anschlag.
Außerdem hatte ich ja erwähnt, dass eine Reproduzierbarkeit quasi 
unmöglich ist und ein Vergleich mit und ohne elektronischem Bauteil 
daher sehr schwer wird.
Ich will erstmal nur wissen, ob ein solches Problem generell durch eine 
zu hohe Last am Portpin entstehen kann und ob es nicht Zufall ist, dass 
genau ein 6. Pin eines Ports betroffen ist und auch das 6. Bit einer 
Variablen springt.

von Willi (Gast)


Lesenswert?

Andreas H. schrieb:
> Nun meine Frage, kann eine zu hohe Strombelastung an einem Portpin dazu
> führen, dass intern ein einzelnes Bit gelöscht wird?

Ja, das geht. Man kann sogar den ganzen Prozessor damit löschen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Andreas H. schrieb:
> und ob es nicht Zufall ist

Der Zufall zeigt, das bei den meisten vermuteten "µC-defekten" sich 
zufällig doch herausstellt, dass die Sotware schuld war...

von Andreas H. (heilinger)


Lesenswert?

Läubi .. schrieb:
> Der Zufall zeigt, das bei den meisten vermuteten "µC-defekten" sich
> zufällig doch herausstellt, dass die Sotware schuld war...

wie gesagt, davon bin ich ja auch am Anfang ausgegangen. Aber so müsste 
der Software-Bug sich in diesem Teil befinden:
1
  if (u16_ADD_ & 0x8000)                                             // PWM - verkleinern
2
  {
3
    if (u16_PWMAir10bit64fach > (IFLOW_PWMIN - u16_ADD_))
4
      u16_PWMAir10bit64fach = u16_PWMAir10bit64fach + u16_ADD_;
5
    else
6
      u16_PWMAir10bit64fach = IFLOW_PWMIN;
7
  }
8
  else                                                               // PWM - vergroessern
9
  {
10
    if (u16_PWMAir10bit64fach < (IFLOW_PWMAX - u16_ADD_))
11
      u16_PWMAir10bit64fach = u16_PWMAir10bit64fach + u16_ADD_;
12
    else
13
      u16_PWMAir10bit64fach = IFLOW_PWMAX;
14
  }

Ich will ja auch gar nicht davon reden, dass der uC defekt ist oder nen 
Fehler hat. Ich will nur wissen, ob eine zu hohe Last an einem Pin einen 
Spannungseinbruch verursachen kann (wie das aufgenommen scope-Bild auch 
zeigt) und dadurch der uC unkontrolliert arbeitet.

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.