/***********************************************************************************************
* *
* 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