Hallo Gulliver,
dein im letzten Beitrag angehäntes Programm sieht schon anders aus, als das zuvor gepostete.
Das hier wird Probleme geben:
Aus einer ISR muss man mit reti rausgehen.
Du holst "akku" vom Stack, ohne da etwas zuvor abgelegt zu haben. Da sich der Controller auch beim Einsprung in die ISR (Einsprungadresse), die Rücksprungadresse im Hauptprogramm auf dem Stack ablegt, stimmt der Stackpointer nicht mehr und es kommt sofort zum "Absturz" deines Programms.
Eine ISR macht dann Sinn, wenn du das ADC Ergebnis sofort in der ISR verarbeitest. In deinem Fall also dort in das Port-Register kopierst.
Du solltest hier auch nicht "single conversion" verwenden, sondern den "free running mode" verwenden. Die Initialsierung des ADC machst du vor der Hauptschleife einmalig, auch diesen nur einmalig starten. Im hauptprogramm kannst du dann beliebige Sachen erledigen. Die Ausgabe des ADC Ergebnisses am Port erledigt dann die ISR.
Wenn du das ADC Ergebnis im Hauptprogramm verarbeiten möchtest, und dies nicht zeitkritisch ist, dann könntest du die in der ISR das Ergebnis auch in einer Variablen zwischenspeichern. Diese Variable kannst du dann im Hauptprogramm verarbeiten, dann wenn mal Zeit ist. In dieser steckt dann immer das letzte ADC Ergebnis. Alternativ kannst du auch einfach das Interruptanforderungsflag im Verlauf des Hauptprogramm ab und zu mal pollen und dir ADCH "holen".
In der ISR musst du ggf. noch darauf achten, dass das Statusregister SREG gesichert wird, zum Beispiel auf dem Stack (push, pop).
Dirk
EDIT:
Interurpts gibst du normalerweise nur einmal global frei (sei), nicht in der Hauptschleife. (Es sein denn du schaltest vorher Interrupts aus bestimmten Gründen aus (cli)).
dein im letzten Beitrag angehäntes Programm sieht schon anders aus, als das zuvor gepostete.
Das hier wird Probleme geben:
Code:
ADCISR:
out PORTB, akku
[COLOR=#800000][B]pop akku ret[/B][/COLOR]
reti
Aus einer ISR muss man mit reti rausgehen.
Du holst "akku" vom Stack, ohne da etwas zuvor abgelegt zu haben. Da sich der Controller auch beim Einsprung in die ISR (Einsprungadresse), die Rücksprungadresse im Hauptprogramm auf dem Stack ablegt, stimmt der Stackpointer nicht mehr und es kommt sofort zum "Absturz" deines Programms.
Eine ISR macht dann Sinn, wenn du das ADC Ergebnis sofort in der ISR verarbeitest. In deinem Fall also dort in das Port-Register kopierst.
Du solltest hier auch nicht "single conversion" verwenden, sondern den "free running mode" verwenden. Die Initialsierung des ADC machst du vor der Hauptschleife einmalig, auch diesen nur einmalig starten. Im hauptprogramm kannst du dann beliebige Sachen erledigen. Die Ausgabe des ADC Ergebnisses am Port erledigt dann die ISR.
Wenn du das ADC Ergebnis im Hauptprogramm verarbeiten möchtest, und dies nicht zeitkritisch ist, dann könntest du die in der ISR das Ergebnis auch in einer Variablen zwischenspeichern. Diese Variable kannst du dann im Hauptprogramm verarbeiten, dann wenn mal Zeit ist. In dieser steckt dann immer das letzte ADC Ergebnis. Alternativ kannst du auch einfach das Interruptanforderungsflag im Verlauf des Hauptprogramm ab und zu mal pollen und dir ADCH "holen".
In der ISR musst du ggf. noch darauf achten, dass das Statusregister SREG gesichert wird, zum Beispiel auf dem Stack (push, pop).
Dirk
EDIT:
Interurpts gibst du normalerweise nur einmal global frei (sei), nicht in der Hauptschleife. (Es sein denn du schaltest vorher Interrupts aus bestimmten Gründen aus (cli)).