Hallo alle :)
ich steh gerade vor einer Wand und komme nicht weiter.
Falls irgendwem unklar ist, was ich im folgenden Text meinen könnte,
dann bitte nachfragen ^^
Ich habe einen mega8, der mittels Timer-Interrupt sehr genau die Zeit
hochzählt. Jede Sekunde wird dieser ausgelöst.
Nach x Minuten wird der Wert auf einen EEPROM geschrieben, das passiert
alles in der Interrupt-Routine.
Der mega8 wertet zusätzlich noch ein paar Ports aus und kommuniziert
ganz simpel über 2 Ports mit einem anderen mega8. Diese 2 Ports sind
PB.4 und PB.5 (SCK und MISO).
PB.5 vom 1. mega8 wird auf PB.4 vom 2. mega8 ausgewertet. Und andersrum
genauso.
Kommt also auf PB.4 ein high, wird so lange in eine Programmschleife
gesprungen, bis das ganze wieder low ist.
Das ganze habe ich mit einer Variablen gelöst
(if port high -> variable = 1, else port low -> variable = 0)
in der hauptschleife steht dann etwa:
if variable = 1, dann LED1 an, else LED2 an
Das Problem ist, es wird zwar erkannt, dass die Variable = 1 ist, aber
irgendwie bleibt immer LED1 an und LED2 leuchtet (nur im dunkeln
sichtbar) für einen sehr kurzen Moment auf
Das ganze passiert nicht mehr sobald ich den timer rausnehme.
Laut Datenblatt haben PB.4 und PB.5 nichts mit dem Timer bzw Interrupts
bzw COMPARE1A zu tun. Aber es muss irgendwie am Timer liegen.
Kann mir da jemand helfen? Ich seh gerade nicht mehr durch ... :(
(Ich schreibe alles in BASCOM, mit C/asm kenne ich mich nicht aus)
Vielen Dank für Hilfe!
PS: zur allgemeinen Verwirrung aller: ich habe auch probiert, zur
Portauswertung hinzuzufügen, dass Interrupts und COMPARE1A disabled
werden, sobald ein hi da ist (und enabled, sobald wieder ein lo da ist),
aber der Timer bleibt nicht stehen, genau wie die LED nicht umschaltet.
Reduziere die Interrupt Routine. Ich vermute, dass sie mehr tut, als
beabsichtigt war. Wenn Du Schrittweise Code entfernst, wirst DU
irgendwann an den Puntk kommen, wo das Reset-Problem verschwindet. Der
gerade entfernet Code ist dann warscheinlich die Problemursache.
Wie hast DU das mit dem 1 Sekunden-Takt gemacht? Soweit ich weiß ist
keiner der Timer imstande, einen Interrupt pro Sekunde auszulösen (mit
einer Taktfrequenz im Mhz Bereich).
Vermutlich zahlst Du die Interrupt, und wenn genug zusammengekommen
sind, dass eine Minute rum sein müsste, dann fängst DU an zu speichern
und zu kommunizieren.
bedenke, dass der Interrupt während dieser Zeit nicht ausgeführt wird.
Wenn die Interruptroutine länger dauert, als das Intervall zwischen zwei
Interrupts., wird die Uhr ungenau laufen.
Aber das ist momentan wohl nicht deine Haupt-Sorge.
(ich hab meine login-Daten gerade nicht im Kopf, deswegen schon wieder
als Gast ...)
Hallo Stefan!
So sieht der Timer aus: (der code ist nicht 100% exakt, z.b. bei den
LEDs und auch die DIMs für die Variablen fehlen, sollte aber dennoch
erkennbar sein)
die sub für den interrupt sieht so aus (ebenfalls als integer
definiert):
1
sec_cnt:
2
incr time_measure
3
4
if time_measure = 1 then
5
time_measure = 0
6
toggle LED1 'LED blinkt wenn interrupt auslöst
7
end if
so. nun passiert folgendes:
die LED1 blinkt
LED 2 geht an, wenn ich pinb.5 hi setze
aber der timer bleibt nicht "stehen", bzw es werden weiter interrupts
ausgelöst
der timer sollte ziemlich exakt jede sekunde auslösen
später werden innerhalb sec_cnt dann noch die minuten gezählt und bei 5
vollen minuten werden wieder compare1a und die interrupts disabled und
auf den eeprom geschrieben, danach werden die beiden sachen wieder
enabled.
auf meiner bisherigen schaltung funktioniert das bisher bestens.
dort wurden lediglich 2 ADC-Ports ausgelesen und sobald ein wert
unterschritten wurde, wurden keine sekunden mehr gezählt und es gingen 2
rote LEDs an. Die wurden grün und es wurde weitergezählt, sobald der
wert für den ADC wieder überschritten wurde.
diesmal habe ich noch ein paar mehr ports auszuwerten, einmal ist es ein
taster, und der rest sind hi/low-signale.
ich verstehe nicht, warum die interrupts weiter auslösen. müssen die in
sec_cnt disabled werden und nicht in der hauptschleife?
das hatte ich gestern auch probiert, hat aber irgendwie keinen
unterschied gemacht ... :/
danke für hilfe!
(achja, meine shift-taste ist nicht defekt, lol) ;)
so, also wie es scheint, darf in der hauptschleife keine Auswertung
stehen, die variablen ändert
bei mir funktioniert es nur, wenn die variablen in der vom Interrupt
ausgelösten sub geändert werden und in der hauptschleife die auswertung
geschieht
(z.b. wenn variable = 1 -> LED an)
ich weiss nicht, ob das tatsächlich so ist, aber nachdem ich die
variablen in sec_cnt setze und dort die ports abfrage, klappt alles
wieder ...
die interrupts und compare1a zu disablen hab ich bisher nicht probiert,
aber da es im alten projekt geklappt hat, müsste es auch hier
funkionieren
Nik schrieb:> und bei 5> vollen minuten werden wieder compare1a und die interrupts disabled und> auf den eeprom geschrieben
Diese Strategie musst du noch mal überdenken. Wenn du immer die gleiche
Stelle im EEPROM beschreibst, ist nach 347 Tagen der 100000ste
Schreibvorgang - damit endet die garantierte Anzahl der möglichen
Schreibzyklen lt. Datenblatt.
hey Matthias :)
ja, da gibt's 2 Möglichkeiten ... entweder wird der EEPROM regelmässig
getauscht (das Ding zählt Betriebsstunden von Lampen, die dann ebenfalls
getauscht werden müssen) oder man schreibt's an eine andere Stelle im
EEPROM.
Da ich aber nicht weiss, wie ich das realisieren könnte, vorallem beim
Einschalten des Gerätes weiss der mega8 ja erst mal nicht, welchen
EEPROM er nun vor sich hat (z.B. nach Tausch) und ab welcher Stelle er
lesen müsste, seh ich noch keine Lösung und da hab ich auch keine
Vorstellung :/
Vorsicht beim automatisierten Schreiben ins EEPROM.
Ein kleiner Fehler, schon beim Systemtest und das Teil ist hinüber.
Überlege mal, ob es wirklich nötig ist 1 Mal pro Sekunde ins EEPROM zu
schreiben.
Wenn ich ein System programmiere, das unbedingt "nachtragend" sein muss,
so spendiere ich dem Prozessor einfach einen großen Kondensator mit
verlustarmer Diode und eine Spannungsüberwachung. Das ist recht einfach,
allerdings geht dabei ein Pin drauf. Dann kann ich meinen Kram im RAM
machen und sichere nur im "Notfall". Restauration natürlich immer beim
Einschalten. Der Strom, der den Prozessor stützen tut ist nicht
sonderlich hoch, weshalb sich die Größe des Stützkondensators auch in
Grenzen hält.
@Spess: ah danke, da guck ich mal rein :)
@amateur: es wird auch nicht jede Sekunde geschrieben, sondern das
geschieht alle 5 Minuten bisher :)
Pro Sekunde zähle ich den Sekundenzähler 1 hoch und mach dann die
Port-Abfragen. Bei 300 wird dann angehalten und geschrieben.
Die "Lebensdauer" wäre also irgendwo bei 345 Tage, wenn ich von 100k
Zyklen ausgehe.
über diese Spannungsüberwachung hab ich auch schon nachgedacht, aber
leider hab ich auch nirgends mehr Pins frei an den beiden mega8
wie gesagt, ich bin kein studierter Entwickler, muss es aber trotzdem
irgendwie schaffen ^^;