Nicht angemeldet. · Kennwort vergessen · Registrieren

ingonör
Mitglied seit 05/2013
67 Beiträge
Betreff: 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. }
Dieser Beitrag wurde am 19.07.2013, 09:12 von ingonör verändert.
killermiller
Mitglied seit 05/2011
41 Beiträge
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
Mitglied seit 05/2013
67 Beiträge
Zitat von 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!

Zitat von 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.

Zitat von 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!

Zitat von 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
Mitglied seit 05/2011
79 Beiträge
Zitat von 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
Mitglied seit 05/2013
67 Beiträge
Antwort auf Beitrag #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
Mitglied seit 05/2011
41 Beiträge
jetzt passts, erklärung is auch richtig...
muffdey
Mitglied seit 04/2012
12 Beiträge
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
Mitglied seit 05/2011
79 Beiträge
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
Mitglied seit 04/2012
12 Beiträge
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
Mitglied seit 05/2011
79 Beiträge
Zitat von 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.

Zitat von 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
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:
Gehe zu Forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen