Ach Du liebes Bisschen - klar, wenn ich mich recht erinnere, bin ich schon mal drüber gestolpert - aber jetzt bleibt es hoffentlich in meinem Kopf :. . . also doch vorlaut oder -eilig.Zitat:
Zitat von doc2545-Seite 16
Druckbare Version
Ach Du liebes Bisschen - klar, wenn ich mich recht erinnere, bin ich schon mal drüber gestolpert - aber jetzt bleibt es hoffentlich in meinem Kopf :. . . also doch vorlaut oder -eilig.Zitat:
Zitat von doc2545-Seite 16
aber du hast in sofern recht, dass die interrupts normalerweise reihenweise abgearbeitet werden. :)
Hallo ihr Verschachtelten ;-)
Ich muss euch leider enttäuschen. Das es beim AVR keine Schachteln gibt, liegt nur daran, dass wir die Interrupt-Funktion immer mit:
- SIGNAL (Interrupt-Name)
bzw.:
- ISR (Interrupt-Name) in neueren Compilerversionen
angeben.
Es liegt genau an diesem Namen, bzw. bei ISR an der Parameterform, dass die Interrupts im AVR eben nicht geschachtelt werden.
Es gibt nämlich noch die Form:
- ISR(XXX_vect, ISR_NOBLOCK)
und auch eine Schreibweise beim alten Compilern. (Im Moment ist mir der Name abhanden gekommen, da ich da selber auch noch nichts mit gemacht habe.)
Hier wird erzwungen, dass Interrupts eben doch geschachtelt aufgerufen werden können. Natürlich unter Einhaltung der Interrupt-Prioritäten. Nur diese sind Hardwareabhängig.
Insofern ist also alle möglich!
- Schachteln vermeiden ist Default.
- Schachteln erzwingen ist Kunst.
- Schachteln per Bit-Fummelei ist Wissen.
Aber das ist es gar nicht was ich euch noch mitteilen möchte. :cheesy:
Ich möchte euch davon berichten, dass die Softwarestruktur sich um die Aufrufe zum Starten von Funktionen kümmert, so dass der Timer-Interrupt z.B. etwas macht, dass ein AD-Wandler angestoßen wird. Der Timer ist also schon lange fertig, aber die AD-Wandler-Hardware ackert und wird in Zukunft einen Interrupt auslösen. Und dass dann noch in Kombination mit einem Tasten-Interrupt.
Aber da muss ich erst noch die Zeit zu finden um euch mit weiterem Input zu 'beglücken'.
In diesem Sinne warten wir auf den nächsten Interrupt. Ich gehe jetzt erst einmal nach Hause. (schon wieder Arbeitszeit, pfui)
Gruß Sternthaler
schachtel erzwingen ist einfach... einfach das I-bit setzen in der interruptroutine. =)
Das ist ja auch die Empfehlung von Atmel:
https://www.roboternetz.de/phpBB2/ze...=346944#346944
Kann mir jmd sagen wo ich das void set_sleep_mode (uint8 t mode)
void sleep_mode (void)
einsetzen muss??Ich möchte das genze über ein 4x16 lcd und 8 tastern am I²C steuern.
ein bitte und ein danke wären schon mal nicht schlecht, vom gruß mal ganz abgesehen...
@inka
sorry,habe ich ganz vergessen.Ach:danke für das tolle Projekt.
Kann mir bitte jmd. sagen wo ich das void set_sleep_mode (uint8 t mode)
void sleep_mode (void)
einsetzen muss??Ich möchte das genze über ein 4x16 lcd und 8 tastern am I²C steuern.Ich habe vor 10 min. draufgeflasht und ich habe probleme bei der einstellung.Knn mir bitte jemand helfen?
Problem gelöst!zwei Taster waren Schrott!
Hallo Sternthaler,Zitat:
Zitat von Sternthaler
deine Taster-Interrupt-Erklärung ist super!:)
gilt dein Angebot noch? Ich wäre dir sehr dankbar, wenn du mir die anderen Interrupts auch noch erklären würdest.
Ich habe jetzt mal zu Übungszwecken, um die Zusammenhänge zu begreifen, versucht ein kleines Programm zu schreiben, in das ich alle nötigen Funktionen etc. direkt eingebunden habe. Damit lässt sich die StatusLED schalten und der Tasterinterrupt geht auch.
Mein nächstes Ziel ist nun, nach der Tastergeschichte mit Hilfe von Timer2-Interrupt eine Wartezeit einzubauen, nach der die LED gelb leuchtet.
Kann es sein, das ich hierfür die "SIGNAL (SIG_OVERFLOW2)" ändern müsste?
Leider ist mir diese Funktion ziemlich unverständlich.
Schöne GrüsseCode://----------------------------------------------------------------
//bitschiebereien und interrupts
#include <avr/io.h>
#include <avr/interrupt.h>
//----------------------------------------------------------------
// variablen in global.c definiert:
volatile int switched; //für tasterinterrupt
volatile unsigned char count36kHz; //für timer2 interrupt
volatile unsigned long timebase; //für timer2 interrupt
//----------------------------------------------------------------
// eigene variablen
volatile int zeit; //für timer2 interrupt
long i; //fürs warten
//----------------------------------------------------------------
// Funktionen
//----------------------------------------------------------------
// warten
void warten(void)
{
for(i=0;i<500000;i++);
}
//----------------------------------------------------------------
//Interruptfunktion taster in asuro.c
SIGNAL (SIG_INTERRUPT1)
{
switched = 1;
GICR &= ~(1 << INT1); // Externen Interrupt 1 sperren
}
//----------------------------------------------------------------
//taster interrupt einschalten
void StartSwitch (void)
{
DDRD &= ~(1 << PD3); // PD3 als Eingang
PORTD &= ~(1 << PD3); // PD3 auf LOW
MCUCR &= ~((1 << ISC11) | (1 << ISC10)); // Low level erzeugt Interrupt
GICR |= (1 << INT1); // Externen Interrupt 1 zulassen
}
//----------------------------------------------------------------
//taster interrupt ausschalten
void StopSwitch (void)
{
GICR &= ~(1 << INT1); // Externen Interrupt 1 sperren
}
//----------------------------------------------------------------
//timer2 interrupt einschalten
void TimerInit (void) // teil der init in asuro.c
/*
Timer2, zum Betrieb mit der seriellen Schnittstelle, fuer die
IR-Kommunikation auf 36 kHz eingestellt.
*/
{
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle fuer 36kHz
TIMSK |= (1 << TOIE2); // 36kHz counter
}
//----------------------------------------------------------------
//Interruptfunktion timer2 in asuro.c
SIGNAL (SIG_OVERFLOW2)
{
TCNT2 += 0x25;
count36kHz ++;
if (!count36kHz)
timebase ++;
#ifdef RC5_AVAILABLE
if (enableRC5 && !(count36kHz % 8))
IsrRC5(); // wird alle 222.2us aufgerufen
#endif
}
//----------------------------------------------------------------
//----------------------------------------------------------------
int main(void)
{
sei (); //Interrupts erlauben
//cli (); //Interrupts verbieten
//led vorbereiten
DDRB |= (1<<PB0); // Datenrichtungsregister für LED-grün auf Ausgang
DDRD |= (1<<PD2); // für rot auf ausgang
//----------------------------------------------------------------
// Ampel
// grün
PORTB |= (1<<PB0); // Ausgang für grün schalten
warten();
// gelb
PORTD |= (1<<PD2); // rot dazu einschalten
warten();
// rot
PORTB &= ~(1<<PB0); // grün ausschalten
warten();
// aus
PORTD &= ~(1<<PD2); // rot auschalten
// Ampel Ende
//----------------------------------------------------------------
warten();
warten();
//----------------------------------------------------------------
// Taster Interrupt
switched = 0;
StartSwitch ();
while (switched == 0) // wenn kein taster gedrückt ist rot leuchten
{
PORTB &= ~(1<<PB0); // grün ausschalten
PORTD |= (1<<PD2); // rot einschalten
}
PORTB |= (1<<PB0); // grün einschalten
PORTD &= ~(1<<PD2); // rot auschalten
//switched = 0;
//StartSwitch ();
StopSwitch ();
// Taster Interrupt Ende
//----------------------------------------------------------------
// und jetzt nach 1sek led gelb mit timer2 interrupt ?????????
//----------------------------------------------------------------
// timer2 Interrupt
// zeit = 1;
TimerInit ();
if ( zeit == 1)
{
PORTB |= (1<<PB0); // grün einschalten
PORTD |= (1<<PD2); // rot einschalten
}
//----------------------------------------------------------------
while(1);
return(0);
}
M.