Not logged in. · Lost password · Register

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;
}
killermiller
Member since May 2011
41 posts
Die beiden Sachen, die mir auffallen:
Pointer auf eine Funktion kriegst du, indem du einfach den Namen der Funktion hinschreibst, ohne Klammern und ohne &.
Also in diesem Fall
registerCallbackButton0(btnpressed);

Und man könnte an der Stelle hier
    /* Wuerfelphase */
    while(1){
        button0 = 0;
        uint8_t pos = 0;
die Interrupts für die drei Zeilen freigeben.

Der Rest sieht gut aus...
muffdey
Member since Apr 2012
12 posts
"Eine Zahl wird dadurch dargestellt, dass nur die entsprechende
LED angeschaltet wird; die restlichen LEDs sind ausgeschaltet."   Werden in der Würfelphase in diesem Code nicht mehrere LED's für einen Wert angezeigt?

Wird button0 gepressed  (button0=1) springt das Programm aus der while(!button0) Schleife und schaltet alle LED's aus ( PORTC = 0xff;). Laut Aufgabenstellung soll  aber der gewürfelte Wert (bzw die LED) angezeigt werden. Ist das hier falsch oder habe ich etwas übersehen?

Grüße

Muffdi
This post was edited 3 times, last on 2015-03-18, 17:12 by muffdey.
muffdey
Member since Apr 2012
12 posts
Hey, sind soviele sei(); cli() notwendig? Hier wurde das ja bei jedem Betreten einer neuer Schleife verwendet. Bei anderen Aufgabenlösungen in diesem Forum wurde das nicht so gemacht und keiner hat dazugeschrieben das es richtig oder falsch ist. Wird das in der Klausur kritisch bewertet wenn man außerhalb der Schlaffunktion sei/cli zu viel/wenig hat?

(Ich weiß die Chancen sind gering das heute noch wer was dazu schreibt aber versuchen kann man es ja ;))

Grüße

muffdey
il66ifix
Member since May 2011
109 posts
Wenn du sie richtig setzt und nen Kommentar dahintermachst, warum du sie hier gesetzt hast (zB //weil neue Schleife und Interruptzustand unbekannt), wird man dir nicht den Kopf abreißen :)
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O :troll:
Special characters:
Go to forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen