Not logged in. · Lost password · Register

All posts by yv21ipim (7)

topic: Klausur 2010 (Aufgabe 1a))  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
Subject: Klausur 2010
Gegeben sei folgende Deklaration in einem C-Programm:
typedef void (*func)(int, int);
Welche Aussage ist richtig?
❏ func ist ein Funktionszeiger auf eine void-Funktion, die zwei
int-Parameter erwartet.
❏ func ist Datentyp für Funktionszeiger auf void-Funktionen, die zwei int-Parameter erwarten.
❏ func ist eine Funktion, die hier durch forward-Deklaration dem Compiler
bekannt gegeben wird.
❏ Der Compiler meldet einen Fehler, weil bei der Deklaration von func die Namen
der formalen Parameter fehlen.


was ist hier richtig?
topic: Klausur März 2012 Aufgabe 2a (dimmer)  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
In reply to post ID 6144
Subject: weiter Lösungsvorschlag
/* Funktionsdeklarationen, globale Variablen, etc. */
static void init(void);
static void wait(uint16_t us);
static volatile uint8_t stufe = 0;
static volatile uint8_t position = 0;
/* Funktion main */
void main(void){
    /* Initialisierung und lokale Variablen */
    init();
    /* Hauptschleife */
    while(1){
        /* Schlafen */
        cli();
        while(!stufe){
            sei();
            sleep_enable();
            sleep_cpu();
            sleep_disable();
            cli();
        }
        /* LED ansteuern */
        while(stufe){
            sei();
            PORTA |= (1 << position);
            wait(stufe/10*512);
            PORTA = 0xff;
            wait(512*(1-stufe/10));
            cli();
        }
        sei();
    }
}
/* Ende Funktion main */
/* Initialisierungsfunktion */
static void init(void){
    DDRA |= 0xff;
    PORTA |= 0xff;
    DDRD &= ~((1 << PD2)|(1 << PD3));
    PORTD |= (1 << PD2)|(1 << PD3);
    MCUCR |= (1 << ISC01)|(1 << ISC11);
    MCUCR &= ~((1 << ISC00)|(1 << ISC10));
    GICR |= (1 << INT0)|(1 << INT1);
    sei();
}
/* Wartefunktion */
static void wait(uint16_t){
    volatile uint16_t i = 0;
    while(i < us * LOOPS_PER_US){
        i++;
    }
}
/* Unterbrechungsbehandlung */
ISR(INT0_vect){
    if((stufe <= 0)|(stufe >= 10)) {
        stufe = 1;
        position = (position++)%8;
    } else {
        stufe++;
    }
   
]
ISR(INT1_vect){
    if(stufe > 0) {
        stufe--;
    }
}
topic: Klausur März 2010 (Aufgabe 2: Tankkontrolle)  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
Subject: 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);   
}
topic: Klausur Juli 2010 (Aufgabe 2: Würfel)  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
Subject: Klausur Juli 2010
wieder mal ne Aufgabe - wäre nett wenn jemand mal drüberschaun könnte und villt einen Kommentar dazu geben könnte ;)

reiben Sie ein Würfelprogramm für den AVR-Mikrocontroller, welches die gewürfelten
Zahlen auf einem LED-Feld anzeigt. Der Würfel soll eine Zahl im Intervall [1; n] anzeigen,
wobei der Höchstwert n durch den Benutzer festgelegt werden soll (Maximum: 8, Anfangswert: 1). Ihr Programm soll sich in zwei Phasen gliedern:
Phase 1: Initialisierung des Höchstwerts
– In einer Schleife wird der Wert n jeweils um 1 hochgezählt (nach der 8 folgt wieder
die 1); gleichzeitig wird der Wert n durch den Füllstand der LEDs angezeigt (Beispiel: n == 3, LEDs 1-3 leuchten).
– Zwischen den Inkrementschritten wartet das Programm für 1000 Schleifendurchläufe in einer aktiven Warteschleife (Funktion void wait(void);).
– Durch Drücken von BUTTON0 wird die Initialisierung abgeschlossen; der aktuelle
Wert n wird dadurch als Höchstwert für die anschließende Würfelphase festgelegt.
Phase 2: Würfelphase
– In der Würfelschleife soll das Programm die Zahlen im Intervall [1; Höchstwert]
direkt nacheinander auf den LEDs darstellen (ohne Wartezeit, dadurch für das Auge
kaum erkennbar). Eine Zahl wird dadurch dargestellt, dass nur die entsprechende
LED angeschaltet wird; die restlichen LEDs sind ausgeschaltet.
– Wenn der Benutzer nun BUTTON0 drückt, hält das Programm an und die gerade
leuchtende LED gilt als gewürfelt. Das Programm wartet auf einen weiteren Tastendruck (Schlafmodus!).
– Durch einen erneuten Druck auf BUTTON0 wird die Würfelschleife wieder fortgesetzt, bis durch einen weiteren Druck auf BUTTON0 wieder angehalten wird. Dies
wird endlos so fortgesetzt.
Informationen zur Hardware und Bibliothek:
– Zur LED-Ansteuerung stehen Ihnen keine Bibliotheksfunktionen zur Verfügung. Die
8 LEDs hängen an Port C und sind active low. Zur Konfiguration als Output-Pin
müssen Sie das entsprechende Bit im DDRC-Register auf 1 setzen; zur Ausgabe
eines High-Pegels müssen Sie das entsprechende Bit im PORTC-Register auf 1 setzen.
– Der Taster ist hardwareseitig entprellt. Um eine Callback-Funktion für BUTTON0
zu registrieren, gehen Sie davon aus, dass Ihnen die folgende Bibliotheksfunktion
zur Verfügung steht:
void registerCallbackButton0(void (*callback)(void));
Als Parameter erhält diese Funktion den Namen Ihrer Callback-Funktion, die dann
automatisch aus dem Interrupthandler aufgerufen wird, wenn der Taster gedrückt
wird.
– Programmieren Sie die Hardwareinitialisierung in einer Funktion
 void init(void);

/* Funktionendeklaration, globale Variablen, etc. */
void registerCallbackButton0(void (*callback)(void));
static void init(void);
static void btnpressed(void);
static volatile button0 = 0;
/* Funktion main */
void main(void) {
    /* Aufruf der Hardware-Initialisierung und Initialisierung der Callback-Funktion */
    init();
    registerCallbackButton0(&btnpressed);
    /*Initialisierungsphase */
    uint8_t max = 0;
    cli();
    while(button0 == 0){
        sei();
        PORTC &= ~(1 << max);
        max = (max ++)%8;
        wait();
        if(max == 0) {
            PORTC = 0xff;
        }
        cli();
    }
    /* Wuerfelphase */
    while(1){
        button0 = 0;
        uint8_t pos = 0;
        while(!button0){
            sei();
            PORTC &= ~(1 << pos);
            pos = (pos ++)%(max+1);
            if(pos == 0) {
                PORTC = 0xff;
            }
            cli();
        }
        PORTC = 0xff;
        sei();
        button0 = 0;
        cli();
        while(!button0) {
            sei();
            sleep_enable();
            sleep_cpu();
            sleep_disable();
            cli();
        }
    }
/* Ende der main-Funktion */

/* Initialisierungsfuntion */
static void init(void) {
    DDRC = 0xff;
    PORTC = 0xff;
    sei();
}

/* Wartefunktion */

/* Callbackfunktion fuer BUTTON0 */
static void btnpressed(void){
    button0 = 1;
}
topic: Klausur Juli 2009 (Aufgabe 2: Tankkontrolle)  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
Subject: Klausur Juli 2009
Hier ein möglicher Lösungsvorschlag; kann jemand mal drüberschaun? wäre nett ;)

Schreiben Sie ein AVR-Mikrokontroller-Programm zur Kontrolle eines Wassertanks mit
einem Fassungsvermögen von 60000 Litern. Der Zufluss wird über ein Ventil geregelt, welches sich im entsperrten Zustand bei eintreffendem Wasser automatisch öffnet und bei versiegendem Wasser wieder schließt. Öffnen (fallende Flanke) und Schließen (steigende
Flanke) des Ventils werden dem Mikrokontroller hierbei über eine Interruptleitung signalisiert. Beim Erreichen eines vollen Tanks sperrt die Steuerung das Zuflussventil. Die Wasserentnahme erfolgt durch eine externe Steuerung, welche an einer Interruptleitung jeweils nach
jedem entnommenen Liter eine fallende Flanke generiert.
Das Programm soll im Einzelnen wie folgt funktionieren:
– Zu Beginn ist der Tank leer und es fließt kein Wasser (Ventil geschlossen).
– 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.
– Die Steuerung soll den Prozessor in den Standardstromsparmodus versetzen, wenn
gerade nichts zu tun ist.
– Während eines Zuflusses überwacht die Steuerung die in den Tank strömende Wassermenge. Hierzu können Sie eine Schleife verwenden und vereinfachend annehmen, dass zu jedem Schleifendurchlauf ein Liter Wasser in den Tank strömt
(unabhängig vom Inhalt der Schleife). Beim Erreichen der maximalen Tankfüllung
sperrt die Steuerung das Ventil (Ausgangspegel: 0=entsperrt, 1=gesperrt).
– Eine Wasserentnahme ist jederzeit möglich und entsprechende Signale sollen so
zuverlässig wie möglich verarbeitet werden. Sobald wieder Platz im Tank frei ist
wird das Ventil wieder entsperrt.
Information über die Hardware
Ventilsignal: PORTD, Pin 2
- externe Interruptquelle 0, ISR-Vektor-Makro: INT0_vect
- Aktivierung der Interruptquelle erfolgt durch Setzen des INT0-Bits im Register GICR
Ventilsperre: PORTD, Pin 0
- Pin als Ausgang konfigurieren: entsprechendes Bit in DDRD-Reg. auf 1
Entnahmesignal: PORTD, Pin 3
- externe Interruptquelle 1, ISR-Vektor-Makro: INT1_vect
- Aktivierung der Interruptquelle erfolgt durch Setzen des INT1-Bits im Register GICR
Externe Interruptquelle 0 bzw. 1 konfigurieren:
- Pin als Eingang konfigurieren: entsprechendes Bit in DDRD-Reg. auf 0
- angeschlossenes Gerät verbindet 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)

/* Funktionsdeklaration, globale Variablen, etc. */
static void init(void);
static volatile entnahme = 0;
static volatile event = 0;
static volatile ventilzustand = 0;
/* Unterbrechungsbehandlungsfunktion */
ISR(INT1_vect){
    entnahme =1;
}
ISR(INT0_vect){
    event = 1;
    ventilzustand = !((PIND && (1<<2));
}

/* Funktion main */
void main (void){
/* Initialisierung */
    init();
    uint16_t tankstand = 0;
    while(1){
/* Warten auf Ereignis */
        cli();
        while(!(event|entnahme)){
            sleep_enable();
            sei();
            sleep_cpu();
            sleep_disable();
            cli();
        }
        sei();
/* Zufluss überwachen */
        while(ventilzustand|entnahme) {
            cli();
            if(ventilstand) {
                sei();
                tankstand++;
            }
            cli();
            if(entnahme){
                sei();
                tankstand--;
            }
            sei();
            if(tankstand >= 60000u) break;
            event = 0;
            entnahme = 0;
        }
        if(tankstand >= 60000u){
            PORTD |= (1<<0);
        }
    }
}
/* Ende der Funktion main */
/* Funktion init*/
static void init(void) {
    DDRD |= 1;
    DDRD &= ~((1<<2)|(1<<3));
    PORTD |= 0x7;
   
    MCUCR |=  (1<<ISC00)|(1<<ISC11);
    MCUCR &= ~((1<<ISC01)|(1<<ISC10));
    GICR |= (1<<INT0)|(1<<INT1);
    sei();
}
topic: Klausur Juli 2012 (Aufgabe 2a: safe)  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
Subject: Klausur Juli 2012
Lösungsvorschlag - wäre nett wenn jemand mal drüberschaun kann ;)

Aufgabenstellung:
Schreiben Sie eine Steuerung für einen AVR-Mikrocontroller in einem Safe, der mit einem
8-stelligen Binärschlüssel gesichert ist. Der Code wird während der Eingabe durch LEDs
visualisiert.
Die Eingabe des Schlüssels erfolgt mit Hilfe von zwei Tastern, die entsprechend mit "0"
(Taster 0) und "1" (Taster 1) beschriftet sind. Jede der 8 Stellen des Schlüssels wird durch
den Benutzer nacheinander durch Drücken eines der beiden Taster eingegeben. Die 8 LEDs
visualisieren den eingegebenen Schlüssel, so dass die LEDs nach der Eingabe jeder Stelle
den bisher eingegebenen Binärcode anzeigen.
Nach der achten eingegebenen Stelle wird der Schlüssel mit einer gegebenen statischen Konstante SECRET verglichen. War die Eingabe erfolgreich, öffnet sich das Schloss für eine
Gesamtdauer von 5 Sekunden während alle LEDs mit einer Periodendauer von einer
Sekunde (1000 ms) blinken, dann schließt das Schloss wieder. Nach dieser Sequenz oder im
Fall eines falschen Schlüssels startet die Eingabe des Schlüssels wieder von vorne.
Im Detail soll Ihr Programm wie folgt funktionieren:
– Initialisieren Sie die Hardware in der Funktion void init(void).
– Das Programm startet mit allen LEDs ausgeschaltet, das Schloss ist geschlossen und
die Eingabe des Benutzers wird erwartet. Während des Wartens auf eine Eingabe soll
der Mikrocontroller jeweils in den Schlafmodus gehen.
– Implementieren Sie das Blinken der LEDs während der Öffnung des Safes unter Verwendung einer aktiven Wartefunktion void wait(uint16_t ms), die ms Millisekunden wartet. Ihnen steht eine PräprozessorkonstanteLOOPS_PER_MS zur Verfügung, die
angibt, wieviele Schleifendurchläufe gewartet werden muss, um eine Millisekunde
verstreichen zu lassen.
Information über die Hardware
LEDs: PORTA, Pins 0-7, Start bei LED 1 an Pin 0, eingeschaltet bei low-Pegel
- Pin als Ausgang konfigurieren: entsprechendes Bit in DDRA-Register auf 1
Schloss: PORTB, Pin 5, offen bei high-Pegel, geschlossen bei low-Pegel
- Pin als Ausgang konfigurieren: entsprechendes Bit in DDRB-Reg. auf 1
Taster: PORTD, "Null"-Taster (Taster 0) = Pin 2, "Eins"-Taster (Taster 1) = Pin 3
- Pin als Eingang konfigurieren: entsprechendes Bit in DDRD-Register auf 0
- externe Interruptquellen INT0 und INT1, ISR-Vektor-Makros:INT0_vect und INT1_vect
- Aktivierung der Interruptquellen erfolgt durch Setzen desINT0- bzw.INT1-Bits
im Register GICR.
- die Taster verbinden den Pin mit Masse, es müssen die internen Pullup-Widerstände
verwendet werden (entsprechende Bits in PORTD-Register auf 1 setzen).
- Konfiguration der externen Interruptquellen 0 und 1 (Bits in Register MCUCR)



/* Funtionsdeklaration, globale Variablen, etc. */
static void init(void);
static void wait(uint16_t ms);
volatile uint8_t event = 0;
volatile uint8_t taster = 0;

/* Unterbrechungsbehandlungsfunktionen */
ISR(INT0_vect) {
    event = 1;
    taster = 0;
}
ISR(INT1_vect) {
    event = 1;
    taster = 1;
}

/* Funktion main */
void main(void){
    /*Initialisierung und lokale Variablen */
    init();
    uint8_t position = 0;
    /* Hauptschleife */
    while(1) {
        /* Code-Eingabe */
        while(pos < 8) {
            cli();
            while(event == 0){
                sleep_enable();
                sei();
                sleep_cpu();
                sleep_disable();
                cli();
            }
            sei();
            portA |= (taster<<pos);
            pos++;
            event = 0;
        }
        /* Schloss oeffnen, naechster Durchlauf */
        if(!(SECRET ^ PORTA)) {
        uint8_t i = 0;
        PORTA = 0xff;
        PORTB |= (1<<5);
        while(i < 5){
            PORTA = ~(0xff);
            wait(500);
            PORTA = 0xff;
            wait(500);
            i++;
        }
        PORTB &= ~(1<<5);   
        }
        event = 0;
    }
}

/* Initialisierungsfunktion */
static void init(void) {
    DDRA |= 0xff;
    PORTA |= 0xff;
   
    DDRB |= (1<<5);
    PORTB &= ~(1<<5);
   
    DDRD &= ~((1<<2)|(1<<3));
    PORTD |= (1<<2)|(1<<3);
    MCUCR |= (1<<ISC01)|(1<<ISC11);
    MCUCR &= ~((1<<ISC11)|(1<<ISC01));
    GICR |= (1<<INT0)|(1<<INT1);
   
    sei();
}
/* Wartefunktion */
static void wait(uint16_t ms) {
    volatile uint16_t i = 0;
    while(i < ms*LOOPS_PER_MS) {
        i++;
    }
}
topic: Klausur Juli 2012 (Aufgabe 3 d))  in the forum: 2. Semester Grundlagen der systemnahen Programmierung in C
yv21ipim
Member since Jan 2013
7 posts
Subject: Klausur Juli 2012
Worin besteht der Unterschied zwischen einer globalen static-Variable und einer
lokalen static-Variable in Bezug auf Nebenläufigkeit zwischen einem Programm
und einem Interrupt-Handler?

Frage: Kann ein Interupt-Handler eigentlich auf lokale static Variablen zugreifen???
was wäre hier die richtige Antwort?

Danke schon einmal im Voraus :)
Close Smaller – Larger + Reply to this post:
Special characters:
Go to forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen