Nicht angemeldet. · Kennwort vergessen · Registrieren

Seite:  1  2  nächste 
Leo
Mitglied seit 03/2011
1 Beitrag
Betreff: Snake - April 2009
Snake Aufgabe vom 04.09.
Korrektur und Kommentare erwünscht...

  1.  
  2. #include <avr/io.h>
  3. #include <stdint.h>
  4. #include <avr/interrupt.h>
  5. #include <avr/sleep.h>
  6.  
  7. void init();
  8. void showSnake(uint8_t pos, unsigned char len);
  9. void active_wait(volatile unsigned int len);
  10.  
  11. static volatile uint8_t button = 0;
  12. static uint8_t position = 0;
  13. static unsigned char laenge = 1;
  14. static volatile unsigned int len = 5000;
  15.  
  16. void main(void){
  17.     init();
  18.     sei();
  19.     while(1){
  20.         while(laenge != 6){
  21.             cli();
  22.             if(button == 0){
  23.                 sei();
  24.                 showSnake(position,laenge);
  25.                 active_wait(len);
  26.                
  27.             }
  28.             cli();
  29.             if(button == 1 && laenge > 1){
  30.                 sei();
  31.                 button = 0;
  32.                
  33.                 showSnake(position,laenge);
  34.                 active_wait(len);
  35.                 laenge -= 2;
  36.                
  37.             }
  38.             position++;
  39.             position %= 6;
  40.             if(position == 0){
  41.                 laenge++;
  42.             }         
  43.         }
  44.         cli();
  45.         while(button == 0){
  46.             sleep_enable();
  47.             sei();
  48.             sleep_cpu();
  49.             sleep_disable();
  50.             cli();
  51.         }
  52.         button = 0;
  53.         position = 0;
  54.         laenge = 1;
  55.         sei();
  56.     }   
  57. }
  58.  
  59. ISR(INT0_vect){
  60.     button = 1;
  61. }
  62.  
  63. void init(){
  64.     for(uint8_t a = 0; a<6,a++){
  65.         DDRB |=(1<<a);
  66.         PORTB &= ~(1<<a);
  67.     }
  68.    
  69.     DDRD &= ~(1<<2);
  70.     PORTD |= (1<<2);
  71.     GICR |= (1<<INT0);
  72.     MCUCR |= (1<<ISC01);
  73.     MCUCR &= ~(1<<ISC00);
  74. }
  75.  
  76. void showSnake(int8_t pos, unsigned char len){
  77.     PORTB = 0xff;
  78.     for(uint8_t a = 0; a<= len; a++){
  79.         PORTB &= ~(1<<((a+pos)%6));
  80.     }
  81. }
  82.  
  83. void acitve_wait(volatile unsigned int len){
  84.     for(uint16_t a = 0; a<= len; a++){}
  85. }
Dieser Beitrag wurde am 31.07.2011, 14:30 von Leo verändert.
morty
SPiC-Meister
(Moderator)
Mitglied seit 05/2011
331 Beiträge
Zitat von Leo am 31.07.2011, 13:51:
Snake Aufgabe vom 04.09.
Korrektur und Kommentare erwünscht...

Ihr dürft auch gerne gegenseitig Kommentieren. Wir schreiten dann schon ein, wenn es in die falsche Richtung geht....
joan
Mitglied seit 04/2011
15 Beiträge
Antwort auf Beitrag #1
ich denke du hast bei der active wait funktion das volatile vor dem uint16_t a = 0 vergessen und außerdem machst du einen schleifendurchlauf zuviel wenn du a<= len machst. Weil du ja genau len schleifendurchläufe machen sollst. also mal angenommen len = 3 dann machst du 0,1,2,3 also vier schleifendurchläufe wenn du das gleich zeichen weg machst müsste es stimmen.
joan
Mitglied seit 04/2011
15 Beiträge
Antwort auf Beitrag #1
zeile 77 verwendest du     PORTB = 0xff; ich denke mal du willst alle leds ausschalten allerdings greift du somit auf pins zu nämlich  pin 6,7,8 die gar nichts mit den leds zutun haben (zumindest nicht in der aufgabe). ich denke besser wäre hier wenn man die leds auf diese weiße ausschlatet PORTB |= 0x3f; dass sollte die ersten 6 bits von portb setzen.
joan
Mitglied seit 04/2011
15 Beiträge
Antwort auf Beitrag #1
zeile 78  zeichnest du denke ich ein schlangensegment zu viel. stell dir vor len = 4 dann zeichnest du für a = 0,1,2,3,4 fünf segmente wenn du das = entfernst müsste es passen.
joan
Mitglied seit 04/2011
15 Beiträge
Antwort auf Beitrag #1
zeile 66 schaltest du alle leds an         PORTB &= ~(1<<a); ich denke du wirst sie in der init alle aushaben wollen oder ? sind active low.
D.Kay
Mitglied seit 10/2010
15 Beiträge
Antwort auf Beitrag #1
Warum ziehst du in Zeile 35 von der laenge 2 ab?
Außerdem könntest du ein Problem bekommen, wenn du in der wait aus Zeile 25 bist und Interrupt auftritt. Dann wird button auf 1 gesetzt und du kommst auch in die zweite if aus Zeile 29, zeigst nochmal die Schlange an, wartest und ziehst dann. D.h. du lässt zwei mal die Schlange anzeigen und warten, ohne dass sich die Position von deinem Kopf verändert. Da hättest auch showSnake und active_wait aus der if-Anweisung raus ziehen können. Spart Platz und Schreibarbeit.
joan
Mitglied seit 04/2011
15 Beiträge
Antwort auf Beitrag #6
ich hätte auch noch ein paar fragen zur angabe der aufgabe:

1. nach jedem durchlauf wächst die schlange um ein segment. ist hier ein durchlauf durch alle sechs leds gemeint also dass der kopf der schlange einmal um die sechs leds gewandert ist ?

2.was bedeutet allgemein (auch bei den anderen klausuren ) die ausführung stoppt heißt dass ich muss alle leds ausschalten und in den schlafmodus oder was sonst?
joan
Mitglied seit 04/2011
15 Beiträge
Antwort auf Beitrag #1
Kommentare und Verbesserungsvorschläge bzw Fehler bitte schreiben :D

  1. /* funktionendeklaration */
  2.  
  3. void init (void);
  4. void active_wait;
  5. volatile static uint8_t laenge = 1;
  6. volatile static uint16_t wartezeit = 5000;
  7.  
  8. /* ISR */
  9.  
  10. ISR(INT0_vect){// darf man hier die laenge direkt abziehen oder soll man mit z.b button = 1 arbeiten, gibt das hier später bei dem schlafmodus probleme?
  11.     if( laenge > 1){
  12.         --laenge;
  13.     }
  14. }
  15.  
  16.  
  17. /* main */
  18.  
  19. void main (void){
  20.     init();//passt dieser funktionsaufruf oder muss hier ein void in die klammer?
  21.     sei();
  22.  
  23.     while(1){
  24.         for(uint8_t i = 0; i < 6 ; i++){
  25.             show_Snake(i,laenge);
  26.             active_wait(wartezeit);
  27.         }
  28.  
  29.         laenge++;
  30.         cli();
  31.         if( laenge == 6) {
  32.             sleep_enable();
  33.             sei();
  34.             sleep_cpu();
  35.             sleep_disable();
  36.             cli();
  37.             laenge = 1;
  38.         }
  39.         sei();
  40.     }
  41. }
  42.  
  43.  
  44.  
  45. /* init*/
  46. void init (void){
  47.     DDRB |= 0x3f;//leds ausgang und alle aus
  48.     PORTB |= 0x3f;
  49.  
  50.     DDRD &= ~(1 << PD2);//darf man PD2 schreiben oder lieber 2
  51.     PORTD |= (1 << PD2);
  52.  
  53.     MCUCR |= ( 1 << ISC01);//fallende flanke steht nicht im text welche man verwenden soll
  54.     MCUCR &= ~ (1 << ISC00);
  55.  
  56.     GICR |= (1 << INT0);
  57. }
  58.  
  59. /* snake*/
  60.  
  61. void show_Snake( uint8_t pos, uint8_t len){
  62.     while( len > 0 ){
  63.         PORTB |= (1 << pos);
  64.         if( pos > 0){
  65.             --pos;
  66.         }else{
  67.             pos = 5;
  68.         }
  69.         --len;
  70.     }
  71. }
  72.  
  73.  
  74. /* wait */
  75.  
  76. void active_wait (volatile uint16_t len){
  77.     for( volatile uint16_t i = 0 ; i < len ; i ++)
  78.         ;
  79.     }
  80. }

// edit by DOM: Das nächste Mal bitte sämtlichen Code in die dafür vorgesehenen "code tags".
Dieser Beitrag wurde am 02.08.2011, 23:36 von dom verändert.
Begründung: code tags hinzugefügt
D.Kay
Mitglied seit 10/2010
15 Beiträge
@joan: Zum Aufruf der init:
Da muss glaube ich kein void rein. Das void ist in der Funktionendeklaration wichtig. Sonst hast du eine "offene Funktion". Kannst du im Skript bei "Funktionsdeklaration" nachlesen.
joan
Mitglied seit 04/2011
15 Beiträge
ok danke :)
Kille
Mitglied seit 05/2011
8 Beiträge
Also ich hab ein paar Sachen zu bemängeln:
1. es fehlt die Deklaration der showSnake
2.in der Angabe steht, dass die init void init() sein soll. Dementsprechend würd ich auch nirgends ein void in die Klammern schreiben.
3.in der Angabe steht, dass die active_wait ein volatile unsigned int übergeben bekommt und kein volatile uint16_t wie bei dir (weiß nicht wie böse da korrigiert wird, aber falls es wegen sowas Puntkabzug geben sollte, sind das leicht verschenkte Puntke). Das gleiche in der showSnake: laut angabe ein unsigned char, bei dir ein uint8_t
4. das sleep_enable kannst du auch gleich am anfang deiner main schreiben, nach dem aufruf der init, das sleep_disable kannste dir komplett sparen (so wurde es mir zumindest in der TÜ beigebracht)
dom
FSI EEI
(Moderator)
Avatar
Mitglied seit 10/2010
54 Beiträge
  1. void init(void) {}
ist schon richtig so. Das hat der Morty heute jedenfalls in der Fragestunde gesagt.
Steppenwolf
GSPiC-Übungsleiter
Mitglied seit 05/2011
31 Beiträge
Um nochmal klarzustellen, was der Unterschied zwischen "void init()" und "void init(void)" ist:

Das erste ist eine sogenannte "offene" Deklaration (siehe auch die Folien dazu), womit man dem Compiler nur sagt, dass es eine Funktion namens "init" geben wird, die nichts zurueckgibt. Ueber die Parameter sagt man hier aber explizit nichts! Das heisst, man kann dann init() z. B. einen uint32_t-Wert uebergeben, obwohl die Funktion spaeter bei der *Definition* z. B. zwei int16_t-Werte erwartet. Das fuehrt zur Laufzeit dann natuerlich zu nicht guten Dingen :).

Mit der zweiten Deklaration sagt man dem Compiler, dass init() definitiv keinen Parameter hat. Wenn man init() dann mit einem Parameter aufruft, wird der Compiler meckern und wir haben keine Probleme zur Laufzeit durch Programmierfehler.

Ergo: Offene Deklarationen sind normalerweise nicht noetig, also vermeiden!

Nachtrag: In der Aufgabenstellung haben wir das damals auch schlecht gemacht, weil wir da eine offene Deklaration angegeben haben. In Zukunft wird das von uns genauer spezifiziert.
macener
Mitglied seit 10/2010
7 Beiträge
Warum ist wartezeit eine globale Variable, wenn diese sowieso nur in einem Funktionsaufruf benötigt wird? Man könnte wartezeit eventuell als Makro definieren. Ich frage mich, ob die Wartezeit etwas mit der Länge der Schlange zu tun haben soll, da die formalen Parameter die gleichen Namen haben. Oder einfach deswegen um die Leute zu verwirren?
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