Problema con interrupciones en PIC Basic

Estoy haciendo un reloj de ajedrez (2 relojes en cuenta regresiva que al accionarse uno este se pone en pausa y el otro continua y viceversa) el problema que tengo es que puedo parar el 1er reloj y hacer que continué el 2do con la función ON INTERRUPT GOTO y el puerto externo B.0 INTCON=%10010000... es posible asignar a otro puerto externo para asignarlo al 2do reloj vi que puedes usar los puertos b4-b7 pero no estoy muy claro.

Espero no confundirles y si es posible que me respondan en lenguaje PBP que es el único que se gracias...

Los 2 relojes estan en un LCD y al primer reloj lo controla un pulsador en el B.0 y el otro (No se como utilizarlo) en el B.1
 
Última edición:
vi que puedes usar los puertos b4-b7 pero no estoy muy claro.
Espero que este ejemplo te aclare como usar las interrupciones externas por cambio de estado en RB4-RB7

Posiblemente puedas usar el código en tu proyecto.

Suerte.
 

Adjuntos

  • 16F628A_RB4-RB7_EXT_INT.rar
    16.7 KB · Visitas: 68
Ya termine mi proyecto las interrupciones funcionan como deben Gracias y la simulacion es 10/10... ahora tengo otro problema al grabarle en el pic16f628 y probarle el circuito no funcionan... pueden revisar mi codigo... los fuses estan bien? no aparece nada en el lcd:

Código:
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 30/11/2012                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
@ __config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF

CMCON=7

TRISB=%10010000  'Se activa los puertos b.7 y b.4 

h1 VAR byte      'Se definen las variables para las horas, minutos y segundos

S1 VAR byte 

M1 VAR byte

h2 VAR byte

S2 VAR byte 

M2 VAR byte

DEFINE LCD_DREG PORTA     'Se definen los puertos A para el uso del LCD

DEFINE LCD_DBIT 0

DEFINE LCD_RSREG PORTA

DEFINE LCD_RSBIT 6

DEFINE LCD_EREG PORTA

DEFINE LCD_EBIT 7

BotonA var PORTB.4        'Se definen los botones de los jugadores
BotonB Var PORTB.7


'------------------------------------------------------------------------
'Programa inicial de bienvenida

INICIO:

LCDOUT $FE,$80, "Chess Clock V1.0"

LCDOUT $FE,$C0, "Press Any Button"
 
if BotonA=0 then    'Si se presiona el Boton A nos vamos al reloj uno y seteamos el segundo reloj
Lcdout $FE,1
LCDout $FE,$C8, DEC2 H2="0", ":", DEC2 M2="0", ":", DEC2 s2="0"
Goto Inicio1 
else 
if botonB=0 then    'Si se presiona el Boton B nos vamos al reloj dos y seteamos el segundo reloj
Lcdout $FE,1
LCDOUT $FE,$80, DEC2 H1="0", ":", DEC2 M1="0", ":", DEC2 s1="0"
goto inicio2
endif    
endif
goto Inicio
end

'--------------------------------------------------------------------------

INICIO1:              'Este es el programa para el reloj uno

s1=s1-1               'Se hace un algoritmo para crear una cuenta regresiva.
if s1>59 then
    s1=59
    m1=m1-1
    if m1>59 then
    m1=59
    h1=h1-1
        if h1>23 then
        h1= 0
        endif
    endif
endif

if s1=0 and m1=0 and h1=0 then  'En esta parte si la cuenta regresiva termina va
goto fin1                       'a otro programa que detiene el reloj
endif
           
LCDOUT $FE,$80, DEC2 H1, ":", DEC2 M1, ":", DEC2 s1  'Se imprime los valores en pantalla
PAUSE 800 

if PORTB.4=0 then resume INICIO2 'Si hay una interrupcion por parte del boton A se detiene
                                 'el proceso actual y se continua con el reloj dos
goto inicio1
end

'--------------------------------------------------------------------------

INICIO2:                   'Este es el programa para el reloj dos

s2=s2-1                    'Se hace un algoritmo para crear una cuenta regresiva
if s2>59 then
    s2=59
    m2=m2-1
    if m2>59 then
    m2=59
    h2=h2-1
        if h2>23 then
        h2=0
        endif
    endif
endif
     
if s2=0 and m2=0 and h2=0 then  'En esta parte si la cuenta regresiva termina va
goto fin2                       'a otro programa que detiene el reloj
endif

LCDOUT $FE,$c8, DEC2 H2, ":", DEC2 M2, ":", DEC2 s2  'Se imprime los valores en pantalla
PAUSE 800
if PORTB.7=0 then resume INICIO1 'Si hay una interrupcion por parte del boton B se detiene
goto Inicio2                     'el proceso actual y se continua con el reloj uno
end

'---------------------------------------------------------------------------
'Fin de los dos relojes setea en cero a los relojes


Fin1:
LCDOUT $FE,$80, DEC2 H1="0", ":", DEC2 M1="0", ":", DEC2 s1="0"
PAUSE 1000
end

Fin2:
LCDOUT $FE,$C8, DEC2 H2="0", ":", DEC2 M2="0", ":", DEC2 s2="0"
PAUSE 1000

end



Esta es la imagen del circuito:
https://www.dropbox.com/s/miavegyjin731zk/Diagrama.jpg
 
Última edición:
¿Qué programa estás usando para compilar?
Lo digo por la forma en que declaras los fuses, ya que tanto MicroCode Studio como MPLAB generarían error.

Si se usa MPLAB se tiene que modificar el archivo 16F628A.INC de la carpeta PBP.
Y si se usa MicroCode Studio, se escriben de otra forma, como en el programa que adjunte anteriormente.

Ahora, tomando eso en cuenta, así como los tienes declarados están bien y no tendrás problemas por ese lado.
Por mera curiosidad grabe un PIC y lo conecte a un LCD modelo JHD 162A, y el programa funciona bien.
Así que debes tener un problema de hardware. Revisa bien tus conexiones.

Una recomendación un tanto importante para ciertos displays, es darles un tiempo antes de iniciar, por ejemplo 500Ms.

Suerte.
 
Mi PC tiene MPLAB para que sea compatible con windows 7... y tengo una maquina virtual con el MicroCode y este tiene el ensanblador por defecto... ya les genere a los dos cambiandole los fuses y al momento de grabarle al pic no hay error pero sigue sin salir nada...



Unas Preguntas?
Solo le pongo un pause de 500 al inicio del programa o donde?
Probaste mi codigo y si te salio en tu lcd? sera posible que me pases el .hex (Para evitar sospechas)

Y por ultimo Gracias!
 
Última edición:
Unas Preguntas?
Solo le pongo un pause de 500 al inicio del programa o donde?
Probaste mi codigo y si te salio en tu lcd? sera posible que me pases el .hex (Para evitar sospechas
El retardo se coloca antes de iniciar la pantalla.
Por ejemplo:
Pause 500
LCDOUT $FE,1 ; Limpia e inicializa la pantalla.
O de esta otra forma...
Pause 500
LCDOUT $FE,1,"Hola Mundo"

Sin embargo a mi me funciono normalmente aún sin agregar el retardo.

Aquí adjunto el proyecto en MPLAB probado físicamente y en simulación.

Nota:
Yo tengo que modificar los archivos PBPMPLAB.BAT y 16F628A.INC para utilizar MPLAB.

Suerte.
 

Adjuntos

  • Chess Clock Funcionando.rar
    51.2 KB · Visitas: 30
Última edición:
Gracias por la respuesta.
Ya le probe... y me sale el mismo resultado: Una linea prendida y la otra oscura... significa algo?

Si ayuda en algo tengo un quemador Pickit2 clone...
 
Posiblemente debe ser algo referente con los fuses que no se están estableciendo como són.
Yo no uso ese programador, utilice el PICSTART Plus.
Aquí en el Foro existen algunos temas que tratan sobre eso, posiblemente te sirvan.
https://www.forosdeelectronica.com/f24/consigo-grabar-pic-57152/
https://www.forosdeelectronica.com/f24/grabar-pic-16f628a-74187/
https://www.forosdeelectronica.com/f24/problema-al-iniciar-oscilador-pic16f628-83158/

Podría haber más temas. Pero prueba compilando un programa sencillo como hacer parpadear un LED,
para que verifiques si está trabajando el oscilador interno.

Suerte.
 
Última edición:
Buenas noches. Una consulta.
T
engo un problema al utilizar la interrupción en proteus, me simula bien pero en la práctica cada vez que suelto el pulsador aún se enciende el led2 (portb.2)
Deseo que no se encienda solo hasta volver a pulsar el Rb0
Agradecería su apoyo.
Código:
cmcon=7
led  var portb.1  ; indicador de funcionamiento
led2 var portb.2 ; salida temporizada

on INTERRUPT GOTO verde
INTCON=%10010000 ; habilita las interrupcion B.0

PROG:
  HIGH LED
  PAUSE 200
  LOW LED
  PAUSE 200
  GOTO PROG      ; mantener en este lazo

DISABLE       ;desabilita las interrupciones en el handler
verde:
  high led2
  pause 500
  low led2

  INTCON=%10010000 ; habilita la interrupcion B.0
  RESUME      ;retorna a programa principal donde ocurrio la inte.
  ENABLE      ;habilita las interrupciones despues del handler
 
  END
 
Tengo un problema al utilizar la interrupción en proteus, me simula bien pero en la práctica cada vez que suelto el pulsador aún se enciende el led2 (portb.2)
Deseo que no se encienda, solo hasta volver a pulsar el Rb0
Agradecería su apoyo.
 
buenas noches gracias por la sugerencia lo hice de esta manera
PROG:
HIGH LED
PAUSE 200
LOW LED
PAUSE 200
GOTO PROG ; mantener en este lazo

verde:
DISABLE
toggle led2
pause 500
low led2
INTCON=%10010000
Resume
ENABLE ;habilita las interrupciones despues del handler

pero cuando suelto el pulsador aun se sigue encendiendo el LED2...
 
Cuando entras en interrupción por cambio de estado (normalmente de b.4 a b7) no verídicas cual de esos pines a cambiado de estado, aparte para que salga de interrupción y no vuelva a entra directamente tienes que borrar el banderín de suceso.
INTCON=%10000000
Pero seria mejor esto.
INTCON.3=0
simplemeste por la razón de que existen muchas interrupciones diferentes y verídicas que sea en caso.
RBIF: RB Port Change Interrupt Flag bit

En tonces lo que arias es:

IF INTCON.3=0 THEN
.....
LO QUE TENGAS QUE HACER
......
INTCON.3=0
ENDIF

y así completas ese tramo de interrupción..

El otro fallo. Creo que son los pauses, ahora estoy en la duda si pause y pauseus detienen no solo el programa y interrupciones o solo lo hace pauses.

Mi consejo es nunca usarlos (usa tmr1 o otro contador) aveces renta hacer una parada, pero mas bien cuando estas texteando un código algo estenso y enrevesado (por saber por donde andas en la pifia que sea) pero eso ya son salidas e improvisaciones para arreglar algo o depurarlo. Después se borran.

Por razones previas de los compiladores y mas en mplap es mas practico definir puertos, variables e interrupciones aparte de librerías (siempre al principio) y con un voto saltas a programa la subrutina de interrupciones va primero.

Un saludo
... Paso de corregir arriba errata mía.. Borras el bit 3 de intcon, pero Enciendes el bit 4 que es el banderín de desborde tmr0 :)
Y sorry. Mi consejo con los banderines.
Pensar en los buzones de correos estos de las películas, pero x buzones comunitarios independientes. Si ves la bandera levantada miras lo que hay bajas la bandera y cierras la tapa ;)
... Bueno si soy un pesado (pero son muchas pifias)
Verde: ???? Y por que no violeta jjjjj

On goto interrupt interrupciones

On goto interrupt verde ..... (Queda mal no)

Se encarga de muchas cosas para llamarlo verde.... Que se lo digas a mas de alguno por aquí... Sí. Puede valer :)
¿Y si usas TOGGLE Pin?
Por ejemplo:
Toggle led2

Toggle es una instrucción muy guapa y practica invertir un bit (o un pin)
Vamos para encender o apagar una luz en casa. En un programa aveces usas el mismo les para distintas indicaciones..
Nos metetiamos en mas de algún momento en la física cuántica, en el integrado no sabrías si esta a 0 o 1, (tener que gastar 5 procesos en una if para saber en que estado esta y si no esta bien ponerlo... es un teorema)
Esta ya si paro... :)
Los banderines no te obligan ir a interrupciones si no los defines tu.. Pero si puedes verificar el banderín y borrarlo en cualquier parte del programa.
 
Última edición:
Gracias Pepibho por tu consejos.
C
onfiguré el registro OPTION(81H) y configuré el bit 6 INTEDG a 0 para habilitar las interrupciones por flanco de bajada y ya a la hora de soltar el pulsador la salida PORTB.2 ya no se enciende.
Q
uedó así de esta manera:
Código:
led  var portb.1  ; indicador de accionamiento
led2 var portb.2 ; salida
OPTION_REG=%00000000
ON INTERRUPT GOTO verde
INTCON=%10010000; habilita las interrupción por RB0

PROG:
  HIGH LED
  PAUSE 200
  LOW LED
  PAUSE 200
GOTO PROG      ; mantener en este lazo

  verde:
  DISABLE
  pause 150
  toggle led2
  pause 500
  low led2
  INTCON=%10010000 ;habilita la interrupción B.0
  Resume       ;retorna a programa principal donde ocurrió la interrupción
  ENABLE      ;habilita las interrupciones después del handler

Gracias por los aportes, muchachos. (y)
 
..... Enserio te has coscado de algo.
Pero sí lo has hecho mal de nuevo.

Cuenta bien los bit....
¿
Y b.0 Dónde?

Sin ánimos de ofender, creo que algo verdes para entender enable disable.
Si debe ponerse en el tramo de interrupciones, pero no es del todo necesario... ¿Por q??
;)
Sorry. B0, porque ahora estás con cambio de flanco.. Ok.
Intcon.1 es la que activa el banderín.
Intcon.4 indica el banderín.

Lo siento, menudas equivocaciones tontas

Intcon.1 ' indicacion, banderín de suceso int
Intcon.4 ' permite que entre en interrupción
 
Atrás
Arriba