Jalousiensteuererung soll mit Schaltwerk realisiert werden in ein Schaltwerk gehen diese Signale rein:
Endschalter TO (oben), TU (unten) und Taster TH (hoch) TR (runter) und WA (Windalarm). Signale pos. Logik.
Ausgänge sind MH (Motor hoch) und MR (Motor runter).
Verwirrend könnte in der Aufgabenstellung die Vorgabe von einem Zustand Z0 mit else-Transition sein. Zustände sollten möglichst aussagekräftig benannt werden. Nur Transitionen, die aus einem Zustand herausführen müssen angegeben werden.
Else-Transitionen, die im selben Zustand verbleiben sind meiner Auffassung nach sinnfrei.
WA | TH | TR | TO | TU | n akt. Zustand |
n+1 folg. Zustand |
---|---|---|---|---|---|---|
0 | 0 | 1 | x | 0 | Ruhe (Z0) | Runter |
0 | 1 | 0 | 0 | x | Hoch | |
1 | x | x | 0 | x | Hoch | |
else | Ruhe | |||||
x | x | x | 0 | x | Hoch (Z1) | Hoch |
x | x | x | 1 | x | Ruhe | |
x | x | x | x | 0 | Runter (Z2) | Runter |
x | x | x | x | 1 | Ruhe |
In der Zustandsübergangstabelle müssen alle vorkommenden Eingangs-Kombinationen des Vorbereitungsschaltnetzes aufgeführt sein.
Durch die x auf der linken Seite können Zeilen zusammengefasst werden, dabei müssen die damit erfassten Kombinationen disjunkt zu den anderen Zeilen bleiben, es darf keine Kombination doppelt erfasst werden. Im Lösungsvorschlag ist dies geschehen, an der grünen Stelle in der Tabelle steht dort ein x, hier wurde dafür eine 0 verwendet um die Überschneidung zu vermeiden.
Mit der else-Zeile werden alle restlichen Kombinationen für Ruhe erfasst.
Hier nicht erfasste weitere Kombinationen werden als Dont-Care zur Minimierung verwendet.
Verwendeter µC: ATMEL AVR 8 Bit RISC.
Systemtakt 1MHz Zylkuszeit 1µs.
TA (auf) | PB1 | MC | PC3 | L3 | Motor |
TZ (zu) | PB0 | PC2 | L2 | ||
PC1 | L1 | ||||
PC0 | L0 | ||||
SN (Nacht) | PD3 (INT1) | ||||
ST (Tag) | PD2 (INT0) | ||||
SZ (zu) | PD1 | ||||
SO (offen) | PD0 |
unsigned char tab[] = {0b1001,0b110,0b0110,0b0011};
Hardwaretimer ohne ISR verwenden. 16 Bit Timer1 mit Systemtakt 1µs auf 19999 zählen lassen, dabei pollen.
void warten20ms(){ TCNT1=0; // Zähler auf 0 TCCR1B |= 1; // rennt mit Systemtakt while(TCNT1 < 19999); // warten }
Lösung mit 8 Bit Timer 0: 20000/256 = 78,125. Vorteiler Takt / 256, Timer zählt dann 78 Schritte.
void warten20ms(){ TCNT0 = 0; // Zähler auf 0 TCCR0B |= 4; // Systemtakt / 256 while(TCNT0<77); // warten 0..77 }
Lösung mit 16 Bit Timer und Abfrage Vergleichsflag, entspricht dem Lösungsvorschlag.
void warten20ms(){ TCNT1 = 0; // Zähler löschen TCCR1B |= 1; // Zähler rennt mit Systemtakt OCR1A = 19999; // Vergleichsregister setzen TIFR &= ~(1<<OCF1A); // Vergleichsflag löschen while(!(TIFR&(1<<OCF1A))); // warten bis Flag gesetzt }
Globale Variable: unsigned char index
void init(){ MCUCR |= (1<<ISC01) | (1<<ISC11); // fallende Flanken GIMSK |= (1<<INT0) | (1<<INT1); // Interrupts einschalten sei(); // globale ISR Freigabe }
ISR(INT0_vect){ ganzOeffnen(); } ISR(INT1_vect)( ganzSchliessen(); }
Mit Polling auf den Timerwert oder dem Timervergleichs- oder Überlaufflag ist das Hauptprogramm während dieser Zeit blockiert. Bei einer ISR-Lösung mit Timerinterrupt wird das Hauptprogramm nur kurz zum Weiterschalten der Schritte unterbrochen.
Soll Strom gespart werden, wäre eine ISR-Lösung die Vorraussetzung den µC auch während der 20ms zwischen den Schritten in den Schlafmodus schicken zu können, beim Polling müsste er wach bleiben.