Hallo Leute, ich habe ein kleines Problem. Bin Anfänger in Sachen AVR µC. Programmiere in C, hab selbst schon ein paar kleine "Progrämmchen" geschrieben. Nur komm ich momentan nicht weiter, obwohl die Funktion einfach sein sollte. Also, ich moöchte mit nur einem Taster jeweils 1 LED an zwei Ausgäng schalten und zwar immer in dieser Reihenfolge: (Tb = Taster betätigen, Taster z.B an PD0) Tb --> PB0 = 1 , Tb --> PB0 = 0 , Tb --> PB1 = 1 , Tb --> PB1 = 0 , und wieder von vorne beginnen... Hoffe mal von euch weis jemand Rat, ich komme einfach nicht drauf. Danke schon einmal Voraus für eure Bemühungen.
So ganz ohne Code kann ich dein Problem nicht erkennen... Oder hakt es schon bei der Umsetzungsidee?
Ich denke es handelt sich wieder mal um das übliche 'Wie erkenne ich einen Tastendruck' anstelle des 'die Taste ist momentan gerade gedrückt' Problems. Und die Antwort darauf führt über die Entprellung: http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
Naja... Mehr oder weniger, hab schon ein paar Sachen ausprobiert... #include <avr/io.h> #ifndef F_CPU #define F_CPU 8e6 #endif #include <util/delay.h> /****************************************************/ /* */ /* Not so powerful Debouncing Macro */ /* No Interrupt needed */ /* */ /* Author: Peter Dannegger */ /* */ /****************************************************/ // Modification for active high push button #define debounce( port, pin ) \ ({ \ static uint8_t flag = 0; /* new variable on every macro usage */ \ uint8_t i = 0; \ \ if( flag ){ /* check for key release: */ \ for(;;){ /* loop... */ \ if( (port & 1<<pin) ){ /* ... until key pressed or ... */ \ i = 0; /* 0 = bounce */ \ break; \ } \ _delay_us( 98 ); /* * 256 = 25ms */ \ if( --i == 0 ){ /* ... until key >25ms released */ \ flag = 0; /* clear press flag */ \ i = 0; /* 0 = key release debounced */ \ break; \ } \ } \ }else{ /* else check for key press: */ \ for(;;){ /* loop ... */ \ if( !(port & 1<<pin) ){ /* ... until key released or ... */ \ i = 0; /* 0 = bounce */ \ break; \ } \ _delay_us( 98 ); /* * 256 = 25ms */ \ if( --i == 0 ){ /* ... until key >25ms pressed */ \ flag = 1; /* set press flag */ \ i = 1; /* 1 = key press debounced */ \ break; \ } \ } \ } \ i; /* return value of Macro */ \ }) /* Debouncing Example */ void ausgang1(void) { if( debounce( PIND, PD0 ) ) { PORTB ^= 1<<PB0; // Toggle @PB0 } int main(void) { // PD0 als Eingang DDRD &= ~(1<<PD0); PORTD |= (1<<PD0); // not needed because active high // Jeder Pin ist Ausgang DDRB = 0xFF; ausgang1(); } Das Programm zum entprellen is hier vom Forum. Im Moment Toggelt der Ausgang nur. Weis nicht wie ich weiter schreiben soll um den Ausgang zwei anzusprechen... Wollte die beiden Ausgänge jeweils in 2 Funktionen packen, oder ist das schon zu aufwendig?
Du brauchst eine Variable, die enthaelt: entweder was zuletzt ausgeschaltet wurde oder was als naechstes eingeschaltet werden soll. Gast
unabhängig von einem MC könnte es etwa so aussehen:
1 | #include <stdio.h> |
2 | #include <stdint.h> |
3 | #include <stdlib.h> |
4 | |
5 | |
6 | // Dummyfunktion:
|
7 | void holeTastendruck() |
8 | {
|
9 | sleep( 1 ); |
10 | }
|
11 | |
12 | int main( ) |
13 | {
|
14 | // zustand wird jeweils um 1 weiter gezählt, nach 4 Zuständen geht
|
15 | // es wieder vorne los:
|
16 | uint8_t zustand = 0; |
17 | |
18 | while( 1 ) |
19 | {
|
20 | switch( zustand ) |
21 | {
|
22 | case 0: |
23 | printf( "PB0 = 0 PB1 = 0\n" ); |
24 | break; |
25 | |
26 | case 1: |
27 | printf( "PB0 = 1 PB1 = 0\n" ); |
28 | break; |
29 | |
30 | case 2: |
31 | printf( "PB0 = 0 PB1 = 0\n" ); |
32 | break; |
33 | |
34 | case 3: |
35 | printf( "PB0 = 0 PB1 = 1\n" ); |
36 | break; |
37 | |
38 | default : |
39 | // kommt nie vor
|
40 | break; |
41 | }
|
42 | |
43 | // Tastendruck holen:
|
44 | holeTastendruck(); |
45 | |
46 | zustand++; |
47 | zustand %= 4; |
48 | |
49 | }
|
50 | |
51 | return 0; |
52 | }
|
Statt holeTastendruck() musst du halt deine Variante einbauen um die Taste zu erkennen, und statt der printf-Ausgaben deine Ausgänge passend setzen.
Sowas nennt sich Statemaschine:
1 | uint8_t state = 0; |
2 | for(;;){ |
3 | if( debounce( PIND, 0 )) |
4 | state++; |
5 | switch( state ){ |
6 | case 1: PORTB |= 1<<PB0; break; |
7 | case 2: PORTB &= ~(1<<PB0); break; |
8 | case 3: PORTB |= 1<<PB1; break; |
9 | default: state = 0; |
10 | PORTB &= ~(1<<PB1); break; |
11 | }
|
12 | }
|
Peter
Man könnte auch Zustandsautomat sagen:
1 | ...
|
2 | uint8_t zustand = 0; |
3 | ...
|
:-)
Okay... Vielen Dank für eure schnelle Hilfe!!! Probier das gleich mal aus, bin mal gespannt ob ichs hingrieg... Also, nochmal Danke!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.