Nicht angemeldet. · Kennwort vergessen · Registrieren

yv21ipim
Mitglied seit 01/2013
7 Beiträge
Betreff: Klausur März 2010
Hier ein lösungsvorschlag, würde mich freun wenn jemand mal drüberschaun würde ;)

Schreiben Sie ein AVR-Mikrokontroller-Programm, das den Füllstand eines Tanks mit einem
Fassungsvermögen von 50000 Litern überwacht und insbesondere einen Überlauf verhindert.
Befüllung: Der Zufluss ist mit einer Zuflusssperre und einem Durchflusssensor ausgestattet.
Der Sensor signalisiert jeden durchgeflossenen Liter durch einen Interrupt. Der Zufluss kann
durch Aktivierung der Sperre gestoppt werden.
Entnahme: Der Abfluss ist durch einen manuellen Absperrhahn geregelt. Öffnen und Schliessen des Hahns werden durch Interrupt an den Controller gemeldet. Ein Durchflussensor
signalisiert jeden abgeflossenen Liter durch Zustandswechsel 0↔ 1 (Pollen!).
Das Programm soll im Einzelnen wie folgt funktionieren:
– Zum Programmstart ist der Tank leer und der Abfluss ist gesperrt.
– Die main-Funktion ruft zunächst die Funktion void init(); auf, welche die Initialisierung der I/O-Ports und Interruptquellen durchführt. Hierbei dürfen keine
Annahmen über den initialen Zustand der Register gemacht werden. Am Ende der
Initialisierung wird der Zufluss geöffnet.
– Stellt die Steuerung fest, dass der Tank voll ist, wird die Zuflusssperre aktiviert.
Sinkt die Tankfüllung unter 20000 Liter, wird wieder aufgefüllt.
– Während eines Abflusses überwacht die Steuerung die abfliessende Wassermenge
durch Pollen des Abflusssensors.
– Die Steuerung soll den Prozessor in den Standardstromsparmodus versetzen, wenn
gerade nichts zu tun ist.
Information über die Hardware
Zuflusssensor: PORTD, Pin 2
- steigende Flanke pro einfließendem Liter Wasser
- externe Interruptquelle 0, ISR-Vektor-Makro:INT0_vect
- Aktivierung der Interruptquelle erfolgt durch Setzen desINT0-Bits im Register GICR
Zuflusssperre: PORTD, Pin 0
- 1 = offen, 0 = gesperrt
Abflusshahn: PORTD, Pin 3
- 1 = offen, 0 = geschlossen (=> steigende Flanke = öffnen, fallende = schließen)
- externe Interruptquelle 1, ISR-Vektor-Makro:INT1_vect
- Aktivierung der Interruptquelle erfolgt durch Setzen desINT1-Bits im Register GICR
Abflusssensor: PORTD, Pin 1
- Zustandswechsel = 1 Liter Durchfluss
- Zustand kann durch Lesen von Bit 1 des Registers PIND abgefragt werden
Eingänge, Ausgänge, Externe Interruptquellen 0 bzw. 1 konfigurieren:
- Pin als Eingang konfigurieren: entsprechendes Bit in DDRD-Reg. auf 0
- Pin als Ausgang konfigurieren: entsprechendes Bit in DDRD-Reg. auf 1
- angeschlossene Sensoren verbinden den Pin mit Masse, es muss der interne
 Pullup-Widerstand verwendet werden (entspr. Bit in PORTD-Reg. auf 1 setzen).
- Konfiguration der externen Interruptquellen (Bits in Register MCUCR)

/* Funktiondeklarationen, globale Variablen, etc. */
static void init(void);
static volatile uint8_t event1 = 0;
static volatile uint8_t event2 = 0;
/* Unterbrechungsbehandlungsfunktionen */
ISR(INT0_vect){
    event1 = 1;
}
ISR(INT1_vect){
    event2 = (PIND >> PD3) & 1;
}
/* Funktion main */
void main(void){
    /* Initialisierung */
    init();
    uint16_t tankstand = 0;
    while(1){
        /* Warten auf Ereignisse */
        cli();
        while(!(event1|event2)){
            sei();
            sleep_enable();
            sleep_cpu();
            sleep_disable();
            cli();
        }
        sei();
        /* Abfluss überwachen */
        static uint8_t zustand = ((PIND >> PD1) & 1);
        cli();
        while(event1|event2){
            sei();
            if(tankzustand >= 50000){
                PORTD &= ~(1 << PD0);
            }
            if(tankzustand <= 20000){
                PORTD |= (1 << PD0);
            }
            tank += event1;
            event1 = 0;
            if(zustand ^((PIND >> PD1) & 1){
                tank --;
                zustand = ((PIND >> PD1) & 1);
            }
            cli();
        }
        sei();
    }
}
/* Ende der Funktion main */
/* Funktion init
 (teilweise vorgegeben, um Schreibaufwand zu sparen)*/
 static void init(void){
    DDRD |= (1 << PD0);
    DDRD &= ~(1 << PD1); /* Port1 als Eingang */
    DDRD &= ~(1 << PD2); /* Port2 als Eingang */
    DDRD &= ~(1 << PD3); /* Port3 als Eingang */
    PORTD &= ~(1 << PD0);
    PORTD |= (1 << PD1); /* Pullup aktivieren */
    PORTD |= (1 << PD2); /* Pullup aktivieren */
    PORTD |= (1 << PD3); /* Pullup aktivieren */
    MCUCR |= (1 << ISC01)|(1 << ISC00)|(1 << ISC10);
    MCUCR &= ~(1 << ISC11);   
}
Schließen Kleiner – Größer + Auf diesen Beitrag antworten:
Prüfcode: VeriCode Gib bitte das Wort aus dem Bild ins folgende Textfeld ein. (Nur die Buchstaben eingeben, Kleinschreibung ist in Ordnung.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O :troll:
Weitere Zeichen:
Gehe zu Forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen