MezData-Logo Creative Commons License 264 :AVR: Garagentorsteuerungssimulationr

Schlüsselwörter: Atmel, AVR, Assembler, TGIT, Mikrokontroller, C

Problemstellung

Mit dem STK200 (ATtiny2313 @ 1MHz) soll die Simulation einer Garagentorsteuerung erstellt werden:

Garagentorsteuerungssimulation

PD 3 2 1 0
Funktion Handsender Zu Stopp Auf
Beschreibung Stopp-Auf-Stopp-Zu... Tor schließen NotStopp Tor öffnen

 

Das Tor wird mit einem Leuchtband LED6..LED0 an PB dargestellt. Bei Tor zu leuchten LED6..0, bei Tor offen leuchtet nur LED0.
LED7 blinkt beim Fahren des Tors. Beim Fahren wechselt die LED7 nach 150ms ihren Zustand. Nach 4 Zustandswechseln wird eine Leuchtbands-LED mehr oder weniger geschaltet, je nach Fahrrichtung.

Schlüsselschalter

An PD2 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 PD1 ist der NotStopp angeschlossen. Bei diesem Signal stoppt das Tor.

An PD3 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 Variable position, für die Position des Tors: 0=offen; 6=zu

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

Die Operation ausLed(n:Byte) schaltet die LED an PBn aus.

Die Operation toggleLed(n:Byte) ändert den Zustand an PBn.

Die Operation ausgebenPosition() gibt entsprechend der position das Leuchtband aus.

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

 

 

Zustandsdiagramm (mit Schülern entwickeln)

Zustandsdiagramm

Aufzählungsdatentyp enum

Um den Quellcode besser lesbar zu machen, ist es wünschenswert statt Zahlen 0,1,2 für zustand aussagekräftige Namen vergeben zu können. 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

Quellcode [checkKeys.h]
#ifndef CHECKKEYS_H_INCLUDETD    // notwendig um Doppeldeklarationen zu vermeiden
#define CHECKKEYS_H_INCLUDETD

unsigned char keyEnter,keyExit; // gedrueckte und losgelassene Tasten 

void checkKeys(unsigned char keyMask,unsigned char keyNlogik); // Maske, neg.Logik  

#endif
Quellcode [checkKeys.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // CPU Frequenz einstellen! 
#include "checkKeys.h"

void checkKeys(unsigned char keyMask,unsigned char keyNlogik){// Maske, neg.Logik
  static unsigned char keyOld = 0;
  unsigned char keyTest,tmp; 
  keyEnter = 0, keyExit = 0; 
  keyTest = (PIND^keyNlogik)&keyMask; // Einlesen
  if (keyOld != keyTest){             // hat sich was getan 
    _delay_ms(20);                    // Prellen abwarten 
    tmp = (PIND^keyNlogik)&keyMask;   // noch mal Einlesen
    if (tmp == keyTest){              // ist es stabil? 
      keyEnter = (~keyOld) & keyTest; // steigende Flanke !alt und neu 
      keyExit = keyOld & (~keyTest);  // fallende Flanke alt und !neu 
      keyOld = keyTest; 
    } 
  } 

Hauptprogramm-Vorgabe

Quellcode [Garagentorsteuerung-Vorgabe.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // CPU Frequenz einstellen!

#include "checkKeys.h"   // checkKeys verwenden

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

unsigned char position; // Position der Schranke
unsigned char blinker;  // Zaehler fuer Blinken

void ausLed(unsigned char n){    // LED n ausschalten
  // Aufgabe 1
}
void toggleLed(unsigned char n){ // LED n umschalten
  // Aufgabe 2
}

void ausgebenPosition(){ // Leuchtband ausgeben
  unsigned char i,a=1;
  // Aufgabe 3
}

void fahren(){   // in Richtung fahren, dabei Blinken
  blinker++;
  toggleLed(7);
  _delay_ms(150);
  if(blinker%4==0){
    // Aufgabe 4
  }
}

void init(){          // Initialisierung der Variabeln hier, wegen Struktogramm fuer init
  PORTB = 0xff;       // alle LED aus 
  DDRB = 0xff;        // PB als Ausgang
  zustand  = STOPP;
  richtung = ZU;
  position = 0;
  blinker  = 0;
  ausgebenPosition();
}

int main(){         // Hauptprogramm 
  init();
  while(1){         // Endlosschleife 
    checkKeys(0b1111,0b1111); // Maske,NLogik PD3..PD0
    switch (zustand){         // in Abhaengigkeit des Zustands
      case STOPP:  // 0
        if(keyEnter==1 || (richtung==ZU && keyEnter==0b1000)){  // Transitionen pruefen
          richtung=AUF;
          zustand=AUF;
        }
        else if(keyEnter==0b100 || (richtung==AUF && keyEnter==0b1000)){
          richtung=ZU;
          zustand=ZU;
        }
        break;
      case AUF:  // 1
        if(position==0 || keyEnter > 0b1){  // Transitionen pruefen
          zustand=STOPP;
          ausLed(7);                        // exit Aktion
        }
        else{                               // do Aktionen
          fahren();
        }
        break;
      case ZU:  // 2
        // Aufgabe 5
      break;
    }
  } 
  return 0; 

Aufgabenstellungen

Ergänzen Sie den Quellcode für:

ausLed(unsigned char n) schaltet die LED an PBn aus.

toggleLed(unsigned char n) ändert den Zustand an PBn

ausgebenPosition() gibt entsprechend der position das Leuchtband aus

fahren(unsigned char n)

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

main(), den Zustand ZU

Lösung anzeigen..