Gut, die Unterlagen hab' ich alle in der Firma, hier bin ich eh hilflos.
bis morgen dann auch
kannst du laut sagen. Wie gesagt, morgen nehme ich mir nix vor. (Schreib jetzt noch kurz von daheim, weil es mich ned loslässt!)
Zu deiner Frage: Wenn es mal fertig läuft kommt der Strobe relativ schnell (so ein paar ms Abstand). Im Moment kommt er dann, wenn ich sage, dass er kommen soll. Also durchaus mit mehreren Sekunden dazwischen.
Mir ist noch was eingefallen, was ich schreiben wollte:
Durch die Standardbelegung von IRCON0 mit lauter 0en wird IR 4 so konfiguriert, dass er auf negative Flanke triggert! Und das Problem kommt auch, wenn er nach dem zweiten Byte eine negative Flanke hat - wie ich jetzt weiß. Ich habe nur nie eine Kombination versucht, die nach dem ersten Byte von high auf low im 8. Bit wechselt... Deshalb waren die anderen Bytes 'beliebig'. Nachher ist man halt immer gescheiter, gell.
Habs jetzt auch mal mit so einer Abfangschleife (in der ISR) versucht:
hat aber leider auch nix gebracht, kommt trotzdem noch zweimal...Code:if (IRCON & 0x10) { IRCON &= 0xef; return; } else { //der ganze switch auf den counter }
Schönen Abend und bis morgen
Gut, die Unterlagen hab' ich alle in der Firma, hier bin ich eh hilflos.
bis morgen dann auch
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Hallo Robert,
ich kann es selber noch gar nicht fassen, aber es geht!
Es ist tatsächlich so, dass der externe Interrupt 4 bei einer negativen Flanke an P3.7 den Request auslöst.
Und jetzt weiß ich auch, warum meine Abfrage am Anfang der ISR nix gebracht hat (s. gestern abend)...
In dem Testprogramm, das ich wieder verwendet habe, hatte ich testweise den Strobe auf einen anderen Interruptkanal gelegt. Das habe ich aber gestern abend übersehen und die Leitung nicht umgesteckt. Das heißt, er hat einen Request ausgelöst, nur war leider an der Stelle, wo normalerweise der IR-Vektor steht ein NOP. Also ist er das ganze Memory durchgelaufen, bis er auf den nächsten Befehl gelaufen ist - und das war wie es der Zufall so will genau meine TriggerISR...
Jetzt habe ich den Strobe wieder auf den Interrupt-Kanal gelegt, wo er hingehört und meine ISR angepasst - und es geht!!
Ich poste dir jetzt hier nochmal eben meine ISR. Wenn du willst kann ich dir später auch gerne nochmal mein komplettes Programm posten - hat sich doch noch etwas geändert - wenn ich die Änderungen übernommen und getestet habe.
Meine (Test-)ISR:
Puh, das war eine schwere Geburt. Aber sie ist geschafftCode:void TriggerISR() interrupt 9 { P0_DATA &= 0xf8; if (IRCON0 != 0x8) { IRCON0 &= 0x8; } else { switch (counter) { case 0: time1 = P3_DATA; //get LSB of time if (time1 == 0) { P0_DATA |= 1; } else { if (time1 == 2) { P0_DATA |= 2; } } break; case 1: time2 = P3_DATA; //get 2nd byte of time /*if (time1 > 127 && error == 1) { error = 0; counter--; }*/ if (time2 == 0) { P0_DATA |= 0x3; } else { if (time2 == 1) { P0_DATA |= 0x4; } } break; case 2: time3 = P3_DATA; //get MSB of time if (time3 == 0) { P0_DATA |= 0x1; } else { if (time3 == 13) { P0_DATA |= 0x7; } } break; case 3: phase = P3_DATA; //get phase information if (phase == 0) { P0_DATA |= 0x6; } else { if (phase == 128) { P0_DATA |= 0x1; } } break; case 4: switch (P3_DATA) { case 0: usePhase = 0; //-> phase ignored mainc = 0; //use serial contactors break; case 1: usePhase = 1; //-> phase important mainc = 0; //use serial contactors break; case 2: usePhase = 0; //-> phase ignored mainc = 1; //use main contactor break; case 3: usePhase = 1; //-> phase important mainc = 1; //use main contactor break; default: break; } break; default: break; } counter++; IRCON0 = 0; //reset IR-Bit of trigger } }
Wie sagt man englisch so schön "You're a star!". Soll heißen, nochmal vielen vielen vielen Dank für deine Hilfe, ohne dich wäre ich glaube ich in 2 Wochen immer noch dagesessen und hätte den Fehler gesucht.
Viele Grüße nach Wien und eine schöne Restwoche (is ja eh nimmer lang )
Michael
Na, das hört man doch gerne. Du hast jetzt wahrscheinlich in den paar Tagen mehr über Controller und Feinheiten gelernt als sonst in einem halben Jahr.
Da sieht man auch eine Tücke in der Zusammenarbeit Compiler/Controller:
Der Compiler läßt unbenutzen Speicher auf Null --> Der Controller versteht Null als "NOP", läuft durch, findet irgendwas oder nicht, läuft über und fängt wieder bei Null an und dann find' er sicher was (meist INIT)
Fachmännisch sagt man da: "the result is undetermined & unpredictable"
Tip: unbenutzte ISR-Vectoren immer mit RETI belegen
Auf eine Gefahr möcht ich dich noch hinweisen: wenn der counter auch nur einmal aus dem Tritt kommt, egal warum, findet er nie wieder nach Hause und keiner merkt es. (Brown out, Peaks etc.)
Ich weiß nicht, wie heikel die Gerätefunktion ist ?
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Das kannst du aber laut sagen! Soviel wie ich über den Controller mittlerweile gelernt habe hätte mir wirklich niemand beibringen können - zumindest nicht nicht in 2 Tagen...Du hast jetzt wahrscheinlich in den paar Tagen mehr über Controller und Feinheiten gelernt als sonst in einem halben Jahr.
Zu den unbenutzten IR-Vektoten: Meinst du tatsächlich, ich soll für jeden möglichen Interrupt eine ISR schreiben, die nichts macht? Könnte man nicht auch 'einfach' an die Stelle der NOPs lauter RET schreiben? RETI bräuchte ich ja nur, wenn ich wirklich in eine ISR verzweige, weil die ja dann noch zusätzlich Info in den Stack legt, oder macht er das schon beim Jump?
Wie bringe ich ihn denn dazu lauter RET(I) an die Stellen im Speicher zu schreiben?
Hm, wie heikel ist die Gerätefunktion. Es handelt sich um ein Steuergerät für Starkstromtests an Telekommunikationsanlagen. Sprich der User stellt an einem Rechner ein führe diesen und jenen Test durch. Daraufhin übermittelt der Rechner dem Steuergerät die erforderlichen Daten (zu benutzenden Widerstand, Spannung etc.) und überwacht anschließend den Test, der von dem Steuergerät gesteuert wird.
Das Problem daran ist, dass er den Test überwacht, indem er selbst die Zeit misst und davon ausgeht, dass der Controller hin ist, wenn mehr als 1s länger die Spannung anliegt als es der Test verlangt. Eine andere Überwachungsmöglichkeit ist mir leider nicht eingefallen.
Was ich theoretisch machen könnte wäre, dass ich in den default-Zweig des switches in der ISR den counter wieder auf 0 setze und dem Rechner einfach nie anzeige, der Test wäre beendet, dann beendet er ihn. Ist wahrscheinlich gar keine schlechte Idee, danke für den Tipp!
Viele Grüße
Michael
Hi,
NOP:
Es ist schwer, einen Prozessor zu helfen, der so richtig von Irgendwo ins Nirwana springt. Da bleibst du übrig.
ISR-Dummies:
Manche Compiler machen das selbst, indem sie die Vector-Tabelle prophylaktisch mit RETI füllen. Dadurch verbrauchen sie keinen zusätzlichen Platz.
Du kannst aber eine Sammel-ISR schreiben, die die NOPS vorher zusammensammelt und halt nix als RETI macht. Wichtig wär nur, daß er nicht wie im vorliegenden Fall eine FALSCHE ISR anspringt, das war ja das tödliche.
Überwachung: Timeout ist immer gut.
Also, Michael, keep codin' und wenn wieder was ist, rühr' dich, und wenn ich nix weiß, aufmunternd auf die Schulter klopfen kann ich immer !
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Hallo Robert,
werde mich dann mal mit der Sammel-ISR versuchen. Schade eigentlich, dass Keil das nicht automatisch macht. Eigentlich finde ich die Software ziemlich gelungen.
Dann würde ich mal sagen, wir können unbesorgt diesen Thread beschließen
Wird - leider - für ne Zeit lang mein letztes hardwarenahes Programmieren gewesen sein. Werde aber schaun, dass ich in die Richtung weiter machen kann, weil mir das echt total fasziniert und mir auch riesigen Spaß macht.
In diesem Sinne nochmal vielen Dank und hoffentlich bis bald (das würde heißen, dass ich wieder Probleme mit nem Controller habe, deswegen )
Viele Grüße
Zitat von Ampfing
Lesezeichen