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
intmain(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
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.
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
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.
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).
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
@ 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 . . .
> 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.