// Software für Lampensimulator mit ATtiny2313
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define TRUE 1
#define FALSE 0
// Fuse-Bits: --- für internen Clock ---
// efuse = FF
// hfuse = DF
// lfuse = E2 (4 MHz Grundtaktakt ohne Teilung)
// -> Frequenz : 4.000.000 Hz
//
// Die Lampen werden durch das Auslesen entsprechender Arrays gesteuert:
// Der Teiler gibt an, wie viele Zyklen (je 130 ms) von TIMER1_OVF_vect
// für eine Hell- bzw. Dunkelphase gebraucht werden:
#define BLINKARRAY1A_LAENGE 2
#define BLINKARRAY1A_TEILER 8 // Takt 0,5 Hz.
#define BLINKARRAY2A_LAENGE 2
#define BLINKARRAY2A_TEILER 4 // Takt 1 Hz.
#define BLINKARRAY3A_LAENGE 2
#define BLINKARRAY3A_TEILER 2 // Takt 2 Hz.
#define BLINKARRAY1B_LAENGE 6
#define BLINKARRAY1B_TEILER 4 // Takt 1 Hz.
#define BLINKARRAY2B_LAENGE 8
#define BLINKARRAY2B_TEILER 4 // Takt 1 Hz.
#define BLINKARRAY3B_LAENGE 10
#define BLINKARRAY3B_TEILER 4 // Takt 1 Hz.
volatile uint8_t BlinkArray1AZaehler = 0; // Normales Wechselblinken LED 1
volatile uint8_t BlinkArray1A[BLINKARRAY1A_LAENGE] =
{
1, 0
};
volatile uint8_t BlinkArray2AZaehler = 0; // Normales Wechselblinken LED 2
volatile uint8_t BlinkArray2A[BLINKARRAY2A_LAENGE] =
{
1, 0
};
volatile uint8_t BlinkArray3AZaehler = 0; // Normales Wechselblinken LED 3
volatile uint8_t BlinkArray3A[BLINKARRAY3A_LAENGE] =
{
1, 0
};
volatile uint8_t BlinkArray1BZaehler = 0;
// Position blinken - 2 s Pause und 1 x Puls 0,5 s
volatile uint8_t BlinkArray1B[BLINKARRAY1B_LAENGE] =
{
0, 0, 0, 0, 1, 0
};
volatile uint8_t BlinkArray2BZaehler = 0;
// Position blinken - 2 s Pause und 2 x Puls 0,5 s
volatile uint8_t BlinkArray2B[BLINKARRAY2B_LAENGE] =
{
0, 0, 0, 0, 1, 0, 1, 0
};
volatile uint8_t BlinkArray3BZaehler = 0;
// Position blinken - 2 s Pause und 3 x Puls 0,5 s
volatile uint8_t BlinkArray3B[BLINKARRAY3B_LAENGE] =
{
0, 0, 0, 0, 1, 0, 1, 0, 1, 0
};
// Variablen für die Zustände Wechselblinken oder Positionierungssignal:
// FALSE = Normales Wechselblinken
// TRUE = Positionierungssignal ausgeben
volatile uint8_t taster1toggle = FALSE; // Toggle-Zustand Taster 1
volatile uint8_t taster2toggle = FALSE; // Toggle-Zustand Taster 2
volatile uint8_t taster3toggle = FALSE; // Toggle-Zustand Taster 3
/* --------------------------------------------------------------------
Timer1-Interrupt-Funktion:
---------------------------------------------------------------------*/
ISR(TIMER1_OVF_vect)
{
if (taster1toggle == FALSE)
{
// Normales Blinken
if (BlinkArray1A[BlinkArray1AZaehler / BLINKARRAY1A_TEILER] == TRUE)
{
PORTB |= (1 << PIN0); // Bit setzen
}
else
{
PORTB &= ~(1 << PIN0); // Bit löschen
}
BlinkArray1AZaehler++;
if (BlinkArray1AZaehler > (BLINKARRAY1A_LAENGE *BLINKARRAY1A_TEILER))
{
BlinkArray1AZaehler = 0;
}
}
else
{
// Positionierungssignal ausgeben
if (BlinkArray1B[BlinkArray1BZaehler / BLINKARRAY1B_TEILER] == TRUE)
{
PORTB |= (1 << PIN0); // Bit setzen
}
else
{
PORTB &= ~(1 << PIN0); // Bit löschen
}
BlinkArray1BZaehler++;
if (BlinkArray1BZaehler > (BLINKARRAY1B_LAENGE *BLINKARRAY1B_TEILER))
{
BlinkArray1BZaehler = 0;
}
}
if (taster2toggle == FALSE)
{
// Normales Blinken
if (BlinkArray2A[BlinkArray2AZaehler / BLINKARRAY2A_TEILER] == TRUE)
{
PORTB |= (1 << PIN1); // Bit setzen
}
else
{
PORTB &= ~(1 << PIN1); // Bit löschen
}
BlinkArray2AZaehler++;
if (BlinkArray2AZaehler > (BLINKARRAY2A_LAENGE *BLINKARRAY2A_TEILER))
{
BlinkArray2AZaehler = 0;
}
}
else
{
// Positionierungssignal ausgeben
if (BlinkArray2B[BlinkArray2BZaehler / BLINKARRAY2B_TEILER] == TRUE)
{
PORTB |= (1 << PIN1); // Bit setzen
}
else
{
PORTB &= ~(1 << PIN1); // Bit löschen
}
BlinkArray2BZaehler++;
if (BlinkArray2BZaehler > (BLINKARRAY2B_LAENGE *BLINKARRAY2B_TEILER))
{
BlinkArray2BZaehler = 0;
}
}
if (taster3toggle == FALSE)
{
// Normales Blinken
if (BlinkArray3A[BlinkArray3AZaehler / BLINKARRAY3A_TEILER] == TRUE)
{
PORTB |= (1 << PIN2); // Bit setzen
}
else
{
PORTB &= ~(1 << PIN2); // Bit löschen
}
BlinkArray3AZaehler++;
if (BlinkArray3AZaehler > (BLINKARRAY3A_LAENGE *BLINKARRAY3A_TEILER))
{
BlinkArray3AZaehler = 0;
}
}
else
{
// Positionierungssignal ausgeben
if (BlinkArray3B[BlinkArray3BZaehler / BLINKARRAY3B_TEILER] == TRUE)
{
PORTB |= (1 << PIN2); // Bit setzen
}
else
{
PORTB &= ~(1 << PIN2); // Bit löschen
}
BlinkArray3BZaehler++;
if (BlinkArray3BZaehler > (BLINKARRAY3B_LAENGE *BLINKARRAY3B_TEILER))
{
BlinkArray3BZaehler = 0;
}
}
}
int Init_Timer1(void)
{
// Timer 1 ist 16-Bit-Timer
// CS12=0, CS11=1, CS10=0 => Vorteiler 8; -> 4.000.000 Hz : 8 = 500 000
// Der Overflow-Interrupt wird aber erst ausgelöst,
// wenn der Zähler die Zahl 65 536 (16 Bit) erreicht
// Zeitintervall = 500 000 : 65 536 = 7,63 Hz (ca. alle 130 ms)
// Damit lassen sich Frequenzen von ca. 1, 2 und 0,5 Hz. ableiten
TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); // Vorteiler 8
// Enable timer 1 interrupt -> ohne die anderen Bits zu verändern
TIMSK |= (1 << TOIE1);
sei(); //enable all interrupts
return 0;
}
//Funktion zum Abfragen des Zustands des negierenden Tasters1
int taster1(void)
{
if (PIND &(1 << PIND0))
{
return FALSE;
}
else
{
return TRUE;
}
}
//Funktion zum Abfragen des Zustands des negierenden Tasters2
int taster2(void)
{
if (PIND &(1 << PIND1))
{
return FALSE;
}
else
{
return TRUE;
}
}
//Funktion zum Abfragen des Zustands des negierenden Tasters3
int taster3(void)
{
if (PIND &(1 << PIND2))
{
return FALSE;
}
else
{
return TRUE;
}
}
int main(void)
{
// Port B Pin0, Pin1, Pin2 auf Ausgang setzen
DDRB |= (1 << PIN0) | (1 << PIN1) | (1 << PIN2);
// Port D Pin0, Pin1 und Pin2 (Taster 1, 2 3) als Eingänge setzen
DDRD &= ~((1 << PIN0) | (1 << PIN1) | (1 << PIN2));
Init_Timer1();
uint8_t taster1_alt = FALSE;
uint8_t taster2_alt = FALSE;
uint8_t taster3_alt = FALSE;
while (1)
{
if ((taster1() == TRUE) && (taster1_alt == FALSE))
{
if (taster1toggle == FALSE)
{
taster1toggle = TRUE;
// Sorgt dafür, dass Positionierungs-Ausgabe mit 2 s Pause startet:
BlinkArray1BZaehler = 0;
}
else
{
taster1toggle = FALSE;
}
}
taster1_alt = taster1();
if ((taster2() == TRUE) && (taster2_alt == FALSE))
{
if (taster2toggle == FALSE)
{
taster2toggle = TRUE;
// Sorgt dafür, dass Positionierungs-Ausgabe mit 2 s Pause startet:
BlinkArray2BZaehler = 0;
}
else
{
taster2toggle = FALSE;
}
}
taster2_alt = taster2();
if ((taster3() == TRUE) && (taster3_alt == FALSE))
{
if (taster3toggle == FALSE)
{
taster3toggle = TRUE;
// Sorgt dafür, dass Positionierungs-Ausgabe mit 2 s Pause startet:
BlinkArray3BZaehler = 0;
}
else
{
taster3toggle = FALSE;
}
}
taster3_alt = taster3();
_delay_ms(10);
}
return 0;
}