PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu C++



Decca
26.02.2005, 12:41
Hallo!

Ich habe mir einen ISP Adapter gebaut und ein kleines experimentierboard für meinen AVR (ATmega8). Funktioniert auch alles ganz gut. Nun möchte ich ein Programm schreiben mit folg. Funktionsweise. Wenn Taster 1 an pinD1 gedrückt dann led 1 an portB1
das ganze in eine for-Schleife, soll einen Zähler ergeben. Wenn dann nochmal Taster 1 dann led 2.... bis es zehn mal durch laufen wurde. So sollte es meiner Meinung nach funktionieren, tut es aber nicht. Ich habe schon sehr lange nach fehlern oder anderen Möglichkeiten gesucht und wäre für jede Hilfe dankbar
Ich arbeite mit WinAVR falls das von Bedeutung ist.

Hier mein Programm:

#include <avr/io.h>

int main(void) {
int i;
unsigned int keys;
DDRB = 0xff; // PORTB als Ausgang
DDRD = 0x00; // PORTD als Eingang
PORTB = 0xff; // setzt alle Ausgangsport auf H-Pegel --> leds aus

for (i=0;i<10;i++) {
keys = ~PIND;


if ( keys & 1 )

PORTB &= ~(1<<PB0+i);


}
}


Grüße Decca

Arexx-Henk
26.02.2005, 13:59
Hallo Decca,


int main(void) {
int i;

unsigned int keys;

'keys' braucht nur unsigned char=8bit, unsigned int (16bit) ist aber nicht falsch, mann sollte dennoch acht geben wenn '|' '~' oder '&' benutzt wird
mit Ports den wass geschied mit bits 8-15?

DDRB = 0xff; // PORTB als Ausgang
DDRD = 0x00; // PORTD als Eingang
PORTB = 0xff; // setzt alle Ausgangsport auf H-Pegel --> leds aus


for (i=0;i<10;i++) {

keys = ~PIND;

Ich nehme an, ein Tastendruck macht eingang PIND niedrich...
Hier wird 'keys' z.B hex 0xFB wenn Taste 3 von 8 gedruckt wird
(bit2 is '0')

if ( keys & 1 )

Ich nehme an dass hinten '& 1 )' ein '{' stehen sollte
Die 'if' wird immer ausgefuhrt wenn Taste 1 NICHT gedruckt ist. Denn
wenn Taste 1 nicht gedruckt ist wird bit0 in 'keys' '1'

PORTB &= ~(1<<PB0+i);

Mein compiler gibt hier eine Warnung. Besser wahre extra Haken.
PORTB &= ~(1<<(PB0+i));

}
}

Nirgendwo wird hier vom Program auf eine Tasendruck gewartet. Dass ganze Program sollte innerhalb (beim 8MHz oscillator) ungefahr 10 * 5 ist ungefahr 50 microseconden abgelaufen sein! Da muss man ja ganz schnell drucken!

Gruss,

Henk

Decca
26.02.2005, 14:10
Danke für die Antwort.
Wie sage ich ihm denn jetzt dass er warten soll bis Taster 1 gedrückt ist?

Arexx-Henk
26.02.2005, 15:11
Hallo Decca,

Man konnte die 'for (i=0;i<10;i++) { '

erzetsen durch

for(;; ){

oder durch

while(1){

dann wird die Schleife immer wieder durchlaufen

mit einem 'break;' verlasst man die Schleife.


if (! keys & 1 ){ //'not' verwenden wenn Tastendruck 'keys' bit niedrich macht
for(i=0;i<1000;i++); //warte mahl einige zeit um die Schalter die Zeit zu geben gut Kontakt zu machen, manchmal zittern die kontakten 10-100 mahl befor die endlich zu sind. (lange zoll man ausprobieren)
mache_etwas();
while( keys & 1); //warte hier bis Taste wieder freigegeben ist sonst wird die Taste 1000-den mahlen gedrukt detectiert.
}

Es gibt auch Tasten die nicht zittern aber normale Taster zittern immer und while die Schleife so Blitzschnell ist wird dass Zittern als mehere Tastendrucken erkannt.

Gruss

Henk

Decca
26.02.2005, 15:35
Gut hab das mal ausprobiert. Funktioniert leider auch nicht. Ich glaube es liegt daran das ich ein Verständnisproblem hab.

Ich habe hier ein kurzes Progr.:
#include <avr/io.h>

int main(void) {
int i=0;
unsigned int keys;
DDRB = 0xff; // PORTB als Ausgang
DDRD = 0x00; // PORTD als Eingang
PORTB = 0xff; // setzt alle Ausgangsport auf H-Pegel --> leds aus

for (;;) {
keys = ~PIND;

PORTB=0xff;
if ( keys & 1 )

PORTB &= ~(1<<PB0+i);
}
}

da leuchtet meine led an pb0 wenn ich meinen taster 1 drücke, und so wie ich das verstanden hab wird die for schleife unendlich mal durchlaufen, und wenn ich nun taster1 drücke....
und das klapt nich mit i++, drinn.

DANKE für die geduldigen Antworten

Arexx-Henk
26.02.2005, 17:11
Hallo Decca,




//alle leds aus
PORTB=0xff;

//fang an mit led1
i=0;

//fur immer...
for (; ;){

//plaziere invertiere tasten data in 'keys' ('1'-bit heisst jetzt taste gedruckt)
keys = ~PIND;

//wenn taste 1 gedrukt...
if ( keys & 1 )

//mache led (1+i) an
PORTB |= ^(1<<PB0+i); //'^'=exclusive-oder benuzten und nicht '&'=und

}
//warte hier bis alle tasten los gelassen sind
while(keys|=0xFF);
}

//selectiere mahl nachste led die angehen soll
i++;

}//fang mahl wieder von vorne bei 'fur immer' an


7654 3210 bits

1111 1111 PORTB alle leds aus
0000 0001 X=(1<<PB0+i) //i=0
1111 1110 'PORTB^=X' macht led1 an

1111 1110 PORTB = led1 an
0000 0010 X=(1<<PB0+i) //i=1
1111 1100 'PORTB^=X' macht led2 dabei auch an

Ich weiss, es ist immer ein bischen schwer wenn mann '0' als 'eingeschaltet' betrachten soll und mann Exclusive-Or anwendet.

Exclusive-Or = nur die bits die beide bytes gleich haben werden im resultat byte getauchst nach '0'. Anders gesagt: nur wenn eine von beiden bits '1' is wird das resultatbit auch '1'.
0 + 0 = 0
1 + 0 = 1
0 + 1 = 1
1 + 1 = 0




Gruss

Henk

Decca
26.02.2005, 17:57
Danke für deine Hilfe Henk!
Mit der Erklärung bin ich schon mal einen ganzen Schritt weiter.

Gruss Decca