Interfaz de entrada de interruptor con pantalla de siete segmentos usando ARM 7

Estoy tratando de detectar una entrada de interruptor para que, si se presiona el interruptor, se incremente un número en la pantalla de siete segmentos. Por ejemplo, si la pantalla de siete segmentos muestra 0y se presiona el interruptor, la SSD ahora mostrará 1. Si se pulsa de nuevo, se mostrará 2y así sucesivamente.

  • Mi pantalla de siete segmentos está conectada en P0.0 a P0.6
  • MI interruptor está en P0.9

¿Cómo puedo detectar cada vez que se presiona el interruptor? Estoy tratando de incrementar una variable ken mi programa para que cada vez que se presione el interruptor, kse incremente y, por lo tanto, pueda realizar diferentes funciones cada vez que se presione el interruptor. Sin embargo, esta parte no funciona correctamente.

Estoy pensando en algo similar al siguiente programa. Sin embargo, debo estar pasando por alto algo ya que solo funciona el primer clic del botón. Cuando se presiona el interruptor, 1aparece en la pantalla. No pasa nada cuando se vuelve a pulsar.

#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++)
     {
     }
 }
 }

Cualquier sugerencia o sugerencia sobre lo que podría mejorar, sería apreciada.

Respuestas (2)

Dos problemas que puedo ver. En primer lugar, cuando configura la pantalla para que muestre un 2, no borra primero la pantalla para que todos los segmentos que estaban encendidos permanezcan encendidos.

En segundo lugar, creo que está viendo problemas de rebote de contacto de interruptor. Cuando un interruptor o botón se cierra, los contactos se tocan, se separan, se tocan de nuevo, se separan, etc. Esto puede continuar durante varios milisegundos y se verá como muchas pulsaciones de botón muy rápidas en el software.

Las técnicas para evitar esto se conocen como antirrebote, puede implementarlas en hardware (un filtro de paso bajo en el pin de entrada) o software (esperar a que el valor en la entrada permanezca estable durante un período de tiempo fijo) o una combinación de ambos.

Para obtener detalles sobre cómo implementar este tipo de cosas, consulte Google o busque aquí para eliminar rebotes.

Hola Andrés, gracias por tu aporte sobre este asunto. He decidido implementar un retraso. ¿Se considera esto una buena práctica? Pregunta editada en consecuencia con respecto a su primer problema.
En general, sentarse en un bucle de retardo no es una buena práctica. Si esto es todo lo que está haciendo, entonces funciona bien, pero no es muy portátil ya que el tiempo de retraso depende del compilador (asegúrese de que no se optimice), del procesador y de la velocidad del reloj. Es una mejor práctica usar interrupciones de temporizador, esto brinda un tiempo más controlado y deja a la CPU libre para realizar otras tareas mientras espera. Dicho esto, si todo lo que está haciendo es buscar presionar un botón, entonces, a menos que sea muy crítico con la energía, un bucle funciona bien en este caso.

¿Cómo puedo detectar cada vez que se presiona el interruptor?

sondear con frecuencia o interrumpir será suficiente.

Sin embargo, esta parte no funciona correctamente.

porque el código está mal. puede manejar solo 1 y 2. cualquier otra cosa, la pantalla no cambia. su código se ejecuta tan rápido que probablemente esté fuera de rango.

la forma correcta de hacer esto es poner la rutina de visualización en una interrupción de temporizador.