mikrocontroller.net

Forum: Compiler & IDEs External Interrupt Atmega16


Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an alle,

ich versuche verzweifelt den externen interrupt des Atmega16 zu nutzen.
Mein Problem ist, das der interrupt an sich funktioniert, jedoch der 
Atmega ab und an danach einen reset macht. Scheint ein Problem mit der 
Rücksprungadresse oder der interruptroutine selbst zu sein. Derzeit 
toggle ich zum testen eine LED, wenn ein interrupt über int0 (Taster, 
über RC entprellt) erzeugt wird.

Hier meine config für den interrupt 0:
#include <avr/interrupt.h>
...
MCUCR |= ( (1<<ISC01) | (1<<ISC00));  //The rising edge of INT0 
generates an interrupt request.
GICR |= (1<< INT0);  //enable external interrupt 0
sei();        //global interrupt enable

Ich habe schon sehr sehr viel gegoogelt und hier im Forum gelesen und 
ich hätte gerne ein Beispielprogramm für den Atmega 16 welches den 
externen interrupt nutzt und keinen reset erzeugt.

Noch einige Fragen:

1. Wo muss die Interruptroutine stehen? Vor oder nach dem main()
2. Wie muss die Routine für den Atmega 16 aussehen
   ISR(INT1_vect) {...}
   SIGNAL(INT1_vect) {...}

   oder das hab ich auch noch gefunden

   #ifdef _GNUC_
   ISR(INT1_vect)
   #else
   interrupt [EXT_INT1] void ext_int1_isr(void)
   #endif
   {...}

Vieleicht hat jemand eine funktionierendes Testprogramm (in c#)

Viele Grüsse,
Jürgen

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juergen schrieb:

> Vieleicht hat jemand eine funktionierendes Testprogramm (in c#)

Seit wann gibt es einen C# Compiler für AVR :-)

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...


(Dein Problem ist wahrscheinlich gar nicht in dieser ISR zu suchen. Ich 
denke, du hast irrtümlich noch einen anderen Interrupt freigegeben, für 
den du keinen Handler hast)

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jürgen,

könntest Du den kompletten Source Code als Datei dranhängen ?

Gruß,
  Frank

Autor: Juergen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Frank,

ich habe meine main.c angehängt.

Das Programm blinkt nach dem Start mit LED1. Dadurch erkenne ich einen 
reset. Ansonsten wird mit dem external Interrupt LED2 getoggelt.

Vieleicht liegt der Fehler in der Initialisierung der seriellen 
Schnittstelle?

Gruß,
Jürgen

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 1. Wo muss die Interruptroutine stehen? Vor oder nach dem main()

Das ist egal.  Wichtig ist nur der richtige Name.

> 2. Wie muss die Routine für den Atmega 16 aussehen
>    ISR(INT1_vect) {...}
>    SIGNAL(INT1_vect) {...}

Für avr-gcc: Ersteres.  Das Zweite ist deprecated, wird aber (noch) als 
gleichwertig erkannt.

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Juergen schrieb:

> Hallo Frank,
>
> ich habe meine main.c angehängt.

... die ich mal etwas umgestaltet habe -  siehe angehängte Datei. Das 
funktioniert so bei mir.

Ich habe die USART Schnittstelle rausgenommen, um Fehler dort 
auszuschliessen. Kannst Du mal probieren und berichten, ob das so bei 
Dir stabil läuft ?

Grüße
  Frank

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
... und hier die Version mit USART wie sie bei mir läuft ...

Gruß,
  Frank

Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Frank,

so ich hatte eben Zeit deinen Code zu testen.

Hat leider nicht funktioniert. Ich sehe zwei Fehlerszenarien die 
scheinbar ohne Systematik auftreten, wenn ich nach dem Einschalten der 
Versorgungsspannung auf Taster 1 (=int0) drücke:

1. Fehler: Sobald der externe interrupt abgearbeitet ist erfolgt sofort 
der reset und die LED1 blinkt 10mal. :/

oder

2. Es passiert, dass ich den interrupt0 ausführen kann (d.h. die LED2 
blinkt kurz), danach passiert kein reset, und es geht auch kein weiterer 
int0 (d.h. kein erneutes blinken der LED2) mehr. Der Atmega hängt.

Wenn ich deinen code anschaue sehe ich, dass du das SREG sicherst. Das 
sollte aber vom GCC selbst übernommen werden.

Außerdem kommt bei mir beim kompilieren von
"ISR(SIG_UART0_RECV)" >>> misspelled signal handler

dass muss "ISR(SIG_UART_RECV)" heissen.


Jedenfalls hats nichts geholfen. Der externe interrupt bleibt ein 
Mysterium. Schade. :(

Sonst noch Vorschläge?

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juergen schrieb:
> Hallo Frank,
>
> so ich hatte eben Zeit deinen Code zu testen.
>
> Hat leider nicht funktioniert.

Schade ;-)

> Ich sehe zwei Fehlerszenarien die
> scheinbar ohne Systematik auftreten, wenn ich nach dem Einschalten der
> Versorgungsspannung auf Taster 1 (=int0) drücke:
>
> 1. Fehler: Sobald der externe interrupt abgearbeitet ist erfolgt sofort
> der reset und die LED1 blinkt 10mal. :/
>
> oder
>
> 2. Es passiert, dass ich den interrupt0 ausführen kann (d.h. die LED2
> blinkt kurz), danach passiert kein reset, und es geht auch kein weiterer
> int0 (d.h. kein erneutes blinken der LED2) mehr. Der Atmega hängt.


>
> Wenn ich deinen code anschaue sehe ich, dass du das SREG sicherst. Das
> sollte aber vom GCC selbst übernommen werden.

Komisch, das hat schonmal jemand behauptet. Ist aber schlicht nicht 
so!!! Einfach mal den generierten Code anschauen.

> Außerdem kommt bei mir beim kompilieren von
> "ISR(SIG_UART0_RECV)" >>> misspelled signal handler
>
> dass muss "ISR(SIG_UART_RECV)" heissen.

Kann sein, habe das geändert, weil bei mir ein ATmega32 zum Einsatz 
kommt. Hab's allerdings auch mit einem ATmega8515 getestet, da lief's 
auch. Und auf dem STK500v2 von Atmel läuft das auch...

> Jedenfalls hats nichts geholfen. Der externe interrupt bleibt ein
> Mysterium. Schade. :(

Das heisst für mich: Hardware-Problem. Wie sieht denn die Anschaltung 
des Tasters an INT0 aus? Kannst Du ein Bild des Schaltplans dranhängen?

> Sonst noch Vorschläge?

Noch geben wir nicht auf... ;-)

Grüße
  Frank

Autor: Juergen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Schaltplan,

es handelt sich um das hier im Forum relativ bekannte Pollin Atmel 
Evaluationsboard.

Die Taster funktionieren ansich wenn ich sie per software auslesen 
lasse. Nur bei Verwendung des int0 kommt immer früher oder später ein 
reset.

Grüße,
Jürgen

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Juergen schrieb:
> Hier der Schaltplan,
>
> es handelt sich um das hier im Forum relativ bekannte Pollin Atmel
> Evaluationsboard.

Ah - das Board hat die Taster mit Pull Down Widerständen drin. Dann 
sollte INT0 als Falling Edge Interrupt konfiguriert werden (geht 
natürlich auch anders, ist aber einen Test wert). Damit geht der 
Interrupt erst los, wenn Du den Taster los lässt.

>
> Die Taster funktionieren ansich wenn ich sie per software auslesen

Jau, da wird auch auf High Pegel direkt abgefragt. Das geht mit der Pull 
Down Konfiguration so nicht am Taster 1 für INT0.

> lasse. Nur bei Verwendung des int0 kommt immer früher oder später ein
> reset.

Und deswegen habe ich jetzt mal einen Generic Interrupt Handler 
eingebaut in den angehängten Source Code. Der feuert immer dann, wenn 
ein Interrupt auftritt, für den keine explizite ISR angegeben ist. Siehe 
main() und ISR( __vector_default ).

>
> Grüße,
> Jürgen

Happy Testing.

Grüße
   Frank

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Wenn ich deinen code anschaue sehe ich, dass du das SREG sicherst. Das
>> sollte aber vom GCC selbst übernommen werden.
>
> Komisch, das hat schonmal jemand behauptet. Ist aber schlicht nicht
> so!!!

Das stimmt. Es wird nämlich nicht vom GCC, sondern vom Prozessor selbst 
bereits gemacht. Ein manuelles Sichern ist unnötig.

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
>>> Wenn ich deinen code anschaue sehe ich, dass du das SREG sicherst. Das
>>> sollte aber vom GCC selbst übernommen werden.
>>
>> Komisch, das hat schonmal jemand behauptet. Ist aber schlicht nicht
>> so!!!
>
> Das stimmt. Es wird nämlich nicht vom GCC, sondern vom Prozessor selbst
> bereits gemacht. Ein manuelles Sichern ist unnötig.

Na, das ist aber doch ein Idiom:

1. Sichere SREG in Variable

2. cli();

3. Mach was hier, was ohne Interrupt durchgeführt werden muss.

4. SREG wieder setzen aus Variable

Wie das durch den AVR selbst gemacht werden soll, ist mir schleierhaft 
!! Denn: Der AVR müßte ahnen, wann die Operationen, die ohne Interrupt 
durchgeführt werden müssen, zu Ende sind. Die AVRs sind zwar richtige 
kleine Künstler, aber dass die KI haben, ist mir neu ;-)

Oder aber: Ich habe da was völlig missverstanden in den letzten 5 Jahren 
AVR Programmierung - was dann gerne zugebe ;-)

Grüße
   Frank

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und nochmal SREG:

Lest Euch mal die Funktion

void NichtUnterbrechenBitte(void)

im AVR-GCC Tutorial in diesem Wiki in Kapitel 13.5 durch. Das macht dann 
hoffentlich klar, was ich meine.


Grüße
   Frank

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

sei();               
 
  // Init environment

  init_ports();   
  init_usart();
  init_interrupt();


Falsche Reihenfolge!
Das sei() kommt immer erst nachdem sämtliche Interrupt-Quellen 
konfiguriert wurden.

So gehört das:

  // Init environment

  init_ports();   
  init_usart();
  init_interrupt();

  sei();               

>Wie das durch den AVR selbst gemacht werden soll, ist mir schleierhaft
>!! Denn: Der AVR müßte ahnen, wann die Operationen, die ohne Interrupt
>durchgeführt werden müssen, zu Ende sind. Die AVRs sind zwar richtige
>kleine Künstler, aber dass die KI haben, ist mir neu ;-)

Da hast du was falsch verstanden:
Eine ISR des AVR kann nicht durch eine andere unterbrochen werden; 
dafür sorgt der AVR.

Andere Funktionen sind vor der Unterbrechung durch einen Interrupt nicht 
geschützt.
>void NichtUnterbrechenBitte(void)
Darin soll verhindert werden, dass ein Interrupt die Funktion 
unterbricht.
Das kann den Grun haben, dass sie einen Wert manipuliert (oder auch nur 
ausliest), der auch durch eine ISR geändert werden kann.
Dafür gibt es inzwischen aber das Atomic-Makro...

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer schrieb:
>
> 
> sei();
> 
>   // Init environment
> 
>   init_ports();
>   init_usart();
>   init_interrupt();
> 
> 
>
> Falsche Reihenfolge!
> Das sei() kommt immer erst nachdem sämtliche Interrupt-Quellen
> konfiguriert wurden.

Jadoch, hast ja Recht.

>
> So gehört das:
>
> 
>   // Init environment
> 
>   init_ports();
>   init_usart();
>   init_interrupt();
> 
>   sei();
> 

>
>>Wie das durch den AVR selbst gemacht werden soll, ist mir schleierhaft
>>!! Denn: Der AVR müßte ahnen, wann die Operationen, die ohne Interrupt
>>durchgeführt werden müssen, zu Ende sind. Die AVRs sind zwar richtige
>>kleine Künstler, aber dass die KI haben, ist mir neu ;-)
>
> Da hast du was falsch verstanden:
> Eine ISR des AVR kann nicht durch eine andere unterbrochen werden;
> dafür sorgt der AVR.

Nee, hatte ich nicht, denn:

>
> Andere Funktionen sind vor der Unterbrechung durch einen Interrupt nicht
> geschützt.
>>void NichtUnterbrechenBitte(void)
> Darin soll verhindert werden, dass ein Interrupt die Funktion
> unterbricht.

das ist genau das, was erreicht werden soll.

> Das kann den Grun haben, dass sie einen Wert manipuliert (oder auch nur
> ausliest), der auch durch eine ISR geändert werden kann.

Ach ... ;-)

> Dafür gibt es inzwischen aber das Atomic-Makro...

Ja, aber das macht genau dasselbe wie die von mir dargestellte Sequenz. 
Ich bin halt einer, der schon vor util/atomic.h AVRs programmiert hat. 
;-)

Grüße
   Frank

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ihr redet aneinander vorbei


>> Jürgen
>> Wenn ich deinen code anschaue sehe ich, dass du das SREG sicherst. Das
>> sollte aber vom GCC selbst übernommen werden.
>
> Frank
> Komisch, das hat schonmal jemand behauptet. Ist aber schlicht nicht
> so!!! Einfach mal den generierten Code anschauen.

Jürgen hat nicht geschnallt, was der Grund für die SREG Sicherung ist. 
Er hat nur SREG gesehen und sofort auf Pfui plädiert.

Und Frank hat ihm nicht erklärt, dass der Grund für diese Sicherung das 
Abschalten der Interrupts zum Zwecke der Nichtunterbrechnung einer 
Codesequenz ist.

Jürgen redet von der SREG Behandlung in einer ISR
Frank von einer SREG Behandlung ausserhalb einer ISR

Aber keiner nennt die Dinge beim Namen und so reden sie aneinander 
vorbei.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotzdem mach der AVR beim Eintritt in eine Interruptroutine das SGER 
sichern und Interrupts abschalten von selber. Dazu braucht er auch keine 
KI, denn der Prozessor weiß, wann er eine ISR ausführt!

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ihr redet aneinander vorbei

Jetzt bin ich auch drauf reingefallen...

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ihr redet aneinander vorbei
>
>
>>> Jürgen
>>> Wenn ich deinen code anschaue sehe ich, dass du das SREG sicherst. Das
>>> sollte aber vom GCC selbst übernommen werden.
>>
>> Frank
>> Komisch, das hat schonmal jemand behauptet. Ist aber schlicht nicht
>> so!!! Einfach mal den generierten Code anschauen.
>
> Jürgen hat nicht geschnallt, was der Grund für die SREG Sicherung ist.
> Er hat nur SREG gesehen und sofort auf Pfui plädiert.
>
> Und Frank hat ihm nicht erklärt, dass der Grund für diese Sicherung das
> Abschalten der Interrupts zum Zwecke der Nichtunterbrechnung einer
> Codesequenz ist.

Ok, ja, nicht direkt, sicher. Dass die fragliche Code Sequenz aber nicht 
in einer ISR stand, war aber doch hoffentlich allen klar.

Es ging ja um das Setzen einer zwischen ISR und main() gemeinsam 
genutzten Variablen: nInterruptOccured .

> Jürgen redet von der SREG Behandlung in einer ISR
> Frank von einer SREG Behandlung ausserhalb einer ISR
>
> Aber keiner nennt die Dinge beim Namen und so reden sie aneinander
> vorbei.

Danke.

;-)

Gruß,
  Frank

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Goenninger schrieb:

>> Dafür gibt es inzwischen aber das Atomic-Makro...
>
> Ja, aber das macht genau dasselbe wie die von mir dargestellte Sequenz.

Aber auf eine etwas andere Art, was Vorteile hat:
1) Innerhalb des Schutzes steht auch genau das, was du selber dort 
reingeschrieben hast. Bei deiner Lösung kann dir der Optimizer durch 
Reordering schon mal einen Strich durch die Rechnung machen.
2) SREG wird auf jeden Fall zurückgeschrieben, egal wie der Block 
verlassen wird. Du kannst sogar innerhalb des geschützten Blocks 
"return" verwenden.

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Frank Goenninger schrieb:
>
>>> Dafür gibt es inzwischen aber das Atomic-Makro...
>>
>> Ja, aber das macht genau dasselbe wie die von mir dargestellte Sequenz.
>
> Aber auf eine etwas andere Art, was Vorteile hat:
> 1) Innerhalb des Schutzes steht auch genau das, was du selber dort
> reingeschrieben hast. Bei deiner Lösung kann dir der Optimizer durch
> Reordering schon mal einen Strich durch die Rechnung machen.

Guter Punkt. Und genau das richtige Argument, um mich zu überzeugen, 
doch mal in atomic.h reinzuschauen. Wieder was gelernt. Danke!!

> 2) SREG wird auf jeden Fall zurückgeschrieben, egal wie der Block
> verlassen wird. Du kannst sogar innerhalb des geschützten Blocks
> "return" verwenden.

Das ist zwar auch wichtig, würde aber bei mir aus Stilgründen schon 
wegfallen.

Siehe main.c anbei. So besser ? ;-)

Gruß,
  Frank

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Goenninger schrieb:

> Siehe main.c anbei. So besser ? ;-)

Ähm, naja, ...
Ich sehe überall nur ATOMIC_FORCEON. Warum dann im Original-Code das 
SREG-Sichern statt eines einfachen cli/sei-Pärchens?

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Frank Goenninger schrieb:
>
>> Siehe main.c anbei. So besser ? ;-)
>
> Ähm, naja, ...
> Ich sehe überall nur ATOMIC_FORCEON. Warum dann im Original-Code das
> SREG-Sichern statt eines einfachen cli/sei-Pärchens?

Sh*t. Ok, wer lesen kann ist klar im Vorteil.

Also sollte es ATOMIC_RESTORESTATE heissen. For the records: Neue 
Version main.c anbei. Ich dachte nicht, dass ich in diesem Thread noch 
die amotic.h lesen würde <g>.

Danke!!!

Gruß,
  Frank

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn wir schon dabei sind ... :-)

> Es ging ja um das Setzen einer zwischen ISR und main() gemeinsam
> genutzten Variablen: nInterruptOccured .

Du meinst wohl nInterruptHappened. Das ist ein uint8_t. Das Schreiben 
ist eh schon atomar, wozu der zusätzliche Schutz?
Was allerdings nötig ist (und fehlt), ist ein "volatile".

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Wenn wir schon dabei sind ... :-)
>
>> Es ging ja um das Setzen einer zwischen ISR und main() gemeinsam
>> genutzten Variablen: nInterruptOccured .
>
> Du meinst wohl nInterruptHappened.

Ja.

> Das ist ein uint8_t. Das Schreiben
> ist eh schon atomar, wozu der zusätzliche Schutz?

Pure Faulheit. Ich kann dann den Typ ändern, ohne daran denken zu 
müssen, dass ich dann auch noch die Unterbrechungsfreiheit dazu kodieren 
muss.

> Was allerdings nötig ist (und fehlt), ist ein "volatile".

Ja.

Gruß,
  Frank

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Goenninger schrieb:

> Pure Faulheit. Ich kann dann den Typ ändern, ohne daran denken zu
> müssen, dass ich dann auch noch die Unterbrechungsfreiheit dazu kodieren
> muss.

Sorry, aber dann bist du ziemlich inkonsequent. Das Schreiben wird 
geschützt, das Lesen aber nicht?

Autor: Frank Goenninger (dg1sbg)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Frank Goenninger schrieb:
>
>> Pure Faulheit. Ich kann dann den Typ ändern, ohne daran denken zu
>> müssen, dass ich dann auch noch die Unterbrechungsfreiheit dazu kodieren
>> muss.
>
> Sorry, aber dann bist du ziemlich inkonsequent. Das Schreiben wird
> geschützt, das Lesen aber nicht?

Ja doch.

Und weil's sonst langweilig wird, habe ich auch noch einen reset() 
Funktion eingebaut. Denn: Wenn's nen unbehandelten Interrupt gibt, dann 
könnte man ja auch einen Reset machen... Nur so als Illustration. 
Rückmeldung ? Danke !

Gruß,
  Frank

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei dem Thread fällt mir nur wieder die Frage ein: "Machen sich die 
Leute schon Gedanken zum Programm, bevor sie es tippen, oder erst, wenn 
es beim Kunden ist?"

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:

> Das stimmt. Es wird nämlich nicht vom GCC, sondern vom Prozessor selbst
> bereits gemacht.

AVRs sichern SREG nicht von sich aus.

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer schrieb:
> Bei dem Thread fällt mir nur wieder die Frage ein: "Machen sich die
> Leute schon Gedanken zum Programm, bevor sie es tippen, oder erst, wenn
> es beim Kunden ist?"

Kunde?  Wer hat was von Kunde gesagt ? Es ging darum, den INT0 auf einem 
bestimmten Eval-Board zu nutzen. Das haben manche hier mit konkreten 
Code Beispielen versucht, hinzubekommen. Leider hat das bisher wohl 
nicht geklappt. Dann ist aus dem Thread ein "Ich zeige Dir wie und wann 
man die Makros aus atomic.h benutzt.

Ich als Gelegenheits-µC-Programmierer habe dabei was gelernt - 
technisch und was über andere ;-)

Gruß,
  Frank

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Das stimmt. Es wird nämlich nicht vom GCC, sondern vom Prozessor selbst
>> bereits gemacht.
>
> AVRs sichern SREG nicht von sich aus.

Ich hatte mich verwirren lassen, wahrscheinlich durch den Namen 
init_initerrupt. Ich hatte irgendwie 'interrupt' gelesen und es dann mit 
einer ISR verbunden, in der man das nicht explizit sichern müßte. Ich 
fürchte, daß ich damit noch einige andere verwirrt hab. Man sollte eben 
doch nicht morgens, bevor man zur Arbeit fährt, schnell noch ein Posting 
schreiben.
Mea Culpa

Autor: Juergen (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Halli Hallo,

ich bin gerade ganz guter Laune :)

zuerst zu Frank: Dein Code vom  30.10.2009 12:03 main.c hat 
funktioniert!
Vielen vielen Dank.

Ich hoffe du bist mir nicht böse wenn ich deinen code etwas entrümpelt 
habe. Im Anhang befindet sich nun die Version deines Programmes welche 
mein ursprünglich geplantes Testscenario enthält.

Kurz zu diesem Testprogramm:

> nach dem Start des Atmega 16 blinken beide LEDs (an PD5/PD6)
> im main() endlosschleife die nicht tut
> bei einem externen interrupt (int0) soll die LED2 getoggelt werden

wichtigstes Feature :) kein reset während dem Programmablauf


zuletzt noch einen Dank an alle anderen die hier was gepostet haben.
Ich kann zwar nicht nachvollziehen ob das alles was geschrieben wurde zu 
meiner Problemlösung beigetragen hat (das sollte sich jeder selbst 
überlegen)...

jedenfalls ist das Problem für mich gelöst. Ich habe mein Testprogramm 
als Grundgerüst, mit dem ich nun weiterarbeiten kann.

Gruß,
Jürgen

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juergen schrieb:
> Halli Hallo,
>
> ich bin gerade ganz guter Laune :)
>
> zuerst zu Frank: Dein Code vom  30.10.2009 12:03 main.c hat
> funktioniert!
> Vielen vielen Dank.

Immer gerne! ;-)

>
> Ich hoffe du bist mir nicht böse wenn ich deinen code etwas entrümpelt
> habe. Im Anhang befindet sich nun die Version deines Programmes welche
> mein ursprünglich geplantes Testscenario enthält.

Das kann man dann aber noch weiter entrümpeln ..

>
> Kurz zu diesem Testprogramm:
>
>> nach dem Start des Atmega 16 blinken beide LEDs (an PD5/PD6)
>> im main() endlosschleife die nicht tut
>> bei einem externen interrupt (int0) soll die LED2 getoggelt werden
>
> wichtigstes Feature :) kein reset während dem Programmablauf

Was wohl letzten Endes auf den geänderten INT0 Trigger zurückzuführen 
ist. Die Pull Down Konfiguration auf dem Board ist wohl nicht für Rising 
Edge geeignet.

> jedenfalls ist das Problem für mich gelöst. Ich habe mein Testprogramm
> als Grundgerüst, mit dem ich nun weiterarbeiten kann.

> Gruß,
> Jürgen

Grüße,
  Frank

Autor: Karsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super Tipp!!!
ATOMIC_BLOCK (ATOMIC_RESTORESTATE){} hat auch mit bei INT1 geholfen.

Danke

Karsten

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.