MezData-Logo

Garagentorsteuerungssimulation

Garagentorsteuerungs-Simulation

SchemaMit dem Zylonenauge @ 1MHz soll die Simulation einer Garagentorsteuerung erstellt werden:

Taster T2 T1 T0
Funktion Handsender Zu Auf
Beschreibung Stopp-Auf-Stopp-Zu... Tor schließen Tor öffnen

Das Tor wird mit einem Leuchtband LED15..LED0 dargestellt. Bei Tor zu leucht LED15, bei Tor offen leuchtet LED0.
Die LED blinken beim Fahren des Tors. Beim Fahren ist die PositionsLED 30ms aus und 40ms an. Nach 4 Zustandswechseln wird eine LED weiter geschaltet, je nach Fahrrichtung.

Schlüsselschalter

An PD1 und PD0 ist ein Schlüsselschalter angeschlossen, mit dem das Tor geschlossen und geöffnet werden kann. Wird bei fahrendem Tor der Schalter in die Gegenrichtung betätigt stoppt das Tor, erst bei erneuter Betätigung läuft es in die Gegenrichtung.

An PD2 ist ein Handsenderempfänger angeschlossen. Bei Betätigung wird ein fahrendes Tor gestoppt. Ein gestopptes Tor wird in die Gegenrichtung der vorherigen Fahrt gestartet.

Vorgaben (mittels Klassendiagramm)

KlassendiagrammZur Erleichterung einer systematischen Problemlösung sei gegeben:

Eine globale Variable zustand, die die Zustände STOPP,AUF,ZU annehmen kann.

Eine globale Variabel richtung, die den Wert AUF oder ZU annehmen kann.

Eine globale VariablesOrt, für die Position des Tors: 0=offen; 15=zu

Die globale Variable blinker soll beim Fahren alle 70ms um 1 erhöht werden.

Die Operation fahren() erhöht den blinker, lässt die sOrt-LED blinken und verändert bei jedem 4. Aufruf die Postion des Tors entsprechend der Richtung.

Zustandsdiagramm (mit Schülern entwickeln)

Zustandsdiagramm

Aufzählungsdatentyp enum

Der Quellcode ist besser lesbar wenn statt Zahlen 0,1,2 für zustand aussagekräftige Namen vergeben werden. Mit dem Aufzählungsdatentyp enum ist dies möglich. Es kann sogar ein eigener wiederverwendbarer Datentyp mittels typedef definiert werden.

//enum {STOPP,AUF,ZU} zustand=STOPP,richtung=ZU; // Aufzaehlungstyp
typedef enum {STOPP,AUF,ZU} ZustandTyp; // Aufzaehlungstyp
ZustandTyp zustand;
ZustandTyp richtung;

Quellcode

Tastaturabfragen [checkKeys.h]
#ifndef CHECKKEYS_H_INCLUDETD // vermeide Doppeldeklarationen
#define CHECKKEYS_H_INCLUDETD
 
#ifdef __cplusplus
extern "C" {
#endif
unsigned char keyEnter,keyExit; // gedr. und losgel. Tasten 
 
void checkKeys(); // Maske, neg.Logik 
 
#ifdef __cplusplus
} // extern "C"
#endif
#endif
Tastaturabfragen [checkKeys.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // CPU Frequenz einstellen! 
#include "checkKeys.h"
 
void checkKeys(){// Maske, neg.Logik
  static unsigned char keyOld = 0;
  unsigned char keyTest,tmp; 
  keyEnter = 0, keyExit = 0; 
  keyTest =  ~PIND>>4; // Einlesen
  if (keyOld != keyTest){             // hat sich was getan 
    _delay_ms(20);                    // Prellen abwarten 
    tmp = ~PIND>>4;;   // noch mal Einlesen
    if (tmp == keyTest){              // ist es stabil? 
      keyEnter = (~keyOld) & keyTest; // steig. Fl. !alt & neu 
      keyExit = keyOld & (~keyTest);  // fall. Fl. alt & !neu 
      keyOld = keyTest; 
    } 
  } 
}
Hauptprogramm Vorgabe [zGarage-Vorgabe.ino]
  1. #include <avr/io.h> // Definitionen laden
  2. #include <util/delay.h> // CPU Frequenz einstellen!
  3.  
  4. #include "checkKeys.h" // checkKeys verwenden
  5. unsigned char ledausgabe[]={0xe1,0xe2,0xe4,0xe8,0xd1,0xd2,
  6. 0xd4,0xd8,0xb1,0xb2,0xb4,0xb8,0x71,0x72,0x74,0x78};
  7.  
  8. typedef enum {STOPP,AUF,ZU} ZustandTyp; // Aufzaehlungstyp
  9. ZustandTyp zustand;
  10. ZustandTyp richtung;
  11.  
  12. unsigned char sOrt; // sOrt der Schranke
  13. unsigned char blinker; // Zaehler fuer Blinken
  14.  
  15. void fahren(){ // in Richtung fahren, dabei Blinken
  16. blinker++;
  17. PORTB=0;
  18. _delay_ms(30);
  19. if(blinker%4==0){
  20. // Aufgabe 6.1
  21. }
  22. PORTB = ledausgabe[sOrt];
  23. _delay_ms(40);
  24. }
  25.  
  26. void init(){ // Initialisierung der Variabeln hier, wegen Struktogramm fuer init
  27. DDRB = 0xff; // PB als Ausgang
  28. PORTD = 0x7f; // Pullups an
  29. zustand = STOPP;
  30. richtung = ZU;
  31. sOrt = 0;
  32. blinker = 0;
  33. PORTB = ledausgabe[sOrt];
  34. }
  35.  
  36. int main(){ // Hauptprogramm
  37. init();
  38. while(1){ // Endlosschleife
  39. checkKeys(); // Maske,NLogik PD3..PD0
  40. switch (zustand){ // in Abhaengigkeit des Zustands
  41. case STOPP: // 0
  42. if(keyEnter==1 || (richtung==ZU && keyEnter==0b100)){ // Transitionen pruefen
  43. richtung=AUF;
  44. zustand=AUF;
  45. }
  46. else if(keyEnter==0b10 || (richtung==AUF && keyEnter==0b100)){
  47. richtung=ZU;
  48. zustand=ZU;
  49. }
  50. break;
  51. case AUF: // 1
  52. if(sOrt==0 || keyEnter > 0b1){ // Transitionen pruefen
  53. zustand=STOPP;
  54. }
  55. else{ // do Aktionen
  56. fahren();
  57. }
  58. break;
  59. case ZU: // 2
  60. // Aufgabe 6.2
  61. break;
  62. }
  63. }
  64. }

Aufgabenstellungen

Ergänzen Sie den Quellcode für:

fahren(unsigned char n)

Erhöht den blinker, lässt die Positions-LED blinken und verändert bei jedem 4. Aufruf die Postion des Tors entsprechend der Richtung.

main(), den Zustand ZU

Lösung anzeigen..