C INT0 deaktivieren ?!

Wenn ich den Overflow für den TIMER0 Enable... Dann funktioniert das nicht mehr mit dem AUSSCHALTEN (INT0) Ich kann zwar die LED´s EINSCHALTEN, nur AUSSCHALTEN halt nicht...
Das muss mit dem TIMER0 Overflow zusammenhängen.... Bremsen sich evtl. die beiden Aktiven ISR´s aus ? ISR für die Tastenentprellung (20 ms.) und die ISR für die PWM (TIMER0_OVF) ???

Code:
int main(void)
{
	

	
	DDRB |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4));
	

	OCR1A = 150;
	TCCR1A = (1<<WGM11);
	TIMSK |= (1<<OCIE1A);
	TCCR1B = ((1<<CS12)) | ((1<<CS10)); // 1024
	
	
	TCCR0B = (1<<CS00);
[B][COLOR="#FF0000"]//	TIMSK  = (1<<TOIE0);[/COLOR][/B]
	
	
	GIMSK  |= (1<<INT0);


	sei();
	
	

	while(1)
	{
		
		
		
	}// Ende While
	
}// Ende Main


//ISR für Tastenentprellung & Auto_Off (20 ms.)
/*---------------------------------------------------------*/

ISR(TIMER1_COMPA_vect)
{
	if (PIND & (1<<PIND2))
	{
		GIMSK |= (1<<INT0);
	}
	
}


//ISR für das Einschalten und Ausschalten der Taschenlampe
/*---------------------------------------------------------*/

ISR (INT0_vect)
{
	
	GIMSK &= ~(1<<INT0);

	if ((PORTB & 0b00001111) == (0b00000000))
	{
		PORTB |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
		//TIMSK  = (1<<TOIE0);
		//TCCR0B = (1<<CS00);
	}
	else
	{
		//TIMSK  &= ~(1<<TOIE0);
		PORTB &= ~((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
	}


}
 
Nein, aber wenn Du TIMSK direkt irgendwas zuweist, werden auch die anderen Bits des Registers beschrieben. Du mußt das RMW realisieren...
 
Nein, aber wenn Du TIMSK direkt irgendwas zuweist, werden auch die anderen Bits des Registers beschrieben. Du mußt das RMW realisieren...

Stimmt, der CompareA Interrupt funktioniert dann nicht mehr.

Wenn ich den Overflow für den TIMER0 Enable... Dann funktioniert das nicht mehr mit dem AUSSCHALTEN (INT0) Ich kann zwar die LED´s EINSCHALTEN, nur AUSSCHALTEN halt nicht...
Das muss mit dem TIMER0 Overflow zusammenhängen.... Bremsen sich evtl. die beiden Aktiven ISR´s aus ? ISR für die Tastenentprellung (20 ms.) und die ISR für die PWM (TIMER0_OVF) ???

In der Timer0 Overflow ISR läuft ja deine Software PWM, ständig.

Folgendes funktioniert dann garnicht, weil die Software PWM ja aktiv ist und dein Änderung an PORTB sofort wieder überschreibt:

Code:
if ((PORTB & 0b00001111) == (0b00000000))
{
  PORTB |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
} else {
  PORTB &= ~((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
}

Hinzu kommt noch, dass das Argument der if-Abfrage quasi ein Zufallswert hat, also wahr oder unwahr, je nachdem was gerade die Software PWM für einen Zustand bei PORTB eingestellt hat.
 
Ich glaube so wird das nie was... Die "Bremsen" sich gegenseitig aus... Wenn ich meine Taste an "INT0" mit TIMER1 Entprelle & mit TIMER0 die SOFT PWM generiere...
Schade :(
 
Folgendes funktioniert dann garnicht, weil die Software PWM ja aktiv ist und dein Änderung an PORTB sofort wieder überschreibt:

Code:
if ((PORTB & 0b00001111) == (0b00000000))
{
  PORTB |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
} else {
  PORTB &= ~((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
}

Hinzu kommt noch, dass das Argument der if-Abfrage quasi ein Zufallswert hat, also wahr oder unwahr, je nachdem was gerade die Software PWM für einen Zustand bei PORTB eingestellt hat.

Auch wenn ich mein "CS00" Bit abfrage, dass gleiche !
 
Auch wenn ich mein "CS00" Bit abfrage, dass gleiche !

Aktuell ist der CompareA Interrupt des Timer1 deaktiviert.

Wenn du die Taste drückst, wird der EXT0 Interrupt deaktiviert und nicht wieder aktiviert. Das heißt, Tastendruck wird nicht mehr erkannt.
 
Hae? Wo ist der denn "Deaktiviert" ? Den TIMER1 deaktiviere ich nirgends :confused:
 
So, in #40 hast Du die entsprechenden Schreibzugriffe auf das TIMSK auskommentiert, effektiv ist hier nur noch der Compare1A scharf (und bleibt es auch)
Und der Externe INT0 (in GIMSK).
Deine PWM ist also abgeschaltet, Du willst direkt in der INT0-ISR die LEDs umschalten. Dort ist soweit alles korrekt, Du schaltest aber dort beim ersten mal den IRQ ab... und nie wieder an.

In der Compare1A-ISR?
Da würdest Du es alle 10ms (nicht nachgerechnet) machen, wenn PinD2 mal gesetzt wäre (wenn ich die C-Syntax richtig interpretiere). Ich sehe aber nichts, was den Pin manipuliert... obwohl... wenn der Pin tristate ist, empfängt der vielleicht irgendwann mal durch kosmisches Rauschen ein High-Pegel (oder wenn man den Pin angrabbelt)

Was ist die Überlegung zu dieser Abfrage gewesen?

Nachtrag zu #47: Quark... das ausbremsen machst Du... da geht noch viel mehr als ein paar Timer-IRQs und der vom Int0...
Wenn Du beim an/abschalten eines IRQ-Enable-Bits in einem Register alle anderen desselben Registers mitabschaltest, oder den entscheidenden Code in bedingten Codeblöcken versteckst, deren Bedingung nie Eintritt, brauchst Du Dich nicht wundern...

Hast Du Dir für das ganze mal 'ne Skizze gemacht, einen Programmablaufplan?
 
In der Compare1A-ISR?
Da würdest Du es alle 10ms (nicht nachgerechnet) machen, wenn PinD2 mal gesetzt wäre (wenn ich die C-Syntax richtig interpretiere). Ich sehe aber nichts, was den Pin manipuliert... obwohl... wenn der Pin tristate ist, empfängt der vielleicht irgendwann mal durch kosmisches Rauschen ein High-Pegel (oder wenn man den Pin angrabbelt)

Was ist die Überlegung zu dieser Abfrage gewesen?

Die Überlegung ist... Wenn der Taster (INT0 = PIND.2) los gelassen wird... so wird "INT0" wieder freigegeben...
 
Hae? Wo ist der denn "Deaktiviert" ? Den TIMER1 deaktiviere ich nirgends :confused:

Der ComareA Interrupt des Timer1 war deaktiviert, nicht der Timer1 gestoppt!

Hatte Lotadac in #42 auch schon erwähnt.

Dies war zumindest seit dem Code in #8 so, der Interrupt war noch nie aktiviert?!

Code:
int main(void)
{
  ...
  OCR1A = 150;
  TCCR1A = (1<<WGM11);
[COLOR=#a52a2a][B]  TIMSK |= (1<<OCIE1A);[/B][/COLOR]
  TCCR1B = ((1<<CS12)) | ((1<<CS10)); // 1024
        
  TCCR0B = (1<<CS00);
[B][COLOR=#a52a2a]  TIMSK  = (1<<TOIE0);[/COLOR][/B]
    
  GIMSK  |= (1<<INT0);

  ...
  while (1)
  {
  ...
 
D2 ist INT0, ok - dann ziehe ich das mit dem nie reaktivieren wieder zurück. Letztendlich gibst Du den IRQ also alle 20ms(?) wieder frei, sofern D2 high ist.
Aber diese 20ms sind nicht an den ersten IRQ gekoppelt - das kann also jederzeit sein. Wie Dein Taster prellt, können wir nicht hellsehen.

Es ist also wahrscheinlich (zumindest möglich), daß er noch prellt, wenn der IRQ im OC1A-IRQ wieder freigegeben wird.
Ebenso, daß dann sofort ein weiterer INT0 getriggert wird. (da er ja noch prellen kann).
Und beim loslassen hast Du das Prellen dann ja auch nochmal (Du läßt los, der Pin geht also prellend von low nach high, irgendwo zwischendrinn erkennt der OC-IRQ dann mal den Hi am D2 und gibt den INT0 frei, der dann (D2 prellt ja noch) sofort wieder ausgelöst wird.

Deine ganzen Implementierungsversuche bringens nicht, wenn bereits das Konzept nicht paßt.
Meinen Konzeptvorschlag mit dem 2ten Timer hast Du hier ja nur noch zu implementieren, der war aber eher auf sleep und so ausgelegt...
Wenn Du das nicht brauchst, kannst Du statt des IRQ auch einfach den Taster sekündlich pollen und umschalten - dann mußte halt so lange drücken bis umgeschaltet wird...
 
Sooo,

Ich habe die Firmware noch überarbeitet und jetzt funktioniert sie soweit wie ich es wollte...
Wo ich jetzt nur noch ein Problem mit habe, ist mit der Auto_Off Funktion...

Diese macht nichts weiter als nach ca. 10 Min. meine LED´s auszuschalten & den TINY2313 in den Schlaf Modus zu versetzen !
Dies frage ich in der "while" ab... Das klappt auch wunderbar... Frage ich aber auch ab ob der aktuelle Status des TIMER1 "CS10" Bits == 0 ist... Funktioniert die Auto_Off Funktion nicht mehr ?!
Was mache ich falsch ?! Wenn ich den "AUS" Taster betätige... möchte ich quasie auch das die "Funktion" Auto_Off meine LED´s ausschaltet & dann in den Sleep_Mode schickt...

Code:
/***********************************************************************************************
*																							   *
*	Stromaufname im IDLE Mode       = ca. 770 µA ( 8 MHz ) kein großer Unterschied zu 4 MHz	   *
*	Stromaufname im Power_Pown_Mode = ca. 20 µA  ( 8 MHz ) kein großer Unterschied zu 4 MHz    *
*																							   *
************************************************************************************************/

#define F_CPU 8000000						// Interner RC Oszillator. Frequenz = 8000000 Hz ( 4 ms. Einschwingzeit )

#define ABSCHALTZEIT	240   				// ABSCHALTZEIT der HighPowerLED´s ( Der TIMER0 läuft ca. jede 10ms in den Interrupt ) 24000
#define HELLIGKEIT		3000				// Wert für den Überlauf ( OCR1A )
#define AB_DIMM_ZEIT	120					// Geschwindigkeit für das ab dimmen der LED´s

#define key_SOS			PD3					// Taste SOS
#define key_ON			PD2					// Taste ON
#define key_UP			PD1					// Taste UP
#define key_DOWN		PD0					// Taste Down

#define TIMER1_START     TCCR1B |=   (1<<CS10);
#define TIMER1_STOP      TCCR1B &= ~ (1<<CS10);

#define XPE_1_AN		PORTB |= (1<<PORTB0)	// HighPowerLED 1 an
#define XPE_2_AN		PORTB |= (1<<PORTB1)	// HighPowerLED 2 an
#define XPE_3_AN		PORTB |= (1<<PORTB2)	// HighPowerLED 3 an
#define XPE_4_AN		PORTB |= (1<<PORTB3)	// HighPowerLED 4 an

#define XPE_1_AUS		PORTB &= ~(1<<PORTB0)	// HighPowerLED 1 aus
#define XPE_2_AUS		PORTB &= ~(1<<PORTB1)	// HighPowerLED 2 aus 
#define XPE_3_AUS		PORTB &= ~(1<<PORTB2)	// HighPowerLED 3 aus 
#define XPE_4_AUS		PORTB &= ~(1<<PORTB3)	// HighPowerLED 4 aus

#define INT0_ENABLE		GIMSK  |= (1<<INT0);					// Interrupt "INT0" aktivieren
#define INT0_DISABLE	GIMSK  &= ~(1<<INT0);					// Interrupt "INT0" deaktivieren

#define INT1_ENABLE  	GIMSK  |= (1<<INT1);					// Interrupt "INT1" aktivieren
#define INT1_DISABLE 	GIMSK  &= ~(1<<INT1);					// Interrupt "INT1" ktivieren

#define ALARM_AN		PORTB |=  (1<<PB4)	// Summer an
#define ALARM_AUS		PORTB &= ~(1<<PB4)	// Summer aus

#include <avr/io.h>							// Library für die I/O (Ports)
#include <avr/sleep.h>						// Library für den Schlaf Modus
#include <avr/interrupt.h>					// Library für die Interrupts
#include <util/delay.h>						// Library für Delay
#include <stdint.h>							// Benötigt Library für Uint16_t Werte

volatile uint16_t Auto_Off;					// Hier zählt der Timer jede 10 ms die Variable hoch, ( Volatile = Darf durch Interrupt verändert werden & der Compiler Optimiert die Variable nicht weg )
volatile uint8_t Sleep_Mode = 1;			// Wertet den Status der LED´s aus (AN / AUS ?)
volatile uint8_t keystatus;					// Verhindert das eine Taste mehrmals abgefragt wird, wenn sie fest gehalten wird
volatile uint16_t Ueberlauf;				// Variable gegen den "überlauf / Unterlauf" der Helligkeit
volatile uint16_t Helligkeit_Speicher;

void SOS();									// Main wird bekannt gegeben, dass ein Unterprogramm existiert
void Boot_Main();							// Main wird bekannt gegeben, dass ein Unterprogramm existiert
void Boot_INT0();


int main(void)
{
    OCR0A   = 77;							// Legt den Wert ZUM Überlaufes fest ( ca. jede 10 ms.)
	TCCR0A |= (1<<WGM01);					// Compare Match (Normal Mode) keine Funktion am PIN &&    TIFR |= 0x01;			// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
    TIMSK  |= (1<<OCIE0A);					// Compare Match Interrupt enable
    TCCR0B |= ((1<<CS02) | (1<<CS00));		// Prescaler auf 1024 setzen (F_CPU/1024)
	
	OCR1A   = HELLIGKEIT;					// Legt den Wert des Überlaufes fest
	TCCR1A |= 0x00;							// Compare Match (Normal Mode) keine Funktion am PIN
	TIFR   |= 0x01;							// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
	TIMSK  |= ((1<<OCIE1A) | (1<<TOIE1));							// Compare Match Interrupt enable
	TCCR1B |= (1<<CS10);					// Prescaler auf 0 setzen (F_CPU)
	
	GIMSK  |= ((1<<INT0) | (1<<INT1));		// Interrupt "INT0 & INT1" aktivieren


    sei();									// Interrupts global aktivieren
	
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);	// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
	sleep_mode();							// Setzt den µC (nach Batteriewechsel) in den sleep_mode 
	
	OCR1A = 550;

		
while(1)
{
	
	if ((Auto_Off == ABSCHALTZEIT) || [COLOR="#FF0000"][B](TCCR1B & (1<<CS10)[/B][/COLOR]))			// Ist Auto_Off = ABSCHALTZEIT, dann schlafen!
	{	
		Auto_Off=0;
		TIMER1_STOP;
		XPE_1_AUS; XPE_2_AUS; XPE_3_AUS; XPE_4_AUS;								
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);		// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
		sleep_mode();								// Schlafen aktivieren!
	}


    
	}// Ende While
	
}// Ende Main


ISR(TIMER0_COMPA_vect) // Sorgt dafür das die Akkus / Batterien geschont werden! (Abschaltung nach ca. 10 min.) 
{
	
	Auto_Off = Auto_Off+1; // Jede 10ms Auto_Off um 1 erhöhen!	
	Ueberlauf = OCR1A;
	
	if (PIND & (1<<PIND2))
	{
		INT0_ENABLE; 
	}
	
	if (PIND & (1<<PIND3))
	{
		INT1_ENABLE;
	}

		
	if (keystatus != (PIND & 0b00000011)) // Sorgt dafür das die Taste (auch wenn gedrückt) nur 1 x ausgewertet wird
	{
	
	if (Ueberlauf <=  (65530 - 6553)) // Verhindert das der Wert wieder von Anfang gezählt wird ( Max )
	{	
		
	if (!(PIND & (1<<key_UP))) // Wertet Taste "key_UP" aus & erhöht die Helligkeit
	{
		Auto_Off=0;
		OCR1A = OCR1A + 6553; // Überlauf um "13107" erhöhen
	}	
			
	}// Ende if Ueberlauf ( Max )		
				
			
	if (Ueberlauf >= (550 + 6553)) // Verhindert das der Wert wieder von Anfang gezählt wird ( Min )
	{
		
	if (!(PIND & (1<<key_DOWN))) // Wertet die Taste "key_DOWN" aus & verringert die Helligkeit	
	{
		Auto_Off=0;
		OCR1A = OCR1A - 6553; // Überlauf um "13107" verringern
	}	
			
	}// Ende if Ueberlauf ( Min )
	Auto_Off=0;
	} // Ende if (keystatus)                                                                                                     

	keystatus = (PIND & 0b00000011); // Weißt der Variable "keystatus" den Wert (PIND & 0b00000011)	
	

} // Ende ISR (TIMER0_COMPA_vect)


ISR(INT0_vect) // HighPowerLED´s ein / aus schalten! // #define TIMER1_START     TCCR1B |=   (1<<CS10);

{	

	Auto_Off = 0; // Muss auf "0" gesetzt werden, sonst geht das Licht erst nach Tastendruck durch "key_UP" | "key_DOWN" aus		
//	OCR1A = Helligkeit_Speicher;
	INT0_DISABLE;

[COLOR="#FF0000"][B]	if (TCCR1B & (1<<CS10))[/B][/COLOR]
	{
		TIMER1_STOP;
		XPE_1_AUS ; XPE_2_AUS ; XPE_3_AUS ; XPE_4_AUS ;
	}
		else
	{
		TIMER1_START;
	}
		

} // Ende ISR (INT0_vect)


	ISR(INT1_vect) // Wird die Taste "key_SOS" gedrückt, läuft das Unterprogramm ( SOS(); ) ab
	{
		INT1_DISABLE;
		TIMER1_START;
	} // Ende ISR (INT1_vect)


	ISR(TIMER1_COMPA_vect) // Ist der OCR1A Wert erreicht, werden die HighPowerLED´s aus geschaltet
	{
		XPE_1_AUS;
		XPE_2_AUS;
		XPE_3_AUS;
		XPE_4_AUS;
	} // Ende ISR (TIMER1_COMPA_vect)


	ISR(TIMER1_OVF_vect) // Schaltet nach jedem Überlauf ( Overflow ) die HighPowerLED´s an
	{	
		XPE_1_AN;
		XPE_2_AN;
		XPE_3_AN;
		XPE_4_AN;	
	} // Ende ISR (TIMER1_OVF_vect)


/***************************************************************************************************
*																								   *
*						Ab hier beginnen die Sonderfunktionen ( Effekte )						   *
*																								   *
***************************************************************************************************/

void SOS() // Hier ist das Unterprogramm "SOS();"

{	
	while(1)
	{	
		
	uint8_t SOS_Counter;
		
	for (SOS_Counter = 0 ; SOS_Counter < 3 ; SOS_Counter++) // 3 x kurz
	{
		ALARM_AN ;
		XPE_1_AN ; XPE_2_AN ; XPE_3_AN ; XPE_4_AN ;
		_delay_ms(100);
		ALARM_AUS ;
		XPE_1_AUS ; XPE_2_AUS ; XPE_3_AUS ; XPE_4_AUS ;
		_delay_ms(100);
			
	if (!(PIND & (1<<key_ON)))
	{

		ALARM_AN;XPE_1_AN;XPE_2_AN;XPE_3_AN;XPE_4_AN;
		_delay_ms(1500);
		ALARM_AUS;XPE_1_AUS;XPE_2_AUS;XPE_3_AUS;XPE_4_AUS;
		_delay_ms(1000);
		Sleep_Mode = 0;
		return;
	}

		}// Ende for SOS_Counter
		
			_delay_ms(700);
		
	for (SOS_Counter = 0 ; SOS_Counter < 3 ; SOS_Counter++) // 3 x lang
	{
		ALARM_AN ;
		XPE_1_AN ; XPE_2_AN ; XPE_3_AN ; XPE_4_AN;
		_delay_ms(500);
		ALARM_AUS ;
		XPE_1_AUS ; XPE_2_AUS ; XPE_3_AUS ; XPE_4_AUS;
		_delay_ms(500);
			
	}// Ende for SOS_Counter	
	
}// Ende While (SOS)

}// Ende SOS
 
Hallo Janiiix.

Im Moment ist es so, dass wenn der Timer1 läuft ODER die Zeit erreicht ist, der Mikrocontroller in den Powerdown geht. Ich denke, dies möchtest du nicht. Bei welchen Bedingungen soll er denn in Powerdown gehen?
 
Hallo Janiiix.

Im Moment ist es so, dass wenn der Timer1 läuft ODER die Zeit erreicht ist, der Mikrocontroller in den Powerdown geht. Ich denke, dies möchtest du nicht. Bei welchen Bedingungen soll er denn in Powerdown gehen?

Moin Dirk,

Ich möchte in den "PowerDown" Mode gehen, wenn der TIMER1 nicht läuft (CS10 = 0) || Die Zeit erreicht ist...
 
Auch wenn ich es so mache... klappt das nicht ?!

Code:
while(1)
{
	
	if ((Auto_Off == ABSCHALTZEIT) || [COLOR="#FF0000"][B](!(TCCR1B & (1<<CS10)))[/B][/COLOR])			// Ist Auto_Off = ABSCHALTZEIT, dann schlafen!
	{	
		Auto_Off=0;
		TIMER1_STOP;
		XPE_1_AUS; XPE_2_AUS; XPE_3_AUS; XPE_4_AUS;								
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);		// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
		sleep_mode();								// Schlafen aktivieren!
	}


    
	}// Ende While
	
}// Ende Main
 
Ich finde leider den Fehler nicht. Jedenfalls stimmt die zweite Version der Argumente der if-Abfrage, das zuvor hatte nicht gestimmt.

Code:
[COLOR=#333333]if ((Auto_Off == ABSCHALTZEIT) || [/COLOR][COLOR=#FF0000][B](!(TCCR1B & (1<<CS10)))[/B][/COLOR][B])[/B]
 
Ich finde leider den Fehler nicht. Jedenfalls stimmt die zweite Version der Argumente der if-Abfrage, das zuvor hatte nicht gestimmt.

Code:
[COLOR=#333333]if ((Auto_Off == ABSCHALTZEIT) || [/COLOR][COLOR=#FF0000][B](!(TCCR1B & (1<<CS10)))[/B][/COLOR][B])[/B]

so klappt es jetzt !

Code:
while(1)
{
	
	if ((Auto_Off == ABSCHALTZEIT) || (TCCR1B & (0<<CS10)))			// Ist Auto_Off = ABSCHALTZEIT, dann schlafen!
	{	
		Auto_Off=0;
		TIMER1_STOP;
		XPE_1_AUS; XPE_2_AUS; XPE_3_AUS; XPE_4_AUS;								
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);		// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
		sleep_mode();								// Schlafen aktivieren!
	}


    
	}// Ende While
	
}// Ende Main
 
so klappt es jetzt

Dieser Ausdruck
Code:
[COLOR=#333333](TCCR1B & (0<<CS10))[/COLOR]

ist immer unwahr (immer 0). Da er mit dem ersten boolschen Ausdruck mit ODER verknüpft ist, kannst du ihn dann auch weglassen.
 
Wenn ich in der INT0 ISR ... Auto_Off den Wert von ABSCHALTZEIT zuweise... Kann ich ihn später nicht mehr aus dem Sleep_Mode holen... Nur wieso :mad:
Aber lasse ich die Zuweisung weg... Geht er nach ca. 4 Min in den Sleep Mode... später kann ich ihn auch wieder wecken...
 
Code:
#define F_CPU 8000000						// Interner RC Oszillator. Frequenz = 8000000 Hz ( 4 ms. Einschwingzeit )

#define ABSCHALTZEIT	24000  				// ABSCHALTZEIT der HighPowerLED´s ( Der TIMER0 läuft ca. jede 10ms in den Interrupt ) 24000 = 4 Min
#define HELLIGKEIT		3000				// Wert für den Überlauf ( OCR1A )

#define key_SOS			PD3					// Taste SOS
#define key_ON			PD2					// Taste ON
#define key_UP			PD1					// Taste UP
#define key_DOWN		PD0					// Taste Down

#define TIMER1_START     TCCR1B |=   (1<<CS10);
#define TIMER1_STOP      TCCR1B &= ~ (1<<CS10);

#define XPE_1_AN		PORTB |= (1<<PORTB0)	// HighPowerLED 1 an
#define XPE_2_AN		PORTB |= (1<<PORTB1)	// HighPowerLED 2 an
#define XPE_3_AN		PORTB |= (1<<PORTB2)	// HighPowerLED 3 an
#define XPE_4_AN		PORTB |= (1<<PORTB3)	// HighPowerLED 4 an

#define XPE_1_AUS		PORTB &= ~(1<<PORTB0)	// HighPowerLED 1 aus
#define XPE_2_AUS		PORTB &= ~(1<<PORTB1)	// HighPowerLED 2 aus 
#define XPE_3_AUS		PORTB &= ~(1<<PORTB2)	// HighPowerLED 3 aus 
#define XPE_4_AUS		PORTB &= ~(1<<PORTB3)	// HighPowerLED 4 aus

#define INT0_ENABLE		GIMSK  |= (1<<INT0);					// Interrupt "INT0" aktivieren
#define INT0_DISABLE	GIMSK  &= ~(1<<INT0);					// Interrupt "INT0" deaktivieren

#define INT1_ENABLE  	GIMSK  |= (1<<INT1);					// Interrupt "INT1" aktivieren
#define INT1_DISABLE 	GIMSK  &= ~(1<<INT1);					// Interrupt "INT1" ktivieren

#define ALARM_AN		PORTB |=  (1<<PB4)	// Summer an
#define ALARM_AUS		PORTB &= ~(1<<PB4)	// Summer aus

#include <avr/io.h>							// Library für die I/O (Ports)
#include <avr/sleep.h>						// Library für den Schlaf Modus
#include <avr/interrupt.h>					// Library für die Interrupts
#include <util/delay.h>						// Library für Delay
#include <stdint.h>							// Benötigt Library für Uint16_t Werte

volatile uint16_t Auto_Off;					// Hier zählt der Timer jede 10 ms die Variable hoch, ( Volatile = Darf durch Interrupt verändert werden & der Compiler Optimiert die Variable nicht weg )
volatile uint8_t keystatus;					// Verhindert das eine Taste mehrmals abgefragt wird, wenn sie fest gehalten wird
volatile uint16_t Ueberlauf;				// Variable gegen den "überlauf / Unterlauf" der Helligkeit
volatile uint16_t Helligkeit_Speicher;

void SOS();									// Main wird bekannt gegeben, dass ein Unterprogramm existiert



int main(void)
{
    OCR0A   = 77;							// Legt den Wert ZUM Überlaufes fest ( ca. jede 10 ms.)
	TCCR0A |= (1<<WGM01);					// Compare Match (Normal Mode) keine Funktion am PIN &&    TIFR |= 0x01;			// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
    TIMSK  |= (1<<OCIE0A);					// Compare Match Interrupt enable
    TCCR0B |= ((1<<CS02) | (1<<CS00));		// Prescaler auf 1024 setzen (F_CPU/1024)
	
	OCR1A   = HELLIGKEIT;					// Legt den Wert des Überlaufes fest
	TCCR1A |= 0x00;							// Compare Match (Normal Mode) keine Funktion am PIN
	TIFR   |= 0x01;							// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
	TIMSK  |= ((1<<OCIE1A) | (1<<TOIE1));							// Compare Match Interrupt enable
	TCCR1B |= (1<<CS10);					// Prescaler auf 0 setzen (F_CPU)
	
	GIMSK  |= ((1<<INT0) | (1<<INT1));		// Interrupt "INT0 & INT1" aktivieren

	MCUCR  &= ~((1<<ISC01) | (1<<ISC00));

    sei();									// Interrupts global aktivieren
		
//	set_sleep_mode(SLEEP_MODE_PWR_DOWN);	// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
//	sleep_mode();							// Setzt den µC (nach Batteriewechsel) in den sleep_mode 
	
	Auto_Off = ABSCHALTZEIT;
	
	OCR1A = 800;
	
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);		// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)

		
while(1)
{

	if ((Auto_Off == ABSCHALTZEIT))			// Ist Auto_Off = ABSCHALTZEIT, dann schlafen!
	{		
		sei();
		INT0_ENABLE;
		Auto_Off=0;	
		TIMER1_STOP;
		XPE_1_AUS; XPE_2_AUS; XPE_3_AUS; XPE_4_AUS;								
		sleep_mode();								// Schlafen aktivieren!
	}
	
    
 }// Ende While
	
}// Ende Main


ISR(TIMER0_COMPA_vect) // Sorgt dafür das die Akkus / Batterien geschont werden! (Abschaltung nach ca. 10 min.) 
{
	
	Auto_Off = Auto_Off+1; // Jede 10ms Auto_Off um 1 erhöhen!	
	Ueberlauf = OCR1A;
	
	if (PIND & (1<<PIND2))
	{
		INT0_ENABLE; 
	}
		
	if (keystatus != (PIND & 0b00000011)) // Sorgt dafür das die Taste (auch wenn gedrückt) nur 1 x ausgewertet wird
	{
	
	if (Ueberlauf <=  (65530 - 6553)) // Verhindert das der Wert wieder von Anfang gezählt wird ( Max )
	{	
		
	if (!(PIND & (1<<key_UP))) // Wertet Taste "key_UP" aus & erhöht die Helligkeit
	{
		Auto_Off=0;
		OCR1A = OCR1A + 6553; // Überlauf um "13107" erhöhen
	}	
			
	}// Ende if Ueberlauf ( Max )		
				
			
	if (Ueberlauf >= (800 + 6553)) // Verhindert das der Wert wieder von Anfang gezählt wird ( Min )
	{
		
	if (!(PIND & (1<<key_DOWN))) // Wertet die Taste "key_DOWN" aus & verringert die Helligkeit	
	{
		Auto_Off=0;
		OCR1A = OCR1A - 6553; // Überlauf um "13107" verringern
	}	
			
	}// Ende if Ueberlauf ( Min )
		Auto_Off=0;
	} // Ende if (keystatus)                                                                                                     

	keystatus = (PIND & 0b00000011); // Weißt der Variable "keystatus" den Wert (PIND & 0b00000011)	
	

} // Ende ISR (TIMER0_COMPA_vect)


ISR(INT0_vect) // HighPowerLED´s ein / aus schalten!

{	
	Auto_Off = 0; // Muss auf "0" gesetzt werden, sonst geht das Licht erst nach Tastendruck durch "key_UP" | "key_DOWN" aus		
	INT0_DISABLE;

	if (TCCR1B & (1<<CS10))
	{
		TIMER1_STOP;
		XPE_1_AUS ; XPE_2_AUS ; XPE_3_AUS ; XPE_4_AUS ;
[COLOR="#FF0000"][B]		Auto_Off = ABSCHALTZEIT;[/B][/COLOR]
	}
		else
	{
		TIMER1_START;
	}
		
} // Ende ISR (INT0_vect)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)