Not logged in. · Lost password · Register

ingonör
Member since May 2013
67 posts
Subject: Klausur 2012-07
Hallo,

wäre vielleicht wieder jemand so nett und könnte mal drüber schauen? Ist mir dieses mal wesentlich leichter gefallen, als das seltsame Garagentor.

Liebe Grüße
ingonör

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/sleep.h>
  4. #include <stdint.h>
  5.  
  6. /* Funktionsdeklarationen, globale Variablen, etc. */
  7. void init(void);
  8. void wait(uint16_t);
  9. volatile uint8_t taster0;
  10. volatile uint8_t taster1;
  11.  
  12. /* Unterbrechungsbehandlungsfunktionen */
  13. ISR (INT0_vect) {
  14.     taster0 = 1;   
  15. }
  16.  
  17. ISR (INT1_vect) {
  18.     taster1 = 1;   
  19. }
  20.  
  21. /* Funktion main */
  22. void main(void) {
  23.    
  24. /* Initialisierung und lokale Variablen */
  25.     init();
  26.     uint8_t stelle = 0;
  27. /* Hauptschleife */
  28.     while(1) {
  29.         cli();
  30.         while(taster0 == 0 || taster1 == 0) {
  31.             sei();
  32.             sleep_cpu();
  33.             cli();
  34.         }
  35.         sei();
  36.        
  37. /* Code-Eingabe */
  38.         if(taster1) {
  39.             PORTA &= ~(1 << stelle++);
  40.             taster1 = 0;
  41.         } else if(taster0) {
  42.             stelle++;
  43.             taster0 = 0;
  44.         }
  45.        
  46. /* Schloss oeffnen, naechster Durchlauf */
  47.         if(stelle == 8) {
  48.             if((PINA & (0xff) == SECRET) {
  49.                 PORTB |= (1 << PB5);
  50.                 uint8_t i = 0;
  51.                 while(i++ < 5) {
  52.                     PORTA |= 0x0;
  53.                     wait(500);
  54.                     PORTA = 0xff;
  55.                     wait(500);
  56.                 }
  57.                 PORTB &= ~(1 << PB5);
  58.             } else {
  59.                 PORTA = 0xff;
  60.             }
  61.             stelle = 0;
  62.         }
  63.     }
  64. /* Ende main */
  65. }
  66.  
  67. /* Initialisierungsfunktion */
  68. void init(void) {
  69.     sleep_enable();
  70.     sei();
  71.    
  72.     DDRA |= 0xff;
  73.     PORTA |= 0xff;
  74.    
  75.     DDRB |= (1 << PB5);
  76.     PORTB &= ~(1 << PB5);
  77.    
  78.     DDRD &= ~((1 << PD2) | (1 << PD3));
  79.     PORTD |= ((1 << PD2) | (1 << PD3));
  80.    
  81.     MCUCR |= ((1 << ISC01) | (1 << ISC11));
  82.     MCUCR &= ~((1 << ISC00) | (1 << ISC10));
  83.    
  84.     GICR |= ((1 << INT0) | (1 << INT1));
  85. }
  86. /* Wartefunktion */
  87. void wait(uint16_t ms) {
  88.     volatile uint16_t t = ms * LOOPS_PER_MS;
  89.     while(t--)
  90.         ;
  91. }
This post was edited on 2013-07-19, 09:12 by ingonör.
killermiller
Member since May 2011
41 posts
sieht bis auf kleinigkeiten gut aus so weit...
im allgemeinen brauchst du nur eine variable, wenn du eh nur komplimentäre zustände hast, also z.b. Taster0 ODER Taster1 gedrückt..hier kannst ja nicht passieren, dass beide gleichzeitig 1 sind. Eine Alternative wäre also z.B. -1 und 1 bzw. 1 und 2 in der selben variable für taster0 und taster1 zu nehmen...aber funktioniert so genauso, is wohl ziemlich geschmackssache.
Zeile 30: Die Abfrage funktioniert so nicht, schau dir das nochmal an...
Zeile 52: hier veroderst du mit 0, das tut einfach gar nichts...entweder register direkt komplett auf 0 setzen (mit "=0") oder verunden (&=0).
Ohne die Aufgabenstellung zur Hand zu haben, würde ich sagen, der Rest passt.
ingonör
Member since May 2013
67 posts
Quote by killermiller:
sieht bis auf kleinigkeiten gut aus so weit...
im allgemeinen brauchst du nur eine variable, wenn du eh nur komplimentäre zustände hast, also z.b. Taster0 ODER Taster1 gedrückt..hier kannst ja nicht passieren, dass beide gleichzeitig 1 sind. Eine Alternative wäre also z.B. -1 und 1 bzw. 1 und 2 in der selben variable für taster0 und taster1 zu nehmen...aber funktioniert so genauso, is wohl ziemlich geschmackssache.
Stimmt! Daran habe ich gar nicht gedacht!

Quote by killermiller:
Zeile 30: Die Abfrage funktioniert so nicht, schau dir das nochmal an...

Das einzige, das mir gerade spontan einfällt sind die '=' Zeichen.
Eigentlich müsste es ja
  1. while(taster0 = 0 || taster1 = 0)
heißen oder? Ansonsten müsste es ja passen. Denn nur dann, wenn entweder taster0 ODER taster1 gedrückt worden ist, soll die CPU aufwachen.

Quote by killermiller:
Zeile 52: hier veroderst du mit 0, das tut einfach gar nichts...
Voll vertippt hätte ich mal gesagt. Ich wollte eigentlich einfach nur '=' schreiben!

Quote by killermiller:
Ohne die Aufgabenstellung zur Hand zu haben, würde ich sagen, der Rest passt.

Dann danke ich dir mal wieder für die Korrektur!  :-)
Raim
GSPiC-Guru
Member since May 2011
79 posts
Quote by ingonör:
Das einzige, das mir gerade spontan einfällt sind die '=' Zeichen.
Eigentlich müsste es ja
  1. while(taster0 = 0 || taster1 = 0)
heißen oder? Ansonsten müsste es ja passen. Denn nur dann, wenn entweder taster0 ODER taster1 gedrückt worden ist, soll die CPU aufwachen.

Vorsicht!
= ist der Operator für eine Zuweisung, == der Vergleichsoperator.

Ich denke deine Beschreibung ist richtig gemeint, allerdings passt sie nicht zum Code. Die Bedingung gibt nämlich an, unter welchen Umständen der Mikrocontroller (wieder) schlafen gehen soll.
ingonör
Member since May 2013
67 posts
In reply to post #3
Hm, nächster Versuch:
  1. while(taster0 == 0 && taster1 == 0)

Bei ODER hätten irgendwie beide gedrückt werde müssen, damit die CPU aufwacht.
Bei UND ist es doch jetzt so, dass, sobald nur einer der beiden Taster gedrückt wurde, die CPU aufwacht. Stimmt's?
killermiller
Member since May 2011
41 posts
jetzt passts, erklärung is auch richtig...
muffdey
Member since Apr 2012
12 posts
Zeile 48 if((PINA & (0xff) == SECRET) ist ja der Vergleich zwischen SECRET und der aktuellen LED Anzeige. Hierbei verstehe ich  nicht wie ((PINA & (0xff)) genau funktioniert. Kann mir das jemand erklären? Ich dachte eher an if(PORTA== SECRET){}

Grüße

muffdey
Raim
GSPiC-Guru
Member since May 2011
79 posts
Bei Eingängen legt PORTx fest, ob ein Pull-Up-Widerstand verwendet werden soll oder nicht. Den anliegenden Wert bekommst du aus PINx.

Bei diesem 8-bit-Register ist die Verundung mit 0xff eigentlich unnötig (schadet aber auch nicht) und du hättest den Wert wie von dir vorgeschlagen direkt verwenden können.
muffdey
Member since Apr 2012
12 posts
Vielen Dank für die Antwort.

Also wären if(PORTA== SECRET)   und if(PINA==SECRET) möglich um eine komplette Maske zu vergleichen?
Für das auslesen eines Pins müsste mann dann if(PINA &(1<<2)==1) benutzen oder? //zb: war wenn der Taster an PIN 2 gerade nicht gedrückt ist //

Grüße Marvin
Raim
GSPiC-Guru
Member since May 2011
79 posts
Quote by muffdey:
Also wären if(PORTA== SECRET)   und if(PINA==SECRET) möglich um eine komplette Maske zu vergleichen?

PORTA enthält den Zustand der Pull-Up-Widerstände, PINA die anliegenden digitalen Pegel.

Quote by muffdey:
Für das auslesen eines Pins müsste mann dann if(PINA &(1<<2)==1) benutzen oder? //zb: war wenn der Taster an PIN 2 gerade nicht gedrückt ist //

Dieses Beispiel wird nie erfüllt sein. Bei Verundung mit dieser Bitmaske kann nur wieder genau dieselbe Bitmaske oder aber 0 rauskommen:
(PINA & (1<<2)) == (1<<2) oder (PINA & (1<<2)) != 0
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