Nicht angemeldet. · Kennwort vergessen · Registrieren

Seite:  1  2  nächste 
andi91
Mitglied seit 11/2011
36 Beiträge
Betreff: August 2011 aufgabe 2
Hallo, ich wollte mal fragen, ob die Aufgabe, so wie ich sie gelöst habe in Ordnung gehen würde(hab mal nur die main gepostet):

void main(void){

//lokale Variablen,init
init();
uint8_t awert;
uint8_t i;
uint8_t b= 0;

while(1){
awert = ((poti_read())/130)+1;
 for(i=0;i<awert;i++){
   PORTB&=b;
   b=b<<1;
 }
b=0;
//Countdownphase
while(!event){
;
}
event=0;
  for(i=awert;i>0;i--){
    if(event){
      wait();
      break; 
}
 PORTB|= (1<<(i-1));
 wait();
 b++
}
//LED_Alarm-Sequenz
if(b== awert){
PORTB&= 166;
wait();
PORTB &=85;
wait();
}
//Schlafphase
event=0;
sleep_enable();
cli();
while(!event){
sei();
sleep_cpu();
cli();
}
}

Außerdem wollte ich noch bei der init() was fragen:
In der Aufgabe steht ja immer "auf tastendruck". Ich bin davon ausgegangen, dass also ein Interrupt bei einer fallenden Flanke ausgelöst wird,also hab ich folgendes für MCUCR geschrieben:
 MCUCR |= ((MCUCR|(1<<ISCO1)) | (MCUCR & ~(1<<ISCOO));
Passt das?
Danke schonmal!! (:
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
Bitte pack den Code in [code=c] ...CODE... [/code] - tags und rück ihn ordentlich ein. Dann ist die Motivation ihn durchzuschauen schon deutlich höher. ;)
andi91
Mitglied seit 11/2011
36 Beiträge
Oke also hier nochmal :D


  1. void main(void){
  2.  
  3. //lokale Variablen,init
  4.     init();
  5.     uint8_t awert;
  6.     uint8_t i;
  7.     uint8_t b= 0;
  8.     uint8_t z= 1;
  9.     sei();
  10.  
  11.       while(1){
  12.          while(!event)
  13.            awert = ((poti_read())/130)+1;
  14.            for(i=0;i<awert;i++){
  15.            PORTB&=b;
  16.            b=b<<1;
  17.       }
  18. }
  19. //b=0;
  20.  
  21. //   sei();
  22. //     while(!event){
  23. //   ;
  24. //  }
  25.    event=0;
  26.  
  27. //Countdown-Phase
  28.  
  29.       for(i=awert;i>0;i--){
  30.          if(event){
  31.          wait();
  32.          break;
  33.    }
  34.  
  35.    PORTB|= (1<<(i-1));
  36.    wait();
  37.    z++
  38. }
  39.  
  40. //LED_Alarm-Sequenz
  41.  
  42.      if(z== awert){
  43.         PORTB&= 166;
  44.         wait();
  45.  
  46.          PORTB &=85;
  47.          wait();
  48. }
  49.  
  50. //Schlafphase
  51.  
  52.    sleep_enable();
  53.    cli();
  54.    event=0;
  55.        while(!event){
  56.             sei();
  57.             sleep_cpu();
  58.             cli();
  59.    }
  60. }

EDIT:  So. Hoffe es passt jetzt.....
EDIT2: Hab die Änderungen ab Zeile 11 eingefügt ...
Dieser Beitrag wurde 3 mal verändert, zuletzt am 21.03.2012, 14:27 von andi91.
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
Das mit dem Einrücken üben wir nochmal. Und man kann alte Beiträge übrigens editieren.
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
  • Also der Code übersetzt schon mal nicht -> Einfach mal durch den Compiler jagen.
  • Wenn der Code sauber eingerückt wäre, wäre einer der Fehler sicher aufgefallen.
  • 130 ist knapp daneben. So etwas lässt man am Besten den Compiler ausrechnen
  • Zeile 9 bis 22 kann ich irgendwie nicht mit der Angabe vereinen.
  • Zeile 17 Sicher, dass das die richtige Stelle ist?
  • Zeile 25 bis 29: Knapp daneben.....
  • Zeile 37: Das wird wohl nie auslösen
  • 166 ist auch knapp daneben. Auch hier im Zweifel lieber den Compiler rechnen lassen....

So, ich glaub das war's für's Erste.
andi91
Mitglied seit 11/2011
36 Beiträge
- Wieso ist 130 daneben? Es wird ein 10-bit wert zurückgeliefert und den hab ich durch 8 geteilt, das ergibt ungefähr 130 und dann noch plus 1 weil man von 1 bis 8 haben will oder ist das falsch gedacht? Und wie soll man das den Compiler rechnen lassen?

-Zeile 9-22: In Zeile 10 lege ich den Anfangswert fest, dann wird in den Folgenden Zeilen der Anfangswert über die Leds angezeigt. In Zeile 13 hab ich mich verschrieben, da müsste es b|=b<<1; heißen... Dann setze ich in Zeile 15 b = 0 , weil ich das später zum Zählen brauche, um zu bestimmen ob der Countdown vollständig abgelaufen ist... Dann warte ich bis ein interrupt kommt..
Wo genau liegt mein Fehler?

- zeile 17 is falsch ja da bin ich verrutscht^^ danke!

- Zeile 25-29 & 37: Wieso funktioniert das nicht?
- Ja stimmt es müsste 169 sein, Aber wie soll ich das den Compiler rechnen lassen?

Vielen Dank auf jeden Fall für die Antworten!!!
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
Zitat von andi91:
- Wieso ist 130 daneben? Es wird ein 10-bit wert zurückgeliefert und den hab ich durch 8 geteilt, das ergibt ungefähr 130 und dann noch plus 1 weil man von 1 bis 8 haben will oder ist das falsch gedacht? Und wie soll man das den Compiler rechnen lassen?
1024/8 = 128

Zitat von andi91:
-Zeile 9-22: In Zeile 10 lege ich den Anfangswert fest, dann wird in den Folgenden Zeilen der Anfangswert über die Leds angezeigt. In Zeile 13 hab ich mich verschrieben, da müsste es b|=b<<1; heißen... Dann setze ich in Zeile 15 b = 0 , weil ich das später zum Zählen brauche, um zu bestimmen ob der Countdown vollständig abgelaufen ist... Dann warte ich bis ein interrupt kommt..
Wo genau liegt mein Fehler?
Das der Poti genau einmal ausgelesen wird. Man den Wert also nicht ändern kann.
Auch wenn es hier richtig ist, rate ich dir davon ab Variablen zu recyceln. Es hat keinerlei Vorteile, kann aber leicht Fehler verursachen und ist schwerer zur korrigieren.

Zitat von andi91:
- Zeile 25-29 : Wieso funktioniert das nicht?
Weil man bei deiner Lösung nach dem Tastendruck die Wartezeit zu ende warten muss und dann nochmal warten muss.


Zitat von andi91:
- Zeile 37: Wieso funktioniert das nicht?
Weil ich mich verdacht hab. Aber es gibt es eine deutlich einfachere und und weniger fehleranfällige Lösung.

Zitat von andi91:
- Ja stimmt es müsste 169 sein, Aber wie soll ich das den Compiler rechnen lassen?
z.B.
  1. char r = (1 << 7) | (1 << 5) | (1 << 3) | (1 << 1);
  2. PORTB = r;
  3. wait();
  4. PORTB = ~r;
Das r, sowie der ~ Operator, werden vom Compiler vollständig weg optimiert.
BTW: Das &= in deiner Lösung ist nicht der Erwartungswert. ;)
andi91
Mitglied seit 11/2011
36 Beiträge
Zitat von morty:
1024/8 = 128

Ja und 1024/130 = 7(.87) +1 = 8  .. Geht das nicht?

Zitat von morty:
Das der Poti genau einmal ausgelesen wird. Man den Wert also nicht ändern kann.

Mh, ich hab die Aufgabenstellung nicht so verstanden gehabt, dass man eine warteschleife schreiben soll, in der abgefragt wird welcher Wert am poti eingestellt ist.. Ist es das? Ich hab meinen Code mal entsprechend verändert...

Zitat von morty:
Auch wenn es hier richtig ist, rate ich dir davon ab Variablen zu recyceln. Es hat keinerlei Vorteile, kann aber leicht Fehler verursachen und ist schwerer zur korrigieren.
Okay, also wenn ich einfach eine neue Variable anlegen würde, dann ginge das in Ordnung oder? Habs auch nochmal in den Code geschrieben...

Zitat von morty:
Weil man bei deiner Lösung nach dem Tastendruck die Wartezeit zu ende warten muss und dann nochmal warten muss
Wird durch das break in der if-schleife nicht die for-schleife verlassen und somit die Wartezeit weiter unten umgangen?

Zitat von morty:
Weil ich mich verdacht hab. Aber es gibt es eine deutlich einfachere und und weniger fehleranfällige Lösung.

Mh, also mir ist keine andere eingefallen, was wäre denn eine Alternative?

Zitat von morty:
BTW: Das &= in deiner Lösung ist nicht der Erwartungswert. ;)
Wieso? Gut, hätte auch einfach PORT = 169 usw schreiben können, aber geht doch auch oder? :D
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
Zitat von andi91:
Zitat von morty:
1024/8 = 128
Ja und 1024/130 = 7(.87) +1 = 8  .. Geht das nicht?
Nein, weil es gelichmäßig sein soll.

Zitat von andi91:
Zitat von morty:
Das der Poti genau einmal ausgelesen wird. Man den Wert also nicht ändern kann.
Mh, ich hab die Aufgabenstellung nicht so verstanden gehabt, dass man eine warteschleife schreiben soll, in der abgefragt wird welcher Wert am poti eingestellt ist.. Ist es das? Ich hab meinen Code mal entsprechend verändert...
Hmm, les den Text nochmal. Alles andere wäre auch irgendwie nicht so sinnvoll.

Zitat von andi91:
Zitat von morty:
Auch wenn es hier richtig ist, rate ich dir davon ab Variablen zu recyceln. Es hat keinerlei Vorteile, kann aber leicht Fehler verursachen und ist schwerer zur korrigieren.
Okay, also wenn ich einfach eine neue Variable anlegen würde, dann ginge das in Ordnung oder? Habs auch nochmal in den Code geschrieben...
Ja, lieber ein oder zwei mehr. Wird wie gesagt eh alles weg optimiert.
Ach ja, wenn es inhaltliche änderungen im Code gibt, den Code lieber nochmal posten, weil es dann für andere Nachvollziehbar ist.

Zitat von andi91:
Zitat von morty:
Weil man bei deiner Lösung nach dem Tastendruck die Wartezeit zu ende warten muss und dann nochmal warten muss
Wird durch das break in der if-schleife nicht die for-schleife verlassen und somit die Wartezeit weiter unten umgangen?
JA, aber nicht die vor dem break.

Zitat von andi91:
Zitat von morty:
Weil ich mich verdacht hab. Aber es gibt es eine deutlich einfachere und und weniger fehleranfällige Lösung.
Mh, also mir ist keine andere eingefallen, was wäre denn eine Alternative?
Einfach eine weitere Variable einführen, auf 0 setzten und vor dem break auf 1 setzen. Dann prüfen ob sie 1 ist.

Zitat von andi91:
Zitat von morty:
BTW: Das &= in deiner Lösung ist nicht der Erwartungswert. ;)
Wieso? Gut, hätte auch einfach PORT = 169 usw schreiben können, aber geht doch auch oder? :D
Nein. Spiel's mal auf dem Papier durch.
Dieser Beitrag wurde am 21.03.2012, 14:53 von morty verändert.
andi91
Mitglied seit 11/2011
36 Beiträge
    Ja und 1024/130 = 7(.87) +1 = 8  .. Geht das nicht?

Nein, weil es gelichmäßig sein soll.

Gut, dann mach ich besser 1024/146= 7.01 und nehm 146 als meinen wert, passt es dann? Wäre das in der Klausur ein Fehler, der einen Punktabzug zur Folge hat?

    Mh, ich hab die Aufgabenstellung nicht so verstanden gehabt, dass man eine warteschleife schreiben soll, in der abgefragt wird welcher Wert am poti eingestellt ist.. Ist es das? Ich hab meinen Code mal entsprechend verändert...

Hmm, les den Text nochmal. Alles andere wäre auch irgendwie nicht so sinnvoll.

Der Text lautet: "Während der Konfigurationsphase wird ein Countdown-Anfangswert durch das
Potentiometer eingestellt, dessen Wert mit der Bibliotheksfunktion
uint16_t poti_read(void)
abgefragt werden kann. Die Funktion liefert einen 10-Bit-Wert zurück. Dessen Wertebereich
soll gleichmäßig auf die Werte von 1 und 8 abgebildet werden. Der gerade
eingestellte Wert wird durch eine entsprechend gefüllte LED-Reihe angezeigt (z. B.
Anfangswert 3: LEDs 0-2 leuchten).
– Wird der Taster gedrückt, wird der eingestellteWert als Anfangswert gesetzt und die
Countdown-Phase beginnt"..... 
Ich kanns eigtl nicht darraus erkennen, aber ist wohl so beabsichtigt, dass man eine Schleife schreiben muss oder?

Wäre meine Schleife richtig? sh nachfolgender post

JA, aber nicht die vor dem break.

Im Text steht ja auch, dass die Warteschleife noch zu Ende ausgeführt werden soll...


          BTW: Das &= in deiner Lösung ist nicht der Erwartungswert. ;)

    Wieso? Gut, hätte auch einfach PORT = 169 usw schreiben können, aber geht doch auch oder? :D

Nein. Spiel's mal auf dem Papier durch.

Versteh ich nicht.. bei der letzten Übungsaufgabe hab ich die Register auch immer so manipuliert....

Einfach eine weitere Variable einführen, auf 0 setzten und vor dem break auf 1 setzen. Dann prüfen ob sie 1 ist.


Habe dazu mal was im code ergänzt, hoffe es stimmt^^
andi91
Mitglied seit 11/2011
36 Beiträge
  1. void main(void){
  2.  
  3. //lokale Variablen,init
  4.     init();
  5.     uint8_t awert;
  6.     uint8_t i;
  7.     uint8_t b= 0;
  8.     uint8_t z= 1;
  9.     sei();
  10.  
  11.  while(1){
  12.          while(!event)
  13.            awert = ((poti_read())/128)+1;
  14.            for(i=0;i<awert;i++){
  15.            PORTB&=b;
  16.            b|=(b<<1);
  17.       }
  18. }
  19. //b=0;
  20.  
  21. //   sei();
  22. //    while(!event){
  23. //  ;
  24. // }
  25.    event=0;
  26.  
  27. //Countdown-Phase
  28.  
  29.       for(i=awert;i>0;i--){
  30.           if(event){
  31.             wait();
  32.             z=0;
  33.             break;
  34.    }
  35.  
  36.    PORTB|= (1<<(i-1));
  37.    wait();
  38.    
  39. }
  40.  
  41. //LED_Alarm-Sequenz
  42.  
  43.      if(z){
  44.         PORTB&= 166;
  45.         wait();
  46.  
  47.          PORTB &=85;
  48.          wait();
  49.          z=0;
  50. }
  51.  
  52. //Schlafphase
  53.  
  54.    sleep_enable();
  55.    cli();
  56.    event=0;
  57.        while(!event){
  58.             sei();
  59.             sleep_cpu();
  60.             cli();
  61.    }
  62. }


Habe Änderungen eingefügt in den Zeilen 9,12-16,19-24,32...

EDIT und zeile 49 noch z=0 eingefügt...
Dieser Beitrag wurde 3 mal verändert, zuletzt am 21.03.2012, 19:24 von andi91.
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
Antwort auf Beitrag #10
Zitat von andi91:
    Ja und 1024/130 = 7(.87) +1 = 8  .. Geht das nicht?

Nein, weil es gelichmäßig sein soll.

Gut, dann mach ich besser 1024/146= 7.01 und nehm 146 als meinen wert, passt es dann? Wäre das in der Klausur ein Fehler, der einen Punktabzug zur Folge hat?

Ne, 1 bis 8 sind 8 Bereiche - nicht 7. Und was den Code angeht: ...= poti_read(void) / (1024/8)   Wichtig: auf die Klammer achten, weil ja mit integer gerechnet wird.


Zitat von andi91:
[..]
Ich kanns eigtl nicht darraus erkennen, aber ist wohl so beabsichtigt, dass man eine Schleife schreiben muss oder?
Ja, ist schlecht formuliert. Aber es macht ja anders wenig Sinn. Zumal es ja eine entsprechende Übungsaufgabe gab.....

Zitat von andi91:
Wäre meine Schleife richtig? sh nachfolgender post
Ja, von der Logik sieht sie jetzt besser aus. Funktional macht sie noch nicht ganz das was sie soll. Und ein paar neue Fehler sind auch rein gekommen. Das mit den Bitoperatoren solltest du dir nochmal anschauen. Hast du die Übungsaufgaben gemacht?!?!?

Zitat von andi91:
JA, aber nicht die vor dem break.
Im Text steht ja auch, dass die Warteschleife noch zu Ende ausgeführt werden soll...
Jep, zuende - nicht nocheinmal.

Zitat von andi91:
          BTW: Das &= in deiner Lösung ist nicht der Erwartungswert. ;)

    Wieso? Gut, hätte auch einfach PORT = 169 usw schreiben können, aber geht doch auch oder? :D

Nein. Spiel's mal auf dem Papier durch.
Versteh ich nicht.. bei der letzten Übungsaufgabe hab ich die Register auch immer so manipuliert....
Hmm, evtl hat das da funktioniert. (Bin gerade zu faul die Aufgabenstellung nachzuschlagen ). Aber probier's mal mit einem Testprogram aus. Mit dem Simulator im AVRStudio sollte man das gut ausprobieren können......

Zitat von andi91:
Einfach eine weitere Variable einführen, auf 0 setzten und vor dem break auf 1 setzen. Dann prüfen ob sie 1 ist.
Habe dazu mal was im code ergänzt, hoffe es stimmt^^
Naja, so wird es nur einmal erkannt.....

Evtl solltest du dir die Übungsaufgaben nochmal raus suchen und durch programmierern. Das sind eigentlich alles typische Fehler, die während der Übung alle schon mal aufgetaucht sein sollten.
andi91
Mitglied seit 11/2011
36 Beiträge
Ne, 1 bis 8 sind 8 Bereiche - nicht 7. Und was den Code angeht: ...= poti_read(void) / (1024/8)   Wichtig: auf die Klammer achten, weil ja mit integer gerechnet wird.

Mh aber wenn ich dann noch 1 draufaddiere ist man doch bei 9 wenn der poti voll aufgedreht ist oder?

Ja, von der Logik sieht sie jetzt besser aus. Funktional macht sie noch nicht ganz das was sie soll. Und ein paar neue Fehler sind auch rein gekommen. Das mit den Bitoperatoren solltest du dir nochmal anschauen. Hast du die Übungsaufgaben gemacht?!?!?

Ja natürlich, hab alle übungsaufgaben schon und auch nochmal gemacht, ich hab mich nur schon wieder verschriebn in zeile 16 : b|=(b<<1)...  Geht PORTB &= b denn nicht? Bei der 4. Übungsaufgabe(die mit der led)  hab ich wie gesagt alle mein PORTs so gesetzt, anstatt b stand hall dann ne zahl und es war draufgeodert, und es hat geklappt... Ich bin grad verwirrt -.-'


    JA, aber nicht die vor dem break.
    Im Text steht ja auch, dass die Warteschleife noch zu Ende ausgeführt werden soll...

Jep, zuende - nicht nocheinmal.

Wieso nocheinmal? Wird doch gleich zu Beginn der Schleife überprüft und dann gewartet und dann abgebrochen...?

        Einfach eine weitere Variable einführen, auf 0 setzten und vor dem break auf 1 setzen. Dann prüfen ob sie 1 ist.

    Habe dazu mal was im code ergänzt, hoffe es stimmt^^

Naja, so wird es nur einmal erkannt.....

Evtl solltest du dir die Übungsaufgaben nochmal raus suchen und durch programmierern. Das sind eigentlich alles typische Fehler, die während der Übung alle schon mal aufgetaucht sein sollten.

Gut, das war jetzt n blöder Fehler^^ Ich habs nochmal geändert.. Aber das mit den Bitoperatoren verwirrt mich doch sehr, habe die Übungsaufgaben auch alle schon durchprogrammiert und hat auch geklappt.....
andi91
Mitglied seit 11/2011
36 Beiträge
Zitat von andi91:
In der Aufgabe steht ja immer "auf tastendruck". Ich bin davon ausgegangen, dass also ein Interrupt bei einer fallenden Flanke ausgelöst wird,also hab ich folgendes für MCUCR geschrieben:
 MCUCR |= ((MCUCR|(1<<ISCO1)) | (MCUCR & ~(1<<ISCOO));

Passt das eigentlich?

Zitat von andi91:

        Zitat von morty:
        1024/8 = 128

    Ja und 1024/130 = 7(.87) +1 = 8  .. Geht das nicht?

Nein, weil es gelichmäßig sein soll.

1024/129 = 7.99.. +1 = 8
Das müsste aber jetzt passen oder?
Dieser Beitrag wurde am 23.03.2012, 18:23 von andi91 verändert.
andi91
Mitglied seit 11/2011
36 Beiträge
1024/129 = 7.99.. +1 = 8
Das müsste aber jetzt passen oder?

Welcher Wertebereich wird vom poti jetzt eigentlich ausgegeben? In der Übung waren es immer 0...1023
Geht nur 1024/128 ohne das plus 1 auch? Weil im Text steht ja man soll auf den Wertebereihc 1 bis 8 abbilden....
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:
Seite:  1  2  nächste 
Gehe zu Forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen