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.