Autor Tema: Interrupcion Pause/Play  (Leído 3534 veces)

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

Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Interrupcion Pause/Play
« en: 06 de Abril de 2020, 13:54:36 »
Buen día a todos, verán estoy creando el código de programación para un reloj digital en lenguaje C, el código ya lo tengo todo y funciona muy bien, lo único que me falta es implementar una boton en el PIN RB0 (INT0) que me interrumpa el conteo del reloj  y que cuando se presione nuevamente  se reanude la cuenta del reloj
La verdad he intentado de todo y no se  como hacer para detener y reanudar el conteo, ayuda porfavor.

Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Re:Interrupcion Pause/Play
« Respuesta #1 en: 06 de Abril de 2020, 13:55:21 »
Aclaro que estoy usando el PIC18F4550 y usando el simulador MPLABX

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion Pause/Play
« Respuesta #2 en: 06 de Abril de 2020, 13:56:34 »
Esto va a depender de como es el conteo. Complicado de ayudarte sin un codigo.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Interrupcion Pause/Play
« Respuesta #3 en: 06 de Abril de 2020, 14:21:12 »
Como dice Killer, es necesario saber como haces el conteo. Si es mediante algún timer del pic sería tan sencillo como invocar el bit que habilita o desahibilita el timer que uses y hacerle una negación:

  Si por ejemplo es el timer0, sería el bit 7 (TMR0ON) del registro T0CON

  !T0CONbits.T0CON;

 Eso es lo único que tendrías que poner en la rutina de la interrupción.

Eso para el compilador Xc8

Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Re:Interrupcion Pause/Play
« Respuesta #4 en: 06 de Abril de 2020, 15:30:22 »
Amigos el conteo lo estoy haciendo mediante bucles for. No estoy usando el timer 0,
while (19{
For(condicion){
     For(condicion){
         For(condicion){
              For(condicion){
                   For(condicion){
                        For(condicion){

                               CODIGO

}
}
}
}
}
}
}
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion Pause/Play
« Respuesta #5 en: 06 de Abril de 2020, 15:37:21 »
Ese es tu problema entonces... Vas a tener que cambiar la forma de contar...

Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Re:Interrupcion Pause/Play
« Respuesta #6 en: 06 de Abril de 2020, 15:40:24 »
No me digas eso :((, no hay una forma de interrumpir por ejemplo el ciclo while(1)  Para dar la instruccion de pause and play?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion Pause/Play
« Respuesta #7 en: 06 de Abril de 2020, 16:04:13 »
Si, con un break... Pero cuando tenes Multiples for anidados, entonces la unica es con un goto, que jamas deberias usar.
Todo aumentando la claridad del programa.

En fin, para evitar problemas y que sea sencillo de entender/trabajar deberias repensar en la forma de contar.


PD: Esto hablando de:
- No se que estas contando
- Lo unico que se es que tenes muchos for, debido a que no hay programa.

Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Re:Interrupcion Pause/Play
« Respuesta #8 en: 06 de Abril de 2020, 16:55:41 »
#include <xc.h>

#define _XTAL_FREQ 4000000

#pragma config FOSC=HS
#pragma config WDT=OFF
#pragma config PBADEN=OFF //Liberar pines analogos del puerto B
#pragma config LVP=OFF //Para utilizar el pin RB5

#define display PORTD

int A, B, C, D, cuenta, segundos;
int numeros[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98};
int retardoLED, retardo1, minuto, minuto1, segundo, segundo1, hora, hora1;
int led[]={0x01,0x00};

void main(void){
   
    ADCON1=7;//Apagar I/O Analogicas
    TRISA=0; //Puerto A como salida
    TRISC=0; //Puerto C como salida
    TRISD=0; //Puerto D como salida
    LATA=0; //Salida del puerto A inicia en '0'
    LATC=0; //Salida del puerto C inicia en '0'
    LATD=0; //Salida del puerto D inicia en '0'
    TRISB=0xff; //Puerto B como entrada
    INT0IF=0; // Borrar la bandera de la interrupcion del pin RB0
    INT0IE=1; //Habilitar interrupcion del pin RB0
    INTCON3bits.INT1IF=0; // Borrar la bandera de la interrupcion del pin RB1
    INTCON3bits.INT1IE=1; //Habilitar interrupcion del pin RB1
    INTCON3bits.INT2IF=0; // Borrar la bandera de la interrupcion del pin RB2
    INTCON3bits.INT2IE=1; //Habilitar interrupcion del pin RB2
    GIE=1; //Habilitar interrupciones globales
    //Se deja la configuracion estandar (se dispara enflancos de subida)
   
    while(1){
        for(hora1=0; hora1<=2; hora1++){
        for(hora=0; hora<=9; hora++){
        for(minuto1=0; minuto1<=5; minuto1++){
        for(minuto=0; minuto<=9; minuto++){
        for(segundo1=0; segundo1<=5; segundo1++){
        for(segundo=0; segundo<=9; segundo++){
        for(retardoLED=0; retardoLED<=1; retardoLED++){
        for(retardo1=0; retardo1<=25; retardo1++){
            //configuracion LED a modo de CPU
            LATC=led[retardoLED];
            __delay_ms(10);
            //configuracion numeros horas, minutos y segundos
            LATA=0x01;
            display=numeros[segundo];
            __delay_ms(1);
            LATA=0x02;
            display=numeros[segundo1];
            __delay_ms(1);
            LATA=0x04;
            display=numeros[minuto];
            __delay_ms(1);
            LATA=0x08;
            display=numeros[minuto1];
            __delay_ms(1);
            LATA=0x10;
            display=numeros[hora];
            __delay_ms(1);
            LATA=0x20;
            display=numeros[hora1];
            __delay_ms(1);
            if(hora==4 & hora1==2){
                hora=0;
                hora1=0;
            }
        }
        }
        }
        }
        }
        }
        }
        }
    }
}

Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Re:Interrupcion Pause/Play
« Respuesta #9 en: 06 de Abril de 2020, 16:57:43 »
Mira entonces como te comentaba la idea es implementar una boton en el PIN RB0 (INT0) que me interrumpa el conteo del reloj  y que cuando se presione nuevamente  se reanude la cuenta del reloj

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Interrupcion Pause/Play
« Respuesta #10 en: 07 de Abril de 2020, 05:39:09 »
Ahí tal y como lo tienes planteado lo que haría utilizar una variable booleana global que se llame por ejemplo stop_ , y en la interrupción lo que haces es cambiar el estado de este bit y además añade condicionales conjugando con la propia bandera de interrupción y el pin del pulsador para que stop_ no pueda volver a cambiar de estado hasta que no lo sueltes,’

  Luego encierra todo el bloque de multiplexado de los displays en un:

do {

 } while (stop_);

   Si Stop_ está a uno, no saldrá de este bucle por lo que los displays se quedarán mostrando el último valor del reloj.  Cuando stop_ sea cero de nuevo correrán todos los for.
« Última modificación: 07 de Abril de 2020, 05:44:04 por remi04 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion Pause/Play
« Respuesta #11 en: 07 de Abril de 2020, 09:41:07 »
Yo no iria por el camino que estas intentando, sino realizar las cosas un poco mas correctas... Donde los tiempos no dependan de instrucciones, etc.

- Crear una interrupcion del Timer cada 1s si es que pretendes contar 1s, o si queres cambiar los leds del medio cada 500ms, entonces interrupcion cada 500ms. Es recomendable utilizar el modo CCP en modo Compare para no tenes que recargar el Timer y asi evitar errores de tiempo.

Código: C
  1. void interrupt interrupciones(void) {
  2.  
  3.   if(interrupcionDelTimer1Bit){
  4.     //Recargo si no lo haces con el CCP
  5.     //Cambio el estado de los leds
  6.     addSecond();
  7.     //Desactivo el flag
  8.   }
  9. }

- La funcion de agregar un segundo, es mas simple:

Código: C
  1. void addSecond(void) {
  2.   if(++segundo>59){
  3.     segundo = 0;
  4.     minuto++;
  5.   }
  6.   if(minuto>59){
  7.     minuto = 0;
  8.     hora++;
  9.   }
  10.   if(hora>24){
  11.     hora = 0;
  12.   }
  13. }

- En el main, te dedicas UNICAMENTE a mostrar en el display en el tiempo que vos desees. Obviamente Aca vas a tener que separar las unidades de las decenas con:

decenas = segundos / 10;
unidades = segundos % 10;

- Aqui para agregar el PAUSE/PLAY solo necesitas modificar unicamente el bit de ON del Timer1 en su interrupcion.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Interrupcion Pause/Play
« Respuesta #12 en: 07 de Abril de 2020, 12:33:17 »
Sin duda. Usaría el Timer que además incluso le puede colocar un resonador de 32768 Hz y obtener un reloj muy exacto.

  El código sería mucho mas simple y rápido que el que ha hecho.

  Le propuse la idea del do{} while(); por si no requiere precisión, por ejemplo, si lo quiere para cronometrar algo de corto lapso pues que pudiese aprovechar su código actual.

 Pero si lo que quiere por ejemplo es hacerse por ejemplo un reloj para ponerlo por ahí en su casa o similares trabajando las 24h del día ese código le introducirá un error bestial.

 


Desconectado DavidtXz

  • PIC10
  • *
  • Mensajes: 22
Re:Interrupcion Pause/Play
« Respuesta #13 en: 07 de Abril de 2020, 22:33:07 »
Amigos pues la verdad ya lo intente pero creo que no se utilizar el timer0... esa es una de las razones por lo que no lo  hice asi..

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion Pause/Play
« Respuesta #14 en: 08 de Abril de 2020, 20:41:57 »
Amigos pues la verdad ya lo intente pero creo que no se utilizar el timer0... esa es una de las razones por lo que no lo  hice asi..

Pero que eso no te detenga, busca algun tutorial de COMO FUNCIONA un timer, luego poco a poco nosotros te podemos ayudar, pero si cerras la puerta a conocer tu microcontrolador va a ser un gran problema. Empeza con algo simple...

Intenta que crear una "interrupcion" cada cierto tiempo, y encende un led como para ver que funcione.

PD: Todos comenzamos asi, solo se requiere un poco de esfuerzo.