Hallo zusammen,
bei einem Projekt brauche ich einen analog comparator interrupt. Dazu
habe ich mir eine kleine Versuchsschaltung aufgebaut, die 2 Spannungen
vergleicht und einer LED zur Anzeige. Das Programm dazu steht unten.
Jetzt ist folgendes Problem aufgetreten, da wo der interrupt auslösen
sollte passiert nichts. Das interrupt flag im ACSR Register wird beim
ersten wechsel der Spannung gesetzt und bleibt danach gesetzt, die
interrupt routine wird aber nicht ausgeführt. Habe das ganze mit 2
atmega168pu-pa und 2 atmega8a-pu ausprobiert, immer mit dem selben
Ergebnis. Kann irgendjemand helfen?
;---------------Interrupt Analog Comperator------------------------------------------------------------------------------------------------------------------------
ertsmal Tip zum schreiben
für 0bxxxxxxx kannst du auch
(0<<ACD|0<<ACBG|1<<ACI|1<<ACIE|0<<ACIC|1<<ACIS1|0<<ACIS0)
macht den Text übersichtlicher
denn setze hier entsprechend reti's ein
statt RJMP nutze er JMP
.org 0x0000
rjmp RESTART
reti
reti
.
.
.
.org 0x002E
rjmp ANA_COMP
bis die Adresse 2E erreicht ist.
siehe Datenblatt S.62
John I. schrieb:> Jetzt ist folgendes Problem aufgetreten, da wo der interrupt auslösen> sollte passiert nichts. Das interrupt flag im ACSR Register wird beim> ersten wechsel der Spannung gesetzt und bleibt danach gesetzt, die> interrupt routine wird aber nicht ausgeführt. Habe das ganze mit 2> atmega168pu-pa und 2 atmega8a-pu ausprobiert, immer mit dem selben> Ergebnis. Kann irgendjemand helfen?Erstens :
1
.org0x002E
2
rjmpANA_COMP
macht man nicht. Es ist nicht dieselbe Adresse beim M8 und M168 und
es sollte auch nicht dasselbe Befehl sein (rjmp/jmp).
MEGA8:
0x010 rjmp ANA_COMP
MEGA88:
0x017 rjmp ANA_COMP
MEGA168:
0x002E jmp ANA_COMP
Dafur gibt es beim ATMEL so etwas wie:
.equ ACIaddr = 0x0010 ; Analog Comparator beim M8
und
.equ ACIaddr = 0x002e ; Analog Comparator beim M168
deswegen schreibt man:
1
.orgACIaddr
2
rjmpANA_COMP
Zweitens :
Irgendwelche Warteschleifen in der ISR sind ganz grosses NoNo.
Setze irgendein Flag in der ISR, den du in der MAIN prufen kannst
und das wars.
Drittens :
John I. schrieb:> main:> cbi PORTD, 0 ;led aus> in r16, ACSR> sbrs r16, 4 ;ueberspringe naechsten Schritt wenn bit 4 gesetzt ist> sbi PORTD, 0 ;led an>> rjmp main
So wie ich das sehe, muss deine LED, wenn einmal an, dauernd leuchten ?
ACI wird in der ISR zuruckgesetzt, LED wird in der ISR eingeschaltet
und nicht mehr ausgeschaltet (abgesehen von den 4 Takten in Main), aber
ich bezweifle, dass du das merken kannst.
> aber ich bezweifle, dass du das merken kannst.
Bei 8 MHz sehe ich tatsächlich nichts, bei 1 MHz kann ich gerade noch
einen Unterschied an der LED erkennen.
Ich bedanke mich schon mal herzlich für die schnellen Antworten.
@chris, retis wurden eingesetzt und rjmp gegen jmp getauschst, hat aber
leider keine Verbesserung gebracht.
@S. Landolt und I/O, out-Befehl geht nicht
@Marc Vesely, Mein Problem ist eher das die LED sofort nach ändern der
spannung an AIN1 ausgeht und demzufolge die interrupt routine nicht
ausgeführt wird. Und natürlich hatte ich für den atmega8 ein anderes
Programm.
Interessant ist warum die routine nicht abgearbeitet wird obwohl
interrupt flag gesetzt und interrupts global eingeschalten sind.
@ S. Landolt, habe gerade dein Programm getestet und es funktioniert :).
Da muss ich schauen wo der Fehler bei mir ist, vielen dank.
Achso und dort funktioniert der out-Befehl, da hab ich wahrscheinlich
irgendwie den Überblick verloren bei der Fehlersuche.
John I. schrieb:> da hab ich wahrscheinlich> irgendwie den Überblick verloren bei der Fehlersuche
Nein.
Du hattest einfach zu keiner Zeit einen Überblick (im Sinne des
Begreifens des Systems).
Und ich bin sicher: Du hast ihn auch jetzt noch nicht...
Nachtrag zu meinem Vorschlag:
Bei dem alten ATmega8 muss der Stackpointer, wie im ursprünglichen
Programm, explizit gesetzt werden.
> Und ich bin sicher: Du hast ihn auch jetzt noch nicht...
Das ist anzunehmen, wird sich aber mit der Zeit ändern, dafür gibt es ja
das Forum.
>> Bei dem alten ATmega8 muss der Stackpointer, wie im ursprünglichen>> Programm, explizit gesetzt werden.>> LOL.> Beim Mega168 nicht ?
Schon mal das Datenblatt gelesen? Nein, man muss nicht.
Alle Adressen(Register) die größer als 003F sind werden mit STS und
darunter mit OUT angesprochen. "REGISTERMAPPING"
Der OUT Befehl muss funktionieren da ACSR die Adresse 30Hex hat und
somit der OUT-Befehl massgebend ist.
John I. schrieb:> Interessant ist warum die routine nicht abgearbeitet wird obwohl> interrupt flag gesetzt und interrupts global eingeschalten sind.
wenn du das AVRstudio6 nutzt siehe Bild blaue Makierung entsprechend
ändern da sonst die INTS übersprungen werden
chris schrieb:> wenn du das AVRstudio6 nutzt siehe Bild blaue Makierung entsprechend> ändern da sonst die INTS übersprungen werden
Bild? Blaue Markierung? INTS übersprungen?
holger schrieb:>> LOL.>> Beim Mega168 nicht ?>> Schon mal das Datenblatt gelesen? Nein, man muss nicht.MWS schrieb:> Nein. Musst Du Datenblatt lesen.S. Landolt schrieb:> Was ist jetzt daran so lustig?
ATMEL:
"The Stack in the data SRAM must be defined by the program before any
subroutine calls are executed or interrupts are enabled. Initial Stack
Pointer value equals the last address of the internal SRAM and the
Stack Pointer must be set to point above start of the SRAM"
Selbst Atmel sagt, dass der SP gesetzt werden muss, ob der jetzt beim
Programstart zum Ende des RAMs oder ins Nirwana zeigt, ist eigentlich
egal.
Und nur weil sich Programm am Anfang befindet, heisst noch lange nicht,
dass der SP auch dorthin zeigt, wo er zeigen soll.
Ich gebe Ihnen Recht, wenn § restart im Wortsinne benutzt wird, das ist
aber hier und auch meistens sonst nicht der Fall.
Und lustig finde ich das Ganze noch immer nicht.
S. Landolt schrieb:> Beim ATmega168 steht der initial-value für SPH&SPL auf RAMEND.
Deswegen steht Ihr beim "P" vom Programmierer und ich bezweifle das
Ihr jemals bis zum "r" kommt.
Marc Vesely schrieb:> S. Landolt schrieb:>> Beim ATmega168 steht der initial-value für SPH&SPL auf RAMEND.>> Deswegen steht Ihr beim "P" vom Programmierer und ich bezweifle das> Ihr jemals bis zum "r" kommt.
Deine Argumentation wäre wohl anders gewesen, wenn du gewußt hättest,
daß die Register schon richtig stehen. Mag sein, daß du mit deinem "P"
recht hast, sehe ich aber hier nur als Ausrede. Schwach.
an Marc Veseley
Jetzt verstehe ich gar nicht mehr, worauf Sie eigentlich hinaus wollen,
ist mir aber letztlich auch egal.
Mein Anliegen war, John I. zu helfen, das scheint so zu sein - mir
reicht's.
I/O schrieb:> Deine Argumentation wäre wohl anders gewesen, wenn du gewußt hättest,> daß die Register schon richtig stehen. Mag sein, daß du mit deinem "P"> recht hast, sehe ich aber hier nur als Ausrede. Schwach.S. Landolt schrieb:> an Marc Veseley> Jetzt verstehe ich gar nicht mehr, worauf Sie eigentlich hinaus wollen,> ist mir aber letztlich auch egal.
Erst lesen, dann "argumentieren".
Marc Vesely schrieb:> Und nur weil sich Programm am Anfang befindet, heisst noch lange nicht,> dass der SP auch dorthin zeigt, wo er zeigen soll.
Als normaler (muss gar nicht so gut sein) Programmierer, stellt man
am Anfang sicher, dass alle Register genau die Werte haben, die man
auch möchte.
Vor allem SP und Index Register. Da wird gar nichts "vorausgesetzt"
und "normallerweise steht der SP auf RAMende und IndexRegister
müssten eigentlich genau dorthin zeigen".
Nach Ihrer Logik könnte der Compiler das auch beim M168/M328
wegoptimieren, tut der aber nicht, was glaubt Ihr warum ?
Dafür war mein LOL.
Wer es immer noch nicht versteht, soll sich lieber ein anderes Hobby
suchen.
Marc Vesely schrieb:> Dafür war mein LOL.
Ach so, Sie haben mich ausgelacht. Je nun, wenn Ihnen das etwas gebracht
hat...
Dem Fragesteller in seinem jetzigen Stadium hat es vermutlich nicht
geholfen.
Im Übrigen teile ich die Meinung nicht ganz; so wird es wohl seine
Gründe haben, dass es überhaupt Anfangswerte gibt, und dass Atmel diesen
für den Stackpointer bei den neueren Controllern sinnvoll setzt.
S. Landolt schrieb:> Ach so, Sie haben mich ausgelacht. Je nun, wenn Ihnen das etwas gebracht> hat...
Nein, ich habe niemanden ausgelacht.
Ich habe nur über etwas, was mir unlogisch schien, gelacht.
S. Landolt schrieb:> Dem Fragesteller in seinem jetzigen Stadium hat es vermutlich nicht> geholfen.
Ich glaube doch, denn: Was der Hänschen nicht lernt, lernt der Hans...
S. Landolt schrieb:> Im Übrigen teile ich die Meinung nicht ganz; so wird es wohl seine> Gründe haben, dass es überhaupt Anfangswerte gibt, und dass Atmel diesen> für den Stackpointer bei den neueren Controllern sinnvoll setzt.
Ja, nur hat ATMEL nirgendwo geschrieben, dass, wenn sich Programm auf
Adresse 0x00 befindet, SP automatisch auf Speicherende zeigen muss.
XMEGAs haben einen bit fur Hardware Reset aber MEGAs haben sowas (noch)
nicht.
Somit ist auch ein JMP nach 0x0000 nutzlos, Register- und Portinhalte
werden nicht verändert.
Aber mit einem Fehler im Loop, falsch berechnetem indirect jump o.ä.
ist man ganz schnell den FLASH raufgefahren und wieder bei 0x0000
angelangt.
In der Zwischenzeit hat man einen Port auf Ausgang gestellt, sollte
aber am Anfang Eingang sein, man verlässt sich halt auf ATMEL und
schon gibt es einen Kurzschluss.
Danach springt man ins Nirwana weil der SP nach deiner Meinung auf
Speicherende zeigen muss.
Danach... usw, usw.
Alles, was bei mir irgendwie mit der Aussenwelt zu tun hat, wird am
Anfang auf Eingang gestellt. Ebenso SP und Indexregister.
Da kann ATMEL in seinem DaBla schreiben, was er will.
Die paar Befehle tun bestimmt nicht weh.
Ich bin anderer Meinung; bei einem davongelaufenen Programm würde ich
die Ursache dafür finden wollen. Ich habe meine Erfahrungen, Sie die
Ihren. Wenn ich das Konzept richtig verstehe, müssten zu Programmbeginn
sämtliche SFRs gesetzt werden, sie könnten ja vom Amok laufenden
Programm verstellt worden sein (immer in der Hoffnung, dass dieses auch
wieder bei 0 aufsetzt).
Wie dem auch sein - ist doch aber alles noch lange kein Grund, uns
gegenseitig die Befähigung zum Programmieren abzusprechen.
Bei meinem Vorschlag für John I. habe ich eben die Initialisierung des
Stackpointers noch nachgetragen, als ich sah, dass er vielleicht das
Programm auch auf dem ATmega8 laufen lässt. Die Reaktion darauf
> LOL.> Beim Mega168 nicht ?
finde ich nach wie vor völlig unpassend; eine kurze Erläuterung statt
des LOL hätte uns dieses jetzige Hin&Her erspart.
Und was hat das alles noch mit der Eingangsfragestellung zu tun? Nichts
mehr, wie ich finde, und so wünsche ich allen eventuellen Mitlesern ein
schönes Wochenende.