TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: Elena2000 en 29 de Junio de 2004, 05:21:00

Título: Interrupciones para el 12F629
Publicado por: Elena2000 en 29 de Junio de 2004, 05:21:00
Hola chicos


Me gustaría pediros que echárais un ojo a este código que he preparado para controlar el parpadeo de una lámpara. Estoy usando el enano capullito 12F629, que está dando una guerra....

Se debe iniciar una secuencia de parpadeo cuando entra un flanco de bajada en la entrada "activar", y se debe interrumpir el parpadeo en cuanto entre un flanco de bajada en la entrada "desactivar".

Yo por más que miro y miro ... no veo nada erróneo...  compila bien... pero no hace nada!
a ver qué opináis los gurús del basic este de marras...
Muchas gracias!!
Codigo:

"****************************************************************
"*  Name    : lampara-flash.BAS                                 *
"*  Author  : Elena                                             *
"*          : All Rights Reserved.... pozzi                     *
"*                                                              *
"*  ENTRADAS: activar y desactivar: señal de radiofrecuencia    *
"*             que entran al PIC por flanco de bajada           *
"*  SALIDA  : señal a un relé para encender o                   *
"*          : apagar la lamparita                               *
"*          :                                                   *
"****************************************************************
    @ DEVICE pic12F629, 0x1FC4 "palabra de configuración: PWRT y BOREN enables
    " Programo el enano este con Osc_Interno,
    " pero con Mclr_externo!! según me ha dicho Sispic,
    @ ID 0x0012
    OPTION_REG = %01111111 "resistencias de pullup
    WPU = %00110011 "despertar resistencias
    TRISIO=%001100 "entradas: GP4 y GP5. Salida: GP2
    CMCON=%00000111 " Deshabilitar Comparatores. No lo uso para nada.
    INTCON = %10001000  "registro de interrupciones
        " 7=GIE, 6=PEIE, 5=TMR0IE, 4=INTE, 3=GPIE, 2=TMR0IF, 1=INTF, 0=GPIF
        " GIE = 1"global interrupt enable
        " INTE = 0"GP2 interrupt enable
        " GPIE = 1"GPIO interrupt enable: interrupción por cambio de estado
        " INTF = 0" Clear GP2 INT Flag
        " GPIF = 0" Clear GPIO INT Flag
     IOC.4 = 1" habilitar interrupción por cambio en GP4
     IOC.5 = 1" habilitar interrupción por cambio en GP5

    " Variables y alias
     GPIF VAR INTCON.0  
     rele VAR GPIO.2
     activar VAR GPIO.5
     desactivar VAR GPIO.4
     mode VAR BIT
     i VAR WORD
     ON INTERRUPT GOTO MyInter


     "rutina de interrupción
     Disable"Deshabilitar Interrupciones mientras ejecuta la rutina
MyInter:
     "Comprobar si la interrupción la causó cambio de estado en GP4 o GP5
    IF GPIF then
     GPIF = 0"borrar flag de interrupción
        if !activar then"cuando lea el puerto, borraré el flag de interrupción
        mode = 1
        gosub activaRele
        endif
        if !desactivar then"cuando lea el puerto, borraré el flag de interrupción
        LOW rele
        endif
    ENDIF
    Resume
    Enable

    "rutina principal
MAIN:
    IF mode THEN
        mode = 0
        " Primer parpadeo
        HIGH rele
        PAUSE 10000
        LOW rele
        " Segundo parpadeo
        FOR i = 1 TO 30
            HIGH rele
            PAUSE 100
            LOW rele
            PAUSE 100
        NEXT i
        " Tercer parpadeo
    loop:
        HIGH rele
        PAUSE 100
        LOW rele
        PAUSE 1100  
        Goto loop
    ENDIF
    GOTO MAIN

activaRele:
    HIGH rele
    return

End




Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 29 de Junio de 2004, 07:21:00
Codigo:

     "rutina de interrupción
     Disable"Deshabilitar Interrupciones mientras ejecuta la rutina
MyInter:
     "Comprobar si la interrupción la causó cambio de estado en GP4 o GP5
    IF GPIF=1 then
        if activar = 1 then"cuando lea el puerto, borraré el flag de interrupción
        mode = 1
        high rele
        endif
        if desactivar = 1 then"cuando lea el puerto, borraré el flag de interrupción
        mode = 0
        LOW rele
        endif
    ENDIF
    GPIF = 0"borrar flag de interrupción
    Resume
    Enable
   
    "rutina principal
MAIN:
    IF mode = 1 THEN
        mode = 0
        " Primer parpadeo
        HIGH rele
        PAUSE 10000
        LOW rele
        pause 100
        " Segundo parpadeo
        FOR i = 1 TO 30
            HIGH rele
            PAUSE 100
            LOW rele
            PAUSE 100
        NEXT i
        " Tercer parpadeo
    loop:
        HIGH rele
        PAUSE 100
        LOW rele
        PAUSE 1100  
        Goto loop
    ENDIF
    GOTO MAIN

End


Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 29 de Junio de 2004, 07:24:00
ahora, solo me queda decir, que el tercer parpadeo, se queda en un buble infinito... vamos eso creo...
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 29 de Junio de 2004, 07:29:00
A ver Abago, bonito, que no tengo la bola mágica bien calibrada esta mañana......

¿qué quieres ddecir con tu respuesta? ¿que te ha gustado mucho esa parte del código y la vas a guardar como recuerdo? o que mi código está mal porque la parte de configuración de PIC hay que pasársela por el forro?...
Más bien creo que se te ha escapado el dedico al botón de añadir respuesta, verdad?

Jejeje... si es que no se puede desayunar cazalla, hombre....
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 29 de Junio de 2004, 07:31:00
AH! JAJA has sido más rápido que yo con esa segunda respuesta.

Pues sí, eso es lo que debe hacer: quedar parpadeando en forma de baliza hasta que le entre un flanco en "desactivar", lo que produciría una interrupción con mode=0 y eso haría apagar la lámpara. Eso es. Esta correcto ese bucle ahí puesto.

Más cositas?
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 29 de Junio de 2004, 07:37:00
Pero por mucho que pongas el flag mode a 0, nunca saldrás del bucle, porque una vez que llegas al tercer parpaceo, ya no vuelves a comparar el flag...

yo lo haría con un

while mode = 0
      HIGH rele
      PAUSE 100
      LOW rele
      PAUSE 1100  
wend
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 29 de Junio de 2004, 07:41:00
Pero a ver.... saldré del bucle en cuento entre una nueva interrupción. En ese caso la ejecución del programa salta a la rutina MyInter. No hace falta chequear la variable mode para salir del bucle, salgo con la interrupción, no?
Título: RE: Interrupciones para el 12F629
Publicado por: Sispic en 29 de Junio de 2004, 15:12:00
He puesto asteriscos en donde parece que hay cosas raras ************** y esta corregido pero no provado

Codigo:

"****************************************************************
"*  Name    : lampara-flash.BAS                                 *
"*  Author  : Elena                                             *
"*          : All Rights Reserved.... pozzi                     *
"*                                                              *
"*  ENTRADAS: activar y desactivar: señal de radiofrecuencia    *
"*             que entran al PIC por flanco de bajada           *
"*  SALIDA  : señal a un relé para encender o                   *
"*          : apagar la lamparita                               *
"*          :                                                   *
"****************************************************************
    @ DEVICE pic12F629, 0x1FC4 "palabra de configuración: PWRT y BOREN enables
    " Programo el enano este con Osc_Interno,
    " pero con Mclr_externo!! según me ha dicho Sispic,
    @ ID 0x0012
    OPTION_REG = %01111111 "resistencias de pullup
    WPU = %00110011 "despertar resistencias
    TRISIO=%001100 "entradas: GP4 y GP5. Salida: GP2
    CMCON=%00000111 " Deshabilitar Comparatores. No lo uso para nada.
    INTCON = %10001000  "registro de interrupciones
        " 7=GIE, 6=PEIE, 5=TMR0IE, 4=INTE, 3=GPIE, 2=TMR0IF, 1=INTF, 0=GPIF
        " GIE = 1"global interrupt enable
        " INTE = 0"GP2 interrupt enable
        " GPIE = 1"GPIO interrupt enable: interrupción por cambio de estado
        " INTF = 0" Clear GP2 INT Flag
        " GPIF = 0" Clear GPIO INT Flag
     IOC.4 = 1" habilitar interrupción por cambio en GP4
     IOC.5 = 1" habilitar interrupción por cambio en GP5

    " Variables y alias
     GPIF VAR INTCON.0
     rele VAR GPIO.2
     activar VAR GPIO.5
     desactivar VAR GPIO.4
     mode VAR BIT
     i VAR WORD
     ON INTERRUPT GOTO MyInter

     mode = 0 ""  *****************
     Goto MAIN ""***************  saltar el hadler de interrupciom es mejor *********************
     
     "rutina de interrupción
     Disable"Deshabilitar Interrupciones mientras ejecuta la rutina
MyInter:
    Disable "********************
     "Comprobar si la interrupción la causó cambio de estado en GP4 o GP5
                      " ************  IF GPIF then - esto no funciona bien con pbp , no se por que usa  IF GPIF=1 then
    IF GPIF = 1 then  " ************  es absurdo comprovar la causa si solo ella esta activada ,, pero no pasa nada
     GPIF = 0"borrar flag de interrupción
        if activar = 0 then"   if activar ******** cuando lea el puerto, borraré el flag de interrupción
        mode = 1
        gosub activaRele
        endif
        if desactivar = 0 then" if desactivar  ****** cuando lea el puerto, borraré el flag de interrupción
        LOW rele
        endif
    ENDIF
    Resume
    Enable

    "rutina principal
MAIN:
    IF mode = 1 THEN   " ************
        mode = 0
        " Primer parpadeo
        HIGH rele
        PAUSE 10000
        LOW rele
        " Segundo parpadeo
        FOR i = 1 TO 30
            HIGH rele
            PAUSE 100
            LOW rele
            PAUSE 100
        NEXT i
        " Tercer parpadeo
    loop:                 """ *** Abago tiene razon con lo que dice , de aqui no saldras nunca
        HIGH rele         """ solo cuando atienda a la interrupcion , pero regresa otra vez al encontrar RESUME
        PAUSE 100
        LOW rele
        PAUSE 1100
        if mode = 0 then Goto loop    """ ******** sales asi por ejemplo
    ENDIF
    GOTO MAIN

activaRele:
    HIGH rele
    return

End


tu sistema de salir del loop no funcionara por que al poner al final de la llamada de interrupcion RESUME es como añadir retfie.

Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 29 de Junio de 2004, 17:02:00
La interrupción solo cambia el estado del flag, pero hay que hacer una comparación para salir del buble...
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 30 de Junio de 2004, 03:08:00
Vale chicos, Muuuuuuuuuuuuchas gracias a los dos!!!!!!
A ver, recopiando:

* Inicializar la variable mode. Vale.... esto se me pasó...
* Saltar el jandeler de interrupciones al comenzar. Pozzi, también se me pasó.
* Poner el disable interrupciones justo a la entrada de la rutina de interrupción. De acuerdo. Aunque a veces
he leído que hay que colocarlo antes...
* Comprobar el estado de "mode" para poder salir del bucle infinito ese.. muy bien: hacer más caso a Abago.

Bueno, esta tarde los pruebo y ya os cuento a ver.
GRACIAS!!!!!!!!!!!!!!!!!!!
Elena
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 30 de Junio de 2004, 04:14:00
a ver si te pasas a tomar el bloody mary y nos lo curramos en un periquete....

Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 30 de Junio de 2004, 04:26:00
AH! gracias, bonito.
Cualquier día te aviso y voy a pasar el modelito a t passarela,
Espero que no hagas los bloody mary"s muy bien, porque me encantan.... y corro el riesgo de entrar en un bucle infinito...
loop:
       HIGH bloody-mary
       if borrachuza=0 then
       goto loop
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 30 de Junio de 2004, 04:58:00
while ((borrachuza = 0) and (bareto_abierto = 1))
 HIGH Bloody_Mary
wend

Yo sigo en mis trece... con el while o el loop until...
Se nota que usas el ensamblador.... y lo digo por lo de los gotos....

Ah!!!, por cierto, ya tenemos primer visitante del foro al garito..
RGL...
Podíamos nombrar Passarela... Punto de encuentro de FOREROS ALCOHOLICOS....
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 30 de Junio de 2004, 05:08:00
Si, jejeje, no puedo evitar los gotossssss. Si te digo la verdad, esta chorrada de programa la hice
en ensamblador en un periquete, y funcionó que-te-cagas, (la hice para un 16f84, pero es similar).
De momento el basic me torea, ya ves, pero en fin... a ver si con más práctica domino los whiles como tú.

Anda! así que me han ganado por la mano! estuvo Ricky por ahí?! pues nada, genial, cualquier día caigo yo, ya sabes. Prepara el bloody.
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 30 de Junio de 2004, 05:16:00
A ver si liamos tambien a marques, y montamos una tertulia sobre electrónica....
Que la verdad ya estoy harto de hablar de mis proyectos a gente que me pone cara de pez...
Y la verdad es que no se si es por el pedo que llevan, o porque no entienden nada de lo que les estoy contando...
Título: RE: Interrupciones para el 12F629
Publicado por: Sispic en 01 de Julio de 2004, 00:45:00
Vaya algoridmos mas refrecantes que estais preparando , me gusta , lo bueno que tiene es que acabareis todos hablando el mismo idioma de programacion , entendiendoos perfectamente .....

Que rabia que tu local esté tan lejos de mi casa

Bueno Elena he visto que este sistema que usas para atender la interrupción , PBP escribe un codigo nada ortodoxo , es decir que por ejemplo si usas un "pause 1000" no saltara a ella hasta que termine con el pause , esto se comentó en un post por aquí cerca , Abago saves donde está ??.


Por ejemplo y como el tiempo no es importante que sea preciso para los pauses lo haces así y como maximo atendreá la interrupcion pasado un milisegundo .

Segundos = 1000 : gosub pausa

pausa:
for Segundos = Segundos to 0 step-1
     for ms=0 to 1000  "* 1 segundo*
          pause 1
          if mode=1 then return
next ms

next Segundos


Como tu aplicacion es muy simple , lo puedes hacer todo sin usar interrupciones ó tambien usando Define  INTHAND que es mas correcto .

Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 01 de Julio de 2004, 02:25:00
Hola chicos,



No funciona nada. Ayer probé el código con las modificaciones que me comentásteis, y nada. No hace nada el maldito pic. No entran las interrupciones, y no se por qué...


No me da guerra el pause, todavía... , lo que ocurre es que sencillamente el pic no se entera de la interrupción. Capullo.

En fin, como muy bien dice Sispic, es una chorrada de programa, y la verdad es que ya lo tengo hecho en ensamblador para el 16f84. Voy a intentar adaptar el codigo asm para el 12f, y espero que logre algo.
De todas formas, me da rabia...... porque es una chorrada y no entiendo porqué en basic no me sale esta idiotez. Voy a probar lo que me dices, Sisco, y también voy a rehacer el programa pero sin utilizar interrupciones, a ver qué tal se comporta la activación/desactivación.

Ya os contaré.
Millones de gracias, resalaos.
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 01 de Julio de 2004, 08:53:00
Sisco, no se si te refieres al link en el que tratamos las mil posibilidades y fallos que me dieron a mi las interrupciones...
está en el subforo de pbp...
y se titulaba Manejo de interrupciones HELP!!!....

http://miarroba.com/foros/ver.php?temaid=1079915&foroid=8826

La verdad, es que hay se puede aprender algo...

ELENA!!! no te desesperes....
Una cosita... porque no manejas las interrupciones en ASM dentro del programa PBP ????.... Yo lo hago así, y funciona muy bien...
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 02 de Julio de 2004, 02:41:00
SOCORROOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!


Verás Sisco, es que no es muy correcto hacer el código con whiles y bucles for, porque tengo que meter chequeos a las entradas cada dos por tres, me tengo que asegurar que mientras la lámpara está en una secuencia de parpadeo, si entra un flanco en las entradas, va a salir INMEDIATAMENTE de la secuencia, sabes? y no va a tener que esperar a terminar el ciclo para comprobar la entrada... Además, los flancos de la entrada duran muy poquito, igual cuando vaya a comprobar la entrada, ya ha pasado el flanco... Es una lata.

Es que no lo consigo.... el pic no se entera, el capullo...
Bueno, no me desespero, vale. Abago, voy a hacer un tiento a eso que me dices, vale. ¿Me ayudás, bonito? voy a modificar el programa y te lo pongo aquí, a ver qué opináis, vale?

Gracias nenes. seguiré sonriendo...


Título: RE: Interrupciones para el 12F629
Publicado por: Sispic en 03 de Julio de 2004, 00:32:00
Si seguramente no se activa la interrupción. (ni idea)

una forma sin usarlas puede ser asi
Codigo:

    @ DEVICE pic12F629, 0x1FC4 "palabra de configuración: PWRT y BOREN enables
    @ ID 0x0012
    OPTION_REG = %01111111 "resistencias de pullup
    WPU = %00110011 "despertar resistencias
    TRISIO=%001100 "entradas: GP4 y GP5. Salida: GP2
    CMCON=%00000111 " Deshabilitar Comparatores. No lo uso para nada.


     Activa  con 2 : Desactiva con 1 : NoPulsados con 3

     Ms var word
     Pulsadores var byte  : pulsadores = NoPulsados
     rele VAR GPIO.2      : low rele
     Mode var bit         : Mode = 0
     I var byte

Main:

        if Pulsadores = Activa then
           mode = 1
           gosub activaRele
        endif else
        if Pulsadores = Desactiva then
           LOW rele
        endif


    "rutina principal
MImain:

    IF mode = 1 THEN   " ************
        mode = 0
        " Primer parpadeo
        HIGH rele                " mas rapido rele = 1
        Ms = 10000 : gosub Pausa
        LOW rele                 " mas rapido rele = 0
        " Segundo parpadeo
        FOR i = 1 TO 30
            HIGH rele
            Ms = 100 : gosub Pausa
            LOW rele
            Ms = 100 : gosub Pausa
        NEXT i
        " Tercer parpadeo
    loop:
        HIGH rele
        Ms = 100 : gosub Pausa
        LOW rele
        Ms = 1100 : gosub Pausa
    ENDIF
   
GOTO MAIN

activaRele:
   HIGH rele
return
   
pausa:
for Ms=Ms to 0 step-1
      Pulsadores = (GPIO  >> 4 )& %00000011
      if Pulsadores <> Nopulsados then Main    " si se ha pulsado alguno ,,, regresa al main
      pause 1                                  " hacemos pausas de 1 ms para ir verificando los pulsadores
next ms
return

End




Título: RE: Interrupciones para el 12F629
Publicado por: Sispic en 03 de Julio de 2004, 00:47:00
por cierto el TRISIO no tendria que estar así ?

TRISIO=%111011 "entradas: GP4 y GP5. Salida: GP2

suerte .
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 03 de Julio de 2004, 23:28:00
Escrito originalmente por Sispic
PBP escribe un codigo nada ortodoxo , es decir que por ejemplo si usas un "pause 1000" no saltara a ella hasta que termine con el pause


sisco... a que te refieres con lo anterior??
a que el pause bloquea la recepción de la interrupción?
o a que si se utiliza la interrupción del modo que la codifica PBP, ocurre esa desgracia....
La verdad es que yo las interrupciones las manejo en asm, dentro del programa PBP...
y en principio parece que funciona bien!!! pero ya me has dejado con la duda..
Título: RE: Interrupciones para el 12F629
Publicado por: Sispic en 03 de Julio de 2004, 23:59:00
Si es así pero solo con el metodo "ON INTERRUPT GOTO MyInter"

No se bloquea la interrupción , digamos que pbp guarda los parametros cuando se produce y hasta que el pause no termina no saltara a tu rutina Myinter . (tambien con serin.... etc.)

Otra cosa es Define  INTHAND MyInter que atendera de manera normal .
Título: RE: Interrupciones para el 12F629
Publicado por: Abago en 04 de Julio de 2004, 09:10:00
AH!!! OK, vamos que solo pasa eso usando el ON INTERRUPT...
por suerte, he utilizado el DEFINE INTHAND myint

Tnks
Título: RE: Interrupciones para el 12F629
Publicado por: Elena2000 en 05 de Julio de 2004, 02:38:00
Hola chicos!

Qué trabajosos habéis estado el finde,

Os pongo a continuación mi versión del programita sin interrupciones, y funciona bien. Lo único que he visto al probarlo con el hadrware, es que se cuelan ruidos y activan el relé cuando no debe, así que voy a meter una validación de las entradas por software. Y otra cosa, a veces no se activan las resistencias de pull-up. ??

Bueno, este es el código:
Codigo:

    @ DEVICE pic12F629, 0x1FC4 "palabra de configuración PWRT y BOREN enables
     asm
     ID 0x0012
     endasm
     TRISIO = %00111011
     OPTION_REG = %01111111 "resistencias de pullup
     WPU = %00110011

    rele VAR GPIO.2           "pin 5 del micro
    activar VAR GPIO.4      "pin 3 del micro
    desactivar VAR GPIO.5   "pin 2 del micro
    i VAR WORD  " para los bucles

    PAUSE 200
   
" el circuito está vivo?
    high rele
    pause 1000
       
" Esperamos a que entre un cero en activar
main:
    while activar
    low rele
    WEND
       
" parpadeo
    " Iniciamos la secuencia de parpadeo con un encendido prolongado de 3 segundos
   
        for i=1 to 30
            HIGH rele
            if !desactivar then
                goto main
            ENDIF
            PAUSE 100
            next i
    " Iniciamos una secuencia de parpadeos rápidos durante 2 segundos
        FOR i = 1 TO 20
            HIGH rele
            pause 50
            LOW rele
            PAUSE 50
            if !desactivar then
                goto main
            ENDIF
        NEXT i
    " Iniciamos una secuencia de parpadeos a modo de baliza
loop:
        HIGH rele
        PAUSE 100
        LOW rele
        FOR i = 1 to 90
        PAUSE 10  
        if !desactivar then
              goto main
        ENDIF
        NEXT i
        if desactivar then    
            Goto loop
            else
            goto main
        ENDIF
   
END



Voy a probar el tuyo, Sisco, graciassssssss!
 Si me animo a intentar las interrupciones, ya os diré, pero de momento voy aver si termino la dichosa lamparita, que me llegan las vacaciones y tengo todo manga por hombro y sin terminar.