Not logged in. · Lost password · Register

Page:  1  2  next 
Leo
Member since Mar 2011
1 post
Subject: 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. }
This post was edited on 2011-07-31, 15:30 by Leo.
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Quote by Leo on 2011-07-31, 14: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
Member since Apr 2011
15 posts
In reply to post #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
Member since Apr 2011
15 posts
In reply to post #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
Member since Apr 2011
15 posts
In reply to post #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
Member since Apr 2011
15 posts
In reply to post #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
Member since Oct 2010
15 posts
In reply to post #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
Member since Apr 2011
15 posts
In reply to post #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
Member since Apr 2011
15 posts
In reply to post #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".
This post was edited on 2011-08-03, 00:36 by dom.
Edit reason: code tags hinzugefügt
D.Kay
Member since Oct 2010
15 posts
@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
Member since Apr 2011
15 posts
ok danke :)
Kille
Member since May 2011
8 posts
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
Member since Oct 2010
55 posts
  1. void init(void) {}
ist schon richtig so. Das hat der Morty heute jedenfalls in der Fragestunde gesagt.
Steppenwolf
GSPiC-Übungsleiter
Member since May 2011
31 posts
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
Member since Oct 2010
7 posts
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?
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:
Page:  1  2  next 
Go to forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen