Autor Tema: Pausar un Display de 7 segmentos  (Leído 2257 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado DavFalc

  • PIC10
  • *
  • Mensajes: 4
Pausar un Display de 7 segmentos
« en: 01 de Abril de 2021, 21:07:47 »
Buenas tardes, tengo una duda con mi código, estoy realizando un contador hexadecimal, sin embargo, me gustaría agregar un botón de pausa, ya agregue un if para que me funcione el botón pero no se que declarar dentro de este para que al presionar el botón el display se quede en el dígito actual y al dejar de presionarlo siga avanzando.
A continuación pondré lo que llevo. Muchas gracias de antemano!
Código: [Seleccionar]
#include <avr/io.h>
#define F_CPU 1000000UL // 1 Mhz
#include <util/delay.h>

uint8_t DISPLAY[16] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6,0xEF,0x3F,0x9D,0x7B,0x9F,0x8F};
                    //  0  , 1  , 2  , 3  , 4  , 5  , 6  , 7  , 8  , 9  , A  , b  , C  , d  , E  , F

#define seg_7 PORTD
#define TIME  500

#define SW_0 PINB0
#define SWITCH PINB

void initialize_ports(void);

int main(void)
{
    initialize_ports();

    while (1)
    {   
 uint8_t counter = 0;
 while(counter < 16)
        {
            seg_7 = DISPLAY[counter];
            _delay_ms (TIME);
if (bit_is_clear(SWITCH,SW_0))
{

}
            counter++;

        }
       
    }
}

void initialize_ports(void)
{
    //--Entradas
DDRB  &= ~((1<<SW_0));
PORTB |=   (1<<SW_0) ;//Pull - up
    //--Salidas
    DDRD  = 0xFF; // Declara el puerto D como salida
    seg_7 = 0x00; //Inicializa el PORTD [7:0] en estado bajo (low) "0"
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Pausar un Display de 7 segmentos
« Respuesta #1 en: 01 de Abril de 2021, 21:18:26 »
Primero que nada:  delays... Siempre es malo... pero si queres hacerlo así entonces:

Código: C
  1. while(1) {
  2.         if (bit_is_clear(SWITCH,SW_0))
  3.         {
  4.             counter++;
  5.             if(counter > 15) counter = 0;
  6.         }
  7.         seg_7 = DISPLAY[counter];
  8.         _delay_ms (TIME);
  9. }

A lo sumo cambias el bit_is_clear por bit_is_set.

Asi cuando NO esta presionado, entre al if, y cuando lo presionas, no entre.

Desconectado DavFalc

  • PIC10
  • *
  • Mensajes: 4
Re:Pausar un Display de 7 segmentos
« Respuesta #2 en: 01 de Abril de 2021, 21:33:58 »
Muchas gracias killerjc! ya me funciono, y me surgio la duda de como seria sin delays??

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Pausar un Display de 7 segmentos
« Respuesta #3 en: 02 de Abril de 2021, 11:59:19 »
Se refiere a usar interrupciones para las temporizaciones.  No solo no te bloquea la ejecución sino que te permite diferentes temporizaciones/tareas simultáneas.

Queda mas complicado el inicio pues obviamente hay que configurar el timer.
Las líneas terminadas con //***  son agregados a tu programa.

Código: [Seleccionar]
#include <avr/io.h>
#include <avr/interrupt.h>                              //***

#define F_CPU 1000000UL // 1 Mhz
#include <util/delay.h>

uint8_t DISPLAY[16] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6,0xEF,0x3F,0x9D,0x7B,0x9F,0x8F};
                    //  0  , 1  , 2  , 3  , 4  , 5  , 6  , 7  , 8  , 9  , A  , b  , C  , d  , E  , F

#define seg_7 PORTD
#define TIME  500

#define SW_0 PINB0
#define SWITCH PINB

void initialize_ports(void);

volatile uint8_t counter = 0;                           //***
                                                        //***
                                                        //***
// 0  No clock source (Timer/Counter stopped).          //***
// 1  clkI/O/1      (no prescaling)                     //***
// 2  clkI/O/8      (from prescaler)                    //***
// 3  clkI/O/64     (from prescaler)                    //***
// 4  clkI/O/256    (from prescaler)                    //***
// 5  clkI/O/1024   (from prescaler)                    //***
                                                        //***
//  prescaler 64                                        //***
#define PRESCALER 3                                     //***
                                                        //***
ISR(TIMER1_COMPA_vect){                                 //***
                                                        //***
    if(++counter == 16) counter = 0 ;                   //***
                                                        //***
    seg_7 = DISPLAY[counter];                           //***
}                                                       //***

int main(void)
{
    uint8_t stop = 0;                                   //***

    initialize_ports();

    seg_7 = DISPLAY[counter];

    sei() ;                                             //***
    while (1)                                           //***
    {                                                   //***
        if (bit_is_clear(SWITCH,SW_0)){                 //***
            TCCR1B &= ~7    ;       //Paro el contador  //***
            stop = 1;                                   //***
        }                                               //***
        if(stop && bit_is_set(SWITCH,SW_0)){            //***
            TCCR1B |= PRESCALER ; //Activo el contador  //***
            stop   = 0 ;                                //***
        }                                               //***
                                                        //***
        //  resto del codigo aqui                       //***
        //..................                            //***
        //..................                            //***
                                                        //***
    }                                                   //***
}

void initialize_ports(void)
{
    //--Entradas
DDRB  &= ~((1<<SW_0));
PORTB |=   (1<<SW_0) ;//Pull - up
    //--Salidas
    DDRD  = 0xFF; // Declara el puerto D como salida
    seg_7 = 0  ;  //Inicializa el PORTD [7:0] en estado bajo (low) "0"

// Timer/Counter 1 initialization         //***
// Clock source: System Clock 1MHz        //***
// Clock value: 15.625 kHz                //***
// Mode: CTC top=OCR1A                    //***
// Compare A Match Interrupt: On          //***
    TCCR1A = 0x00;                        //***
    TCCR1B = 8 + PRESCALER ;              //***
    TCNT1  = 0x00;                        //***
    ICR1   = 0x00;                        //***
    OCR1A  = TIME/.512 ;                  //***
                                          //***
    TIMSK1=0x02;                          //***
}


 

anything