Not logged in. · Lost password · Register
Forum: Grundstudium 2. Semester Informatik (GDI II) SPiC RSS
April-2009-Aufgabe 2a
Dani #1 -- for 2 months · 8 posts
Show profile · Link to this post
Subject: April-2009-Aufgabe 2a
Hi,
ich habe mal die Klausuraufgabe 2a vom April 2009 durchgearbeitet.
Wär echt super wenn sich jemand mal meine Lösung durchschaut und auf Fehlern überprüft :)
Vielen Dank schonmal
lg Dani :)

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/sleep.h>
  4.  
  5. #define NUMLED 6
  6.  
  7.  
  8. /*Funktionsdeklarationen, globale Variablen, tec. */
  9.  
  10. volatile static in laenge;  /*länge der Schlange*/
  11. volatile static in running; /*Findet gerade eine Umrandung statt?*/
  12. volatile static in interrupt;   /*gab es schon einen Interrupt?*/
  13.  
  14.  
  15. /*Unterbrechungsbehandlungsfunktion*/
  16.  
  17. ISR (INT0_vect){
  18.     if(interrupt == 0){
  19.         if (running == 0){
  20.             if (laenge < NUMLED)
  21.                 lange++;
  22.                 }
  23.         else if (running == 1 && laenge > 1)
  24.             lange --;
  25.             }
  26.         interrupt = 1;
  27. }
  28.  
  29.  
  30.  
  31. /*Funktion main*/
  32.  
  33. void main (){
  34.     init();
  35.  
  36. /* Initialisierung */
  37.  
  38. laenge = 1;
  39. running = 0;
  40. interrupt= 0;
  41.  
  42. sei();
  43.  
  44.  
  45. /* Hauptschleife */
  46. while(1){
  47.     int i = 0;
  48.     cli();
  49.     running = 1;
  50.     for (i; i < NUMLED; i++){
  51.         ShowSnake(i;laenge);
  52.             active_wait(5000);
  53.     }
  54. interrupt = 0;
  55. sei();
  56. cli();
  57. running = 0;
  58. sei();
  59.  
  60.  
  61.  
  62. /* Vorbereitung des naechsten Umlaufsbzw. Schlafen */
  63.  
  64. cli();
  65. if (interrupt == 0 && laenge ==6){
  66.     laenge = 1;
  67.     sei();
  68.     cli();
  69. }
  70. while(interrut == 0){
  71.     sei();
  72.     sleep_cpu;
  73.     cli();
  74.     interrupt = 0;
  75.     sei();
  76. }
  77.  
  78.  
  79.  
  80. /*Funktion init*/
  81.  
  82. void init(){
  83.     DDRB = 0xFF;
  84.     DDRD = 0x00;
  85.     PORTD |= (1<<PD2);
  86.     MCUCR |= (1<<1) | (1<<0);
  87.     GICR |= (1<<6);
  88. }
  89.  
  90.  
  91.  
  92. /*Funktion active_wait()*/
  93.  
  94. void active_wait (volatile unsigned int len){
  95.     int i = o;
  96.     for (i; i <= len; i++)
  97.         sleep_cpu;
  98. }
This post was edited on 2010-07-20, 10:41 by morty.
Edit reason: Highlighting vom Code aktiviert.
morty (Administrator) #2 -- since Sep 2003 · 730 posts · Location: Erlangen
Show profile · Link to this post
Hab mal das Code Highlighting bei deinem Beitrag aktiviert. Ich hoffe das war ok.

Bin jetzt mal grob drüber. Folgendes ist mir aufgefallen:
  • Den Variablentyp "in" gibt es nicht
  • Auch sonst sollte man int nicht verwenden, sondern einen geeignete typen
  • Da fehlen Klammern
  • Deklaration von Funktionen nicht vergessen! (init)
  • Du solltest nochmal genau schauen, wann die Interrupts an und wann aus sind.
  • Ein sei mit direkt darauffolgenden cli bringt nichts, weil sei erst im nächsten Takt, cli aber sofort wirksam ist -> Die interrupts werden nicht aktiviert.
  • active_wait: Hier solltest du nochmal überlegen warum welche Variable volatile sein muss.
  • Auch Zeile 64, 65 solltest du nochmal mit der Aufgabenstellung vergleichen
  • Ob Zeile 70ff das machen was du willst solltest du auch nochmal durchdenken.

Am Besten die Kommentare mal einarbeiten und nochmal hier posten.
Dani #3 -- for 2 months · 8 posts
Show profile · Link to this post
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define NUMLED 6


/*Funktionsdeklarationen, globale Variablen, etc. */

Den Variablentyp "in" gibt es nicht
Auch sonst sollte man int nicht verwenden, sondern einen geeignete typen
Da fehlen Klammern
Deklaration von Funktionen nicht vergessen! (init)

volatile static double laenge;        /*länge der Schlange*/
volatile static double running;        /*Findet gerade eine Umrandung statt?*/
volatile static double interrupt;    /*gab es schon einen Interrupt?*/


void init();

void active_wait (volatile unsigned int len);


/*Unterbrechungsbehandlungsfunktion*/

ISR (INT0_vect){
    if(interrupt == 0){
        if (running == 0){
            if (laenge < NUMLED)
                lange++;
                }
        else if ((running == 1) && (laenge > 1))
            lange --;
            }
        interrupt = 1;
}



/*Funktion main*/

void main (){
    init();

/* Initialisierung */

    laenge = 1;
    running = 0;
    interrupt= 0;

    sei();


/* Hauptschleife */
    while(1){
Auch Zeile 64, 65 solltest du nochmal mit der Aufgabenstellung vergleichen
        if (laenge > 6)
            laenge = 1;
        int i = 0;
        cli();
        running = 1;
        for (i; i < NUMLED; i++){
            ShowSnake(i;laenge);
            sei();
            active_wait(5000);
            cli();
        }
        interrupt = 0;
        running = 0;




/* Vorbereitung des naechsten Umlaufsbzw. Schlafen */


 
Ob Zeile 70ff das machen was du willst solltest du auch nochmal durchdenken
        while(interrut == 0){
            sleep_enable();
            sei();
            sleep_cpu;
            sleep_disable;()
        }
    }
}


/*Funktion init*/

init(){
    DDRB = 0xFF;
    DDRD = 0x00;
    PORTD |= (1<<PD2);
    MCUCR |= (1<<1) | (1<<0);
    GICR |= (1<<6);
}



/*Funktion active_wait()*/
active_wait: Hier solltest du nochmal überlegen warum welche Variable volatile sein muss
active_wait (volatile unsigned int len){
    int i = o;
    cli();
    for (i; i <= len; i++){
    }
    sei();

}
morty (Administrator) #4 -- since Sep 2003 · 730 posts · Location: Erlangen
Show profile · Link to this post
Seht doch schon mal nicht schlecht aus. Wenn du ein [code=c] vor und ein [/code] hinter deinen code schreibst wird er auch schön.

  • Variablen: Da hatten wir mal eine Tafelübung eine Einheit über die geeignete Wahl der Variablentyps
  • active_wait: Da sind noch ein paar Probleme mit volatile und Interrupts
  • init: Woher weißt du, dass das INT0-Bit die 6 ist? Gleiches gilt für ISC[01]
  • Zustand running=0 : Der Code müsste zwar tun, was er soll, aber vor allem in Kombination mit dem Interrupt sind hier glaube ich zu viele Abfragen drin. Mixed declarations!
  • Zustand running=1: Nochmal mit der Aufgabenstellung vergleichen, Varaiablenübergabe an Funktionen
  • Interrupt: Formatier den mal ordentlich und setz lieber noch ein paar Klammern. Entweder hast du da noch einen Denk oder Klammer-Fahler drin.
Dani #5 -- for 2 months · 8 posts
Show profile · Link to this post
So ich habe jetzt mal die Lösung optimiert.
Ich weiß aber nicht was du mit folgendem meinst:
Zustand running=0 : Der Code müsste zwar tun, was er soll, aber vor allem in Kombination mit dem Interrupt sind hier glaube ich zu viele Abfragen drin. Mixed declarations!
Zustand running=1: Nochmal mit der Aufgabenstellung vergleichen, Varaiablenübergabe an Funktionen

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#define NUMLED 6


/*Funktionsdeklarationen, globale Variablen, etc. */

Variablen: Da hatten wir mal eine Tafelübung eine Einheit über die geeignete Wahl der Variablentyps

volatile static u_int8 laenge;        /*länge der Schlange*/
volatile static u_int8 running;        /*Findet gerade eine Umrandung statt?*/
volatile static u_int8 interrupt;    /*gab es schon einen Interrupt?*/


void init();

void active_wait (volatile unsigned int len);


/*Unterbrechungsbehandlungsfunktion*/
Interrupt: Formatier den mal ordentlich und setz lieber noch ein paar Klammern. Entweder hast du da noch einen Denk oder Klammer-Fahler drin.

ISR (INT0_vect){
    if(interrupt == 0){
        if (running == 0){
            if (laenge < NUMLED)
                lange++;
        }
        else if ((running == 1) && (laenge > 1))
            lange --;
    }
        interrupt = 1;
   
}



/*Funktion main*/

void main (){
    init();

/* Initialisierung */

    laenge = 1;
    running = 0;
    interrupt= 0;

    sei();


/* Hauptschleife */
    while(1){
        if (laenge > 6)
            laenge = 1;
        int i = 0;
        cli();
        running = 1;
        for (i; i < NUMLED; i++){
            ShowSnake(i;laenge);
            sei();
            active_wait(5000);
            cli();
        }
        interrupt = 0;
        running = 0;




/* Vorbereitung des naechsten Umlaufsbzw. Schlafen */


 
                cli();
        while(interrut == 0){
            sleep_enable();
            sei();
            sleep_cpu;
            sleep_disable;()
        }
    }
}


/*Funktion init*/
init: Woher weißt du, dass das INT0-Bit die 6 ist? Gleiches gilt für ISC[01]

init(){
    DDRB = 0xFF;
    DDRD = 0x00;
    PORTD |= (1<<PD2);
    MCUCR |= (1<<ISC01) | (1<<ISC00);
    GICR |= (1<<INT0);
}



/*Funktion active_wait()*/
active_wait: Da sind noch ein paar Probleme mit volatile und Interrupts

active_wait (volatile unsigned int len){
    int i = o;
        for (i; i <= len; i++){
    }

}
Panos #6 -- for 2 months · 18 posts
Show profile · Link to this post
In der Aufgabenstellung steht: Nach jedem Durchlauf wächst die Länge der Schlange um ein Segment. Laut deinem Code passiert das aber nicht.... Du erhöhst die Länge nur in dem Interrupt-Handler. Außerdem, verstehe ich deine Hauptschleife nicht.  Es passiert nur ein Durchlauf und dann legt sich die CPU in den Stromsparmodus, das heißt nur durch einen Interrupt kanns weitergehen.

Bei der active_wait Funktion ist der Parameter der an die Funktion übergeben wird volatile. Welche Variable verwendest du aber in for-schleife? Denk mal nach was der Compiler da machen wird.

Ich hoffe meine Tipps waren hilfreich und ich hab nicht nur mist erzählt^^

Grüße, Panos.
Dani #7 -- for 2 months · 8 posts
Show profile · Link to this post
Es passiert nur ein Durchlauf und dann legt sich die CPU in den Stromsparmodus, das heißt nur durch einen Interrupt kanns weitergehen.
Aber genau das ist die Aufgabe:
"Umrandet die Schlange die komplette 7-Segment-Anzeige, so stoppt die Ausführung bis zum Druck des Taster."

Bei der active_wait Funktion ist der Parameter der an die Funktion übergeben wird volatile. Welche Variable verwendest du aber in for-schleife? Denk mal nach was der Compiler da machen wird.
Könntest du konkret sagen was du damit meinst??
danke
lg dani =)
morty (Administrator) #8 -- since Sep 2003 · 730 posts · Location: Erlangen
Show profile · Link to this post
Quote by Panos:
Ich hoffe meine Tipps waren hilfreich und ich hab nicht nur mist erzählt^^

Ne, klingt gut.

Quote by Dani:
"Umrandet die Schlange die komplette 7-Segment-Anzeige, so stoppt die Ausführung bis zum Druck des Taster."

Umrandet != Umrundet
Panos #9 -- for 2 months · 18 posts
Show profile · Link to this post
  1. active_wait (volatile unsigned int len){
  2.     int i = o;
  3.         for (i; i <= len; i++){
  4.     }
  5.  
  6. }


Deine for-schleife wird wegoptimiert weil die Laufvariable i nicht volatile ist.
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please note the verification code from the picture into the text field next to it.
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Go to forum
Unclassified NewsBoard 1.6.4 © 2003-5 by Yves Goergen
Page created in 784.4 ms (548.2 ms) · 98 database queries in 81.3 ms
Current time: 2010-09-08, 11:52:30 (UTC +02:00)