Schnittstellenschaltereingang mit Siebensegmentanzeige unter Verwendung von ARM 7

Ich versuche, einen Schaltereingang zu erkennen, damit beim Drücken des Schalters eine Zahl auf der Sieben-Segment-Anzeige erhöht wird. Wenn zum Beispiel die Sieben-Segment-Anzeige anzeigt 0und der Schalter gedrückt wird, zeigt die SSD jetzt an 1. Wenn es erneut gedrückt wird, wird es angezeigt 2und so weiter.

  • Meine Sieben-Segment-Anzeige ist an P0.0 bis P0.6 angeschlossen
  • Mein Schalter steht auf P0.9

Wie kann ich jedes Mal erkennen, wenn der Schalter gedrückt wird? Ich versuche, eine Variable kin meinem Programm zu inkrementieren, so dass jedes Mal, wenn der Schalter gedrückt wird, kinkrementiert wird, und so kann ich jedes Mal, wenn der Schalter gedrückt wird, verschiedene Funktionen ausführen. Allerdings funktioniert dieser Teil nicht richtig.

Ich denke an etwas Ähnliches wie das folgende Programm. Allerdings muss ich etwas übersehen, da nur der erste Klick auf die Schaltfläche funktioniert. Wenn der Schalter gedrückt wird, 1erscheint auf dem Display. Beim erneuten Drücken passiert nichts.

#include <LPC21xx.h>
#define a 0x00000001 
#define b 0x00000002
#define c 0x00000004
#define d 0x00000008
#define e 0x00000010
#define f 0x00000020
#define g 0x00000040


void small_delay (void);

void infinite (void);
int main (void)
{
int k = 0;
unsigned int SW1;

PINSEL0 = 0;                                //Set P0.0 - P0.15 as GPIOS
PINSEL1 = 0;                                //Set P0.16 - P0.31 as GPIOS
IO0DIR  = 0xFFFFFDFF;               //Setting  P0.9 as input for SW1     

while (1)
{

    SW1 = IO0PIN & 0x00000200; //switch connected on P0.9

    if ( SW1 == 0x00000200 )        //when not pressed
    {   

    }

  if ( SW1 != 0x00000200 )  //when pressed      
    {
        k++;

        if (k == 1){
        IO0SET = b;                     
        IO0SET = c;                         //displaying number 1 

        }       

        else if (k == 2){

        IO0CLR = c; 
        IO0SET = a;
        IO0SET = b;
        IO0SET = g;                         //displaying number 2
        IO0SET = d;
        IO0SET = e;
        //small_delay();
            }
        }
    }
}

 void small_delay (void) 
 {
 unsigned int i, j;

 for (i=0; i<1000; i++)
 {  
    for (j=0; j<1000; j++)
     {
     }
 }
 }

Für Anregungen oder Hinweise, was ich verbessern könnte, wäre ich dankbar.

Antworten (2)

Zwei Probleme, die ich sehe. Erstens, wenn Sie das Display so einstellen, dass es eine 2 anzeigt, löschen Sie nicht zuerst das Display, sodass alle leuchtenden Segmente erleuchtet bleiben.

Zweitens vermute ich, dass Sie Probleme mit dem Prellen von Schalterkontakten sehen. Wenn ein Schalter oder eine Taste schließt, berühren sich die Kontakte, prallen auseinander, berühren sich erneut, prallen auseinander usw. Dies kann mehrere Millisekunden dauern und sieht für die Software wie viele sehr schnelle Tastendrücke aus.

Die Techniken, um dies zu vermeiden, werden als Entprellen bezeichnet. Sie können sie entweder in Hardware (ein Tiefpassfilter am Eingangspin) oder in Software (warten, bis der Wert am Eingang für eine feste Zeitdauer stabil bleibt) oder einer Mischung implementieren von beiden.

Einzelheiten zur Implementierung solcher Dinge finden Sie bei Google oder suchen Sie hier nach Entprellung.

Hallo Andreas, danke für deinen Beitrag zu diesem Thema. Ich habe mich für eine Verzögerung entschieden. Wird dies als gute Praxis angesehen? Bearbeitete Frage entsprechend in Bezug auf Ihre erste Ausgabe.
Im Allgemeinen ist es keine gute Übung, in einer Verzögerungsschleife zu sitzen. Wenn dies alles ist, was Sie tun, funktioniert es gut, ist aber nicht sehr portabel, da die Verzögerungszeit vom Compiler (stellen Sie sicher, dass es nicht optimiert wird), dem Prozessor und der Taktgeschwindigkeit abhängig ist. Es ist besser, Timer-Interrupts zu verwenden, dies gibt eine kontrolliertere Zeit und lässt die CPU während des Wartens frei, um andere Aufgaben zu erledigen. Das heißt, wenn Sie nur nach Tastendrücken suchen, funktioniert eine Schleife in diesem Fall gut, es sei denn, Sie sind sehr leistungskritisch.

Wie kann ich jedes Mal erkennen, wenn der Schalter gedrückt wird?

Häufiges Abfragen oder Unterbrechen reicht aus.

Allerdings funktioniert dieser Teil nicht richtig.

weil der Code falsch ist. es kann nur 1 und 2 verarbeiten. alles andere, die Anzeige bleibt unverändert. Ihr Code wird so schnell ausgeführt, dass Sie wahrscheinlich außerhalb des Bereichs liegen.

Der richtige Weg, dies zu tun, besteht darin, die Anzeigeroutine in einen Timer-Interrupt zu versetzen.