Forum: Compiler & IDEs Attiny13A einfache Quizschaltung


von Marcel A. (marcel_lat)


Lesenswert?

Hallo Liebe µC Gemeinde,

ich habe mir einen Atmel AVRISP MKII zugelegt, um einen Attiny13A zu 
programmieren. Rauskommen soll eine Quizschaltung, also 2 Spieler und 2 
LEDs, wer als erster drückt bei dem leuchtet es beim anderen nicht. Für 
die Spielerknöpfe verwende ich ganz normale Kurzhubtaster mit 22pF 
Kodensator parallel geschalten. Taster liegt auf GND und dem jeweilen 
PIN des µC.
Als Test habe ich einfach mal zwei LED abwechselnd Blinken lassen, das 
hat funktioniert. Aber die Quizschaltung möchte einfach nicht und ich 
weiß nicht mehr weiter. Vielleicht findet jemand das Problem.

Gruß Marcel
1
/*
2
 * Quiz.c
3
 *
4
 * Created: 16.03.2014 17:21:56
5
 *  Author: Marcel
6
 */ 
7
8
#define F_CPU 1000000
9
#include <avr/io.h>
10
11
//PB 2 LED A
12
//PB 1  LED B
13
//PB 5  SW A
14
//PB 3  SW B
15
//PB 4  SW RESET
16
17
18
19
int main(void)
20
{  
21
  DDRB = 0b000110;   //B2 und B1 auf Ausgang
22
  PORTB= 0b111000;  //B 0-2 auf low, B 3-6 auf High (SW Input)
23
  
24
25
    while(1)
26
    {  
27
      if ((PINB & (1<<5)) == 0){
28
        if((PINB & (1<<1)) == 0){ //Abfrage SW A, wenn dann LEDA schalten
29
          PORTB |= (1<<2);
30
        }
31
      }
32
    
33
      if ((PINB & (1<<3)) == 0){
34
        if((PINB & (1<<2)) == 0){ //Abfrage SW B, wenn dann LEDB schalten
35
          PORTB |= (1<<1);
36
        }
37
      }
38
      if ((PINB & (1<<4)) == 0){  //reset Button
39
        PORTB &=~(1<<2);
40
        PORTB &=~(1<<1);
41
      }
42
    }
43
}

von Karl H. (kbuchegg)


Lesenswert?

Marcel Amthor schrieb:

> die Spielerknöpfe verwende ich ganz normale Kurzhubtaster mit 22pF
> Kodensator parallel geschalten.

Schlecht.
Solche Konstruktionen sind notorisch dafür bekannt, durch kurze 
Spannungseinbrüche auf der Versorgungsspannung, dieselbe zum Einsturz zu 
bringen, wodurch der µC abstürzen kann.

Löte die Kondensatoren aus. In deinem Beispiel brauchst du die nicht. 
Wer als erster drückt gewinnt, egal ob die Taste danach noch ein paar 
mal prellt oder nicht.

von gatsby (Gast)


Lesenswert?

Hallo,

mit dieser Zeile

        if((PINB & (1<<1)) == 0){ //Abfrage SW A, wenn dann LEDA 
schalten

willst du prüfen ob die LED des Gegners schon eingeschaltet ist.
Da dies aber ein Ausgang ist, muss das heißen

        if((PORTB & (1<<1)) == 0){ //Abfrage SW A, wenn dann LEDA 
schalten

Außerdem verwirrt der Kommentar.


Gruß
gatsby

von Karl H. (kbuchegg)


Lesenswert?

gatsby schrieb:
> Hallo,
>
> mit dieser Zeile
>
>         if((PINB & (1<<1)) == 0){ //Abfrage SW A, wenn dann LEDA
> schalten
>
> willst du prüfen ob die LED des Gegners schon eingeschaltet ist.
> Da dies aber ein Ausgang ist, muss das heißen
>
>         if((PORTB & (1<<1)) == 0){ //Abfrage SW A, wenn dann LEDA
> schalten

Es geht beides.
Mit PORT kriegt man den Pegel, den das Programm eingestellt hat., Mit 
PIN kriegt man den Pegel, den der Pin tatsächlich hat (nach einer kurzen 
Verzögerungszeit nach dem Setzen von PORT). Solange man keinen 
Kurzschluss hat und der Pin den am PORT eingestellten Pegel tatsächlich 
auch annehmen kann, stimmen die beiden Werte (nach 1 CPU Takt) überein.

Ich hätte es auch in der PORT Variante geschrieben, weil es meiner 
Meinung nach klarer ist, was hier die Absicht ist. Aber direkt falsch 
ist es nicht.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Marcel Amthor schrieb:
> Aber die Quizschaltung möchte einfach nicht

Das ist ja mal ne besonders ausführliche Fehlerbeschreibung, Hut ab.

Der Code sieht o.k. aus.
Ich würde noch ne Flankenerkennung einbauen gegen Schummeln (zu früh 
drücken).

von Marcel A. (marcel_lat)


Angehängte Dateien:

Lesenswert?

So vielen Dank für die Antworten!

Ich habs dann doch endlich hinbekommen. Der erste Fehler war PINB5 
überhaupt als IO port zu nutzen. Wenn nämlich Reset Fuse nicht gesetzt 
ist, wird das nichts. Also nutze ich nun die Pins 0-4 und verwende 
wieder die "bit_is_clear" Funktion zum abfragen der Pins. Zweite Sache 
die mir beim rumtesten auffiel, war dann die Tasterpins nach dem 
Abfragen wieder auf 1 zusetzen. Damits hats schlussendlich funktioniert. 
Anbei noch mal der neue Code und was fürs Auge :)

Vielen Danke nochmal an alle die mitgrübelten.

Grüße Marcel
1
/*
2
 * GccApplication1.c
3
 *
4
 * Created: 25.03.2014 12:26:07
5
 *  Author: Marcel
6
 */ 
7
#define F_CPU 1000000
8
#include <util/delay.h>
9
#include <avr/io.h>
10
int press=0;
11
12
int main(void)
13
{  DDRB=0b00000110;
14
  PORTB=0xFF;
15
    while(1)
16
    {   
17
    
18
    if (bit_is_clear(PINB, PINB0)  && press==0){
19
      PORTB=0b00011101;
20
      press=1;
21
    } 
22
    if (bit_is_clear(PINB, PINB3) && press==0){
23
      PORTB=0b00011011;
24
      press=1;
25
    }
26
    if (bit_is_clear(PINB, PINB4)){
27
      PORTB=0b00011001;
28
      press=0;
29
    }
30
  
31
    
32
     }  
33
    
34
}

von Falk B. (falk)


Lesenswert?

@ Marcel Amthor (marcel_lat)

>wieder die "bit_is_clear" Funktion zum abfragen der Pins. Zweite Sache

Die ist eher veraltet, die gab es früher mal, als der avr gcc noch nicht 
so ganz fit war.

>die mir beim rumtesten auffiel, war dann die Tasterpins nach dem
>Abfragen wieder auf 1 zusetzen. Damits hats schlussendlich funktioniert.

Nicht gut. Einfach den Port als Ganzes setzen geht bestenfalls bei 
diesem sehr einfachen Programm. Sobald es ETWAS größer wird, versinkst 
du im Chaos. Also lerne etwas über Bitmanipulation und wie man 
einzelne Bits gezielt abfragen oder schreiben kann.

>Anbei noch mal der neue Code und was fürs Auge :)

Naja . . .
Beides eher hyperfluide . . .

von Karl H. (kbuchegg)


Lesenswert?

> Naja . . .
> Beides eher hyperfluide . . .

Vor allen Dingen.
Die Bitzugriffe im Originalprogramm waren alle in Ordnung. Es gibt 
keinen Grund, warum ein bit_is_clear bzw. das Zuweisen des ganzen Ports 
irgendetwas mit dem Fehlersymptom zu tun haben sollte.

OK. Das du irrtümlich den Reset-Pin 'mitbenutzt' hast, das ist natürlich 
ein grober Schnitzer. Davon bin ich eigentlich nicht ausgegangen und das 
hab ich nicht mit dem Datenblatt kontrolliert.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.