Not logged in. · Lost password · Register

Musil
Member since Jul 2013
10 posts
Subject: Klausur März 2012 Aufgabe 2a
Hi,
könnte da mal jemand drüber schauen, ob das so passt?
Ich bin mir beim Ausrechnen der Warteintervalle nicht so ganz sicher, ob man das so machen darf (automatisches Runden...) genauso wie beim Setzen der Register in der Initialisierung
wär super :)

  1. /*Funktionsdeklarationen, globale Variablen etc.*/
  2. volatile int8_t helligkeit;
  3. volatile int8_t led =1;
  4. static void init(void);
  5. static void wait(uint16_t us);
  6.  
  7. /*Funktion main*/
  8. void main(void){
  9.  
  10.     /*Initialisierung und lokale Variablen*/
  11.     sleep_enable();
  12.     uint16_t leuchtzeit;
  13.     uint16_t auszeit;
  14.     init();
  15.  
  16.     /*Hauptschleife*/
  17.     for(;;){
  18.    
  19.         /*Schlafen*/
  20.         cli();
  21.         while(helligkeit == 0)
  22.             sei();
  23.             sleep_cpu();
  24.             cli();
  25.         }
  26.         sei();
  27.         /*LED ansteuern*/
  28.  
  29.         leuchtzeit = (LOOPS_PER_US*512/10*helligkeit);
  30.         auszeit = LOOPS_PER_US*512-leuchtzeit;
  31.  
  32.         PORTA = ~(1<<(led-1));
  33.         wait(leuchtzeit);
  34.         PORTA = 0xff;
  35.         wait(auszeit);
  36.     }
  37. }      
  38. /*Ende der Funktion main*/
  39.  
  40. /*Initialisierungsfunktion*/
  41. static void init(void){
  42.     DDRA = 0xff;
  43.     PORTA = 0xff;
  44.     DDRD &= ~((1<<2)|(1<<0));
  45.     PORTD |= (1<<2)|(1<<3);
  46.     MCUCR |= (1<<ISC01)|(1<<ISC11);
  47.     MCUCR &= ~((1<<ISC00)|(1<<ISC10));
  48.     GICR |= (1<<INT0)|(1<<INT1);
  49.         sei();
  50. }
  51.  
  52. /*Wartefunktion*/
  53. static void wait(uint16_t us){
  54.    
  55.     for(volatile uint16_t i = 0; i<us; i++){}
  56.    
  57. }
  58.  
  59. /*Unberbrechungsbehandlung*/
  60. ISR(INT0_vect){
  61.    
  62.     if(helligeit == 0){
  63.         if(led<8){
  64.             led++;
  65.         }
  66.     }
  67.     helligkeit = (helligkeit+1)%11;
  68.  
  69. }
  70.  
  71. ISR(INT1_vect){
  72.  
  73.     if(helligkeit==1){
  74.         if(led>1){
  75.             led--;
  76.         }
  77.     }
  78.     helligkeit = (helligkeit-1)%11;
  79.        
  80. }
This post was edited 2 times, last on 2013-07-20, 18:27 by Musil.
ingonör
Member since May 2013
67 posts
Ich schreibe die Aufgabe später selber mal und gebe dann meine Senf dazu!
ingonör
Member since May 2013
67 posts
In reply to post #1
Quote by Musil on 2013-07-19, 20:35:
  1.         leuchtzeit = (LOOPS_PER_US*512/10*helligkeit);
  2.         auszeit = LOOPS_PER_US*512-leuchtzeit;
Es kann sein, dass deine 'auszeit' nicht stimmt. Ich berechne die ein wenig anders. Zuerst berechne ich quasi '512 - leuchtzeit' und multipliziere das mit LOOPS_PER_US.

Quote by Musil on 2013-07-19, 20:35:
  1. /*Initialisierungsfunktion*/
  2. static void init(void){
  3.     DDRA = 0xff;
  4.     PORTA = 0xff;
  5.     DDRD &= ~((1<<2)|(1<<0));
  6.     PORTD |= (1<<2)|(1<<3);
  7.     MCUCR |= (1<<ISC01)|(1<<ISC11);
  8.     MCUCR &= ~((1<<ISC00)|(1<<ISC10));
  9.     GICR |= (1<<INT0)|(1<<INT1);
  10.         sei();
  11. }
Sieht eigentlich ganz gut aus. Ist wie bei mir.

Quote by Musil on 2013-07-19, 20:35:
  1. /*Unberbrechungsbehandlung*/
  2. ISR(INT0_vect){
  3.    
  4.     if(helligeit == 0){
  5.         if(led<8){
  6.             led++;
  7.         }
  8.     }
  9.     helligkeit = (helligkeit+1)%11;
  10.  
  11. }
  12.  
  13. ISR(INT1_vect){
  14.  
  15.     if(helligkeit==1){
  16.         if(led>1){
  17.             led--;
  18.         }
  19.     }
  20.     helligkeit = (helligkeit-1)%11;
  21.        
  22. }

Ja, ehm. Hier habe ich ein paar Problemchen mit der Aufgabenstellung. Also wenn ich das richtig verstanden habe, gibt es 8 LEDs. Wir beginnen mit der 1. auf Stufe 1. Ist auf Stufe 0 geschaltet worden (also aus), wird die 2. LED aktiviert, sobald man wieder den Taster0 drückt. Ist man bei der 8. angelagt, springt man wieder auf die 1. LED. Bitte korrigiert mich, falls ich das falsch verstehe.
Wendet man den Aufgabentext aber so auf deine ISR an, dann stimmt das noch nicht so ganz. Ich vermisse auch den Sprung von der 8. wieder zurück auf die 1. LED.

Edit: Eine Frage: Bei dir sind init() und wait() als static deklariert. Ist das denn notwendig? Wenn ja, warum?

Anbei mal mein Code. Ist bis auf die ISR fast identisch:

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/sleep.h>
  4. #include <stdint.h>
  5. #define LOOPS_PER_US 42
  6.  
  7. /* Funktionsdeklarationen, globale Variablen, etc. */
  8. void wait(uint16_t);
  9. void init(void);
  10. volatile uint8_t stufe = 0;
  11. volatile uint8_t position = 0;
  12.  
  13. /* Funktion main */
  14. void main(void) {
  15.  
  16. /* Initialisierung und lokale Variablen */
  17.     init()
  18.    
  19. /* Hauptschleife */
  20.     while(1) {
  21.    
  22. /* Schlafen */
  23.         cli();
  24.         while(!stufe) {
  25.             sei();
  26.             sleep_cpu();
  27.             cli();
  28.         }
  29.         sei();
  30.        
  31. /* LED ansteuern */ 
  32.     while(stufe) {
  33.         PORTA = 0xff;
  34.         wait(512 * 1 - stufe / 10);
  35.         PORTA |= (1 << position);
  36.         wait(512 * stufe / 10);
  37.     }
  38.    
  39. /* Ende Funktion main */
  40.     }
  41. }
  42.  
  43. /* Initialisierungsfunktion */
  44. void init(void) {
  45.     sleep_enable();
  46.     sei();
  47.    
  48.     DDRA = 0xff;
  49.     PORTA = 0xff;
  50.    
  51.     DDRD &= ~((1 << PD2) | (1 << PD3));
  52.     PORTD |= ((1 << PD2) | (1 << PD3));
  53.    
  54.     MCUCR |= ((1<< ISC01) | (1 << ISC11));
  55.     MCUCR &= ~((1 << ISC00) | (1 << ISC10));
  56.    
  57.     GICR |= ((1 << INT0) | (1 << INT1));
  58. }
  59.  
  60. /* Wartefunktion */
  61. void wait(uint16_t us) {
  62.     volatile uint16_t i = us * LOOPS_PER_US;
  63.     while(i--)
  64.         ;
  65.  
  66. }
  67.  
  68. /* Unterbrechungsbehandlung */
  69. ISR (INT0_vect) {   
  70.     if (stufe == 0) {   
  71.         stufe = 1;
  72.         position = (position + 1) % 8;
  73.     } else if (stufe < 10) {
  74.         stufe = stufe++;
  75.     }
  76. }
  77.  
  78. ISR (INT1_vect) {
  79.     if (stufe > 0) {
  80.             stufe--;
  81.     }
  82. }
This post was edited on 2013-07-20, 23:03 by ingonör.
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
static: Nein ist nicht zwingend notwendig. Sollte aber bei allen Funktionen hingeschrieben werden, die nicht von einem anderen Modul benötigt werden (vermeidet ggf Probleme mit doppelt benannten Funktionen/Variablen und erlaubt dem Compiler mehr zu optimieren). Aber vor die globalen variablen sollte man auch ein static schreiben. Da sie in einem Interrupt verwendet werden umso mehr!

musli: So wie du die wait implementiert hast entspricht es nicht der Aufgabenstellung. -> Am besten immer erst die Funktionen implementieren, dann passiert das nicht.

ingnör: Schau die mal die Berechnung in Zeile 34 an - da ist noch ein Fehler drin.
ingonör
Member since May 2013
67 posts
In reply to post #3
Aus
  1.         wait(512 * 1 - stufe / 10);
wird
  1.         wait(512 * (1 - stufe / 10));


morty, du hast Adleraugen. ;)
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Quote by ingonör:
morty, du hast Adleraugen. ;)
Jahrelange Übung. Ist aber immer noch falsch. ;)
King-Chris
Member since Oct 2012
31 posts
In reply to post #3
Quote by ingonör on 2013-07-20, 22:12:
/* Unterbrechungsbehandlung */
ISR (INT0_vect) {   
    if (stufe == 0) {   
        stufe = 1;
        position = (position + 1) % 8;
    } else if (stufe < 10) {
        stufe = stufe++;
    }
}

ISR (INT1_vect) {
    if (stufe > 0) {
            stufe--;
    }
}

Aber bei position = (position + 1) % 8;  wird doch immer 1 als Ergebnis rauskommen, da man am Ende durch 8 teilt. Den Schritt verstehe ich nicht.

Du wilst ja damit von der 8. LED wieder zur 1. springen, aber geht das wirklich einfach ohne if/else-Schleife ?
This post was edited 2 times, last on 2013-07-25, 18:12 by King-Chris.
ingonör
Member since May 2013
67 posts
In reply to post #5
Quote by ingonör on 2013-07-23, 12:57:
Aus
  1.         wait(512 * 1 - stufe / 10);
wird
  1.         wait(512 * (1 - stufe / 10));


Verdammte Axt! Und wie wäre es damit?

  1. wait((512 * (10 - stufe)) / 10)

Edit: Sorry, habe deinen Beitrag erst jetzt gelesen. Warum sollte bei der Modulo-Rechnung immer 1 rauskommen? Die spuckt in dem Fall Zahlen zwischen 0 und 7 aus.
Edit2: Ach jetzt check ich, was du meinst. Ja, so wie es gerade da steht ist das ziemlicher Quatsch! Ich schaue mir das später nochmal in Ruhe an. Ist jetzt auch schon ein paar Tage her!
ingonör
Member since May 2013
67 posts
In reply to post #7
Quote by King-Chris:
Aber bei position = (position + 1) % 8;  wird doch immer 1 als Ergebnis rauskommen, da man am Ende durch 8 teilt. Den Schritt verstehe ich nicht.

So, das war natürlich Blödsinn. Ohne Abfrage kommt man nicht weit. Ich denke, so sollte es funktionieren:
  1. position = (++position == 8) ? 1 : position;
King-Chris
Member since Oct 2012
31 posts
So kompliziert :D ? Könntest dus nochmals kurz erklären, was da jetzt genau gemacht wird. Ich hätte für die Aufgabe leider auch einfach keine bessere Idee.
yv21ipim
Member since Jan 2013
7 posts
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--;
    }
}
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