mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem bei Programmierung


Autor: Daniel H. (daniel_fh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Tajas R. (tony)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ganz ohne Code kann ich dein Problem nicht erkennen... Oder hakt es 
schon bei der Umsetzungsidee?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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/Entprellun...

Autor: Daniel H. (daniel_fh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: dsgbn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du brauchst eine Variable, die enthaelt:
entweder was zuletzt ausgeschaltet wurde
oder was als naechstes eingeschaltet werden soll.

Gast

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unabhängig von einem MC könnte es etwa so aussehen:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>


// Dummyfunktion:
void holeTastendruck()
{
  sleep( 1 );
}

int main( )
{
  // zustand wird jeweils um 1 weiter gezählt, nach 4 Zuständen geht
  // es wieder vorne los:
  uint8_t   zustand = 0;

  while( 1 )
  {
    switch( zustand )
    {
      case 0:
        printf( "PB0 = 0 PB1 = 0\n" );
        break;

      case 1:
        printf( "PB0 = 1 PB1 = 0\n" );
        break;

      case 2:
        printf( "PB0 = 0 PB1 = 0\n" );
        break;

      case 3:
        printf( "PB0 = 0 PB1 = 1\n" );
        break;

      default :
        // kommt nie vor
        break;
    }

    // Tastendruck holen:
    holeTastendruck();

    zustand++;
    zustand %= 4;

  }

  return 0;
}

Statt holeTastendruck() musst du halt deine Variante einbauen
um die Taste zu erkennen, und statt der printf-Ausgaben deine
Ausgänge passend setzen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas nennt sich Statemaschine:
uint8_t state = 0;
for(;;){
  if( debounce( PIND, 0 ))
    state++;
  switch( state ){
    case 1:  PORTB |= 1<<PB0; break;
    case 2:  PORTB &= ~(1<<PB0); break;
    case 3:  PORTB |= 1<<PB1; break;
    default: state = 0;
             PORTB &= ~(1<<PB1); break;
  }
}


Peter

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte auch Zustandsautomat sagen:
...
  uint8_t   zustand = 0;
...

:-)

Autor: Daniel H. (daniel_fh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay...
Vielen Dank für eure schnelle Hilfe!!!

Probier das gleich mal aus, bin mal gespannt ob ichs hingrieg...
Also, nochmal Danke!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.