# Interrupciones PROTON



## xiober (Mar 21, 2007)

Soy nuevo en esto de los microcontroladores, queria saber por que esto no funciona, es casi igual a los ejemplos que estan en la red, el codigo esta escrito en PROTON PLUS.

INICIO:
    trisa = %11111111   ' PuertoA Como Entrada
    INTCON = %00001000  'Activacion de la Interrupcion por cambio
                        'del puerto B

on interrupt goto In'Iniciamos la interrupcion

 INFINITO:               'Bucle o ciclo infinito
    goto INFINITO 

 In:
    toggle portc.2       'Cambiamos el estado del  pin
    return


----------



## Jairo (Mar 24, 2007)

Hola

para solucionar tu problema prueba lo siguiente
cambia lo siguiente

INTCON = %1o001000 'con eso activas las interrupciones en general 

ademas pon un retardo en alguna parte dentro del principal, y ademas borra la bandera y desactiva la interrupcion cuando ingresas a la misma, y dentro de esta has un pequeño retardo y comproueba que se activo la bandera deseada para luedo hacer lo que deseas dentro de la interrupcion

disable; con esto deshabilitas la int mientras realiza
In: 
toggle portc.2 'Cambiamos el estado del pin 
return 
enable ;habilitas la interrupcion de nuevo

Cualquier duda no hay problema en que me preguntes
Saludos Jairo


----------



## Fer_TACA (Oct 3, 2008)

Hola amigo Jairo:

Espero no molestarte, he leido tu respuesta a un compañero respecto a al funcionamiento de la interupcion en proton y veras hace poco empeze con el basic y me llego el momento de llegar al funcionamiento de las insterrupciones.
El caso es que quiero implementar una por cambio de estado de los pines rb4 a 7 y mi problema es que no siempre se entra en la interrupcion y que cuando se entra la repite 6 o 7 veces hasta que sale y vuelta a empezar.
La verdad es que llevo un par de dias y no consigo ver que estoy realizando mal. Adjunto el codigo por si me pudes dar un emujoncito.
Gracias de antemano

Codigo:

    Symbol Compresor = PORTB.1                        'Señal de compresor activo en RB1
    Symbol Cambio = PORTB.0                           'Señal de cambio de secado en RB0
    Symbol Ev_Secado = PORTA.0                        'Electroválvula de secado en RA0
    Symbol Averia = PORTA.1                           'Señal de averia en RA1
    Symbol T_ciclo = 100                              'Tiempo de marcha/paro del secado
    Symbol RBIF = INTCON.0                            'flag de interrupción en RB4 a RB7  

'***************************** SECCIÓN DE INICIALIZACIONES *******************************
    ALL_DIGITAL = True                                'Todos los pines son digitales
    TRISA = %00000000                                 'Puerto A como salida
    TRISB = %11111111                                 'Puerto B como entrada
    PORTA = 0
    Conta1sg = 0
    Ev_Secado = 0
    Averia = 0
    INTCON = %10001000                                'Se activa interrupción de RB4 a RB7
'********************************* PROGRAMA PRINCIPAL ************************************

    On Interrupt GoTo In_Averia

Main:

Mi programa

' Si no pongo la interuppcion funciona perfectamente.

goto main


'************************************ SUBRUTINAS *****************************************
        Disable
In_Averia:
        Averia = 1
        DelayMS 5000
        Averia = 0
        DelayMS 1000
        RBIF = 0
        Resume
        Enable

'*********************************** FIN DEL PROGRAMA ************************************

End


----------



## Jairo (Oct 4, 2008)

Hola Fer_TACA

No es molestia y si te puedo ayudar encantado, estuve revisando tu programa y prueba con revisar la bandera de interrupcion RBIF antes de hacer todo lo que deseas en la interrupcion, es decir chequea si subio, y si realmente subio manda a hacer lo que quieras, caso contrario, manda a que salga de la interrupicon sin hacer nada, algo parecido a lo que te pongo abajo

Disable
In_Averia: 
'*****Aqui chequea si se activo la bandera *****
' *****si si manda a la interrupcion
if rbif=0 then fin_int
    Averia = 1 
    DelayMS 5000 
    Averia = 0 
    DelayMS 1000 
fin_int:
    RBIF = 0 
    Resume 
Enable

Espero que te sirva, ademas pon un pequeño retardo en en el programa priciàl puede  ser 10 mseg, me cuentas si te ayude o que problema tienes

saludos, Jairo


----------



## Fer_TACA (Oct 4, 2008)

Gracias por la respuesta amigo Jairo:

creo que no me expresé muy bien la vez anterior. El problema reside es que cuando se produce la interrupción se produce siempre la ejecuta, se activa su bandera RBIF, tanto lo que yo escribo como lo que me indicas tu.
Pero cuando llega a la instruccion de borrar la bandera RBIF no se borra, se sale de la interrupcion y vuelve a entrar otra vez y asi repetidas veces(6-7) hasta que en una de ellas s se borra la bandera (RBIF=0).
Despues al producirse otro flanco en RB4 se vuelve a entrar en la interrupcion y se repite el ciclo descrito anterior.

La verdad es que me trae un poco loco, pues ya no se que está pasando y el caso es que llevo varios dias ya con ello.
Otra cosa no se si usaras Proton, pero el caso es que no se si se puede poner un break point cuando se hace un debug con Proteus. El boton de altivarlas no se encuenta activado  y me gustaria poner uno para ver en donde se cuelga.
En fin un saludo
Fermin


----------



## Jairo (Oct 4, 2008)

hola Fermin

Tengo una pregunta como es el hardarwe que estas utilizando para las interrupcione , es decir, que tienes conectado en el puerto b, como lo tienes conectado, talvez puede ser un problema de rebotes, es decir hay varios cambios de flanco en el mismo instante y por eso se queda las interrupciones en espera, por eso cuando salen vuelven a ingresar.
Sobre proton no he utilizado, ademas en proteus yo puedo poner break points pero cuando el programa sea en assembler, con basic  no he podido ver directamente el programa en proteus para ir paso a paso

SAludos Jairo


----------



## Fer_TACA (Oct 4, 2008)

Hola de nuevo:

El hardware que tengo es con las puertas del puerto B con unas resistencias uno de cuyos extremos está conectado a GND y el otro va a ir conectado a las salidas de unos optoacopladores.
La verdad es que todavia no he pasado el programa al micro pues primero me gusta simularlo y encontrar errores graves antes de pasarlo al micro.
Por eso me extraña ya que al ser una simulacion software(Proteus) no deberian de producirse esos rebotes, de hecho lo hace aunque vayas ejecutando el programa paso a paso, de ahi mi extrañeza.

Referente a los break point por eso lo preguntaba ya que en ensamblador si que puedo y con Basic no y pensaba que hacia algo mal.

Si para el lunes no tengo comprobado el programa( de manera simulada al menos y funcionando) tendré que dado el plazo de entrega del equipo tendré que ir buscando otra solucion
Si necesitas alguna información adicional puedes pedirmela.

Fermin


----------



## Jairo (Oct 5, 2008)

hola que tal..
si estas solo simulando de ley es software, pero si no entiendo mal me dices que te da rebotes aun cuando simulas, eso esta aun mas raro, no creo que te de rebotes solo simulando, chequea la bandera como te dije, y para borrar la bandera borrala dos veces a ver que sucede, ademas te recuerdo que las interrupciones por portb 4 a 7 son por estado y no for flanco, asi que cualquier cambio de estado que suceda en esos pienes te llevara a la interrupcion, no importa si es de uno a cero o de cero a uno, chequea bien eso.

cuentame que tal te fue
SAludos Jairo


----------



## Fer_TACA (Oct 6, 2008)

Hola:

Creo que me sigo expresando mal.

De momento solo estoy simulando con proteus. Lo de los rebotes, no es que sean rebotes pero es lo que parece pues la interrupcion se repite un numero indeterminado de veces aunque soo se haa cambiado una vez la señal en RB4.

He simulado paso a paso el ejemplo del help de proton y lo mas curioso es que no hace cas a la instruccion:

INTCON.0= 0 que es la que borra el flag y me parece que por eso se repite la interrupcion de forma indeterminada un numero de veces. Se queda siempre como INTCO.0 =1.

¿Por que será?
fermin


----------



## atricio (Sep 18, 2009)

hola amigos muy interesante el tema pero me he dado cuenta que todabia ando sin piso en esto de programar en basic he estado aprendiendo un poco en micro code studio miro que proton es algo parecido pero alguie me puede dar un poco de información sobre proton como ejemplos basicos etc etc para poder entender mas esto de programar en proton ya que me han dicho que es uno de los mejores por el momento muchas gracias por la ayuda


----------



## hitman_zam (Nov 23, 2009)

hola a todos, de antemano muchas gracias por estar prestos a resolver las dudas de la comunidad y de verdad q me ha ayudado mucho este foro; aprobecho este foro sobre interrupciones en proton para ver si me pueden ayudfar con un problema de interrupciones q me esta rompiendo la cabeza; el programa q estoy trabajando consiste en controlar 3 servomotores por el puerto serial para lo cual utilizo la intruccion hserin la cual captura un valor el cual me indica 1 el numero del servo y 2 los grados; el programa funciona bien hasta q supe q los servos se deben mantener siempre con el numero q se quiere a la salida (0 a 3000) para lo cual la unica opcion q tengo es una interrupcion pero la verdad no tengo la menor idea de como usarlas a continuacion agrego el programa y les pido por favor me ayuden no se si alguien me pogria indicar con un poco de plastilina q comandos debo y como usarlos y q debo activar al inicio del programa para para q la interrupcion se active cuando detecte el cambio en el puerto serial. Muchas gracias por su tiempo y de verdad les agadesco la ayuda


```
DEVICE 16F876A 
XTAL4 

OPTION_REG = %00000111
INTCON = %11000000
PIE1=%00100000 

SERIAL_BAUD = 2400 
RSOUT_PIN = PORTC.6
RSOUT_MODE = TRUE
RSOUT_PACE = 1
RSIN_PIN = PORTC.7
RSIN_MODE = TRUE


HSERIAL_BAUD = 2400 
HSERIAL_RCSTA = %10010000 
HSERIAL_TXSTA = %00100100 
HSERIAL_CLEAR = ON 

Declare LCD_TYPE = 0.
Declare LCD_DTPINPORTB.4
Declare LCD_ENPINPORTB.2 
Declare LCD_RSPINPORTB.3
Declare LCD_INTERFACE = 4
Declare LCD_LINES = 2 

DEFINE HSER_RCSTA 90h 

TRISA = 0 
PORTA = 0 

DIM Posicion_1 as WORD
DIM Posicion_2 as WORD
DIM Posicion_3 as WORD
DIM SELECTOR AS BYTE
DIM IN_SERVO AS BYTE
DIM N AS BYTE
DIM N1 AS BYTE
DIM GRADOS AS BYTE
DIM ANGULO AS BYTE
DIM GIROS AS BYTE

SYMBOL Pin_1 = PORTA.0 
SYMBOL Pin_2 = PORTA.1
SYMBOL Pin_3 = PORTA.3


POSICION_1 = 0
POSICION_2 = 0
POSICION_3 = 0

IN_SERVO = 0
GRADOS = 0
ANGULO = 0
GIROS= 0

ON INTERRUPT GOTO INTER

INICIO:

SERVO PIN_1 , POSICION_1
SERVO PIN_2 , POSICION_2
SERVO PIN_3 , POSICION_3
ENABLE
GOTO INICIO

INTER:

HSERIN [DEC SELECTOR]
CLS
PRINT AT 1,1,"SERVO N.", AT 1,9, DEC SELECTOR
IF SELECTOR = 1 THEN GOTO INICIO_1
IF SELECTOR = 2 THEN GOTO INICIO_2
IF SELECTOR = 3 THEN GOTO INICIO_3


inicio_1:

HSERIN [DEC GRADOS]
CLS
PRINT AT 1,1,"GRADOS SERVO N.1", AT 2,6, DEC GRADOS

IF GRADOS > ANGULO THEN 
GIROS = GRADOS - ANGULO
FOR N = 0 TO GIROS 
Posicion_1 = Posicion_1 + 16
SERVO Pin_1 , Posicion_1
DELAYMS 50
NEXT
ENDIF

IF GRADOS < ANGULO THEN 
GIROS = ANGULO - GRADOS
FOR N = 0 TO GIROS 
Posicion_1 = Posicion_1 - 10
SERVO Pin_1 , Posicion_1
DELAYMS 50
NEXT
ENDIF

IF GRADOS = ANGULO THEN GIROS = GRADOS
DISABLE

GOTO inicio_1

inicio_2:

HSERIN [DEC GRADOS]
CLS
PRINT AT 1,1,"GRADOS SERVO N.2", AT 2,6, DEC GRADOS
IF GRADOS > ANGULO THEN 
GIROS = GRADOS - ANGULO
FOR N = 0 TO GIROS 
Posicion_2 = Posicion_2 + 16
SERVO Pin_2 , Posicion_2
DELAYMS 50
NEXT
ENDIF

IF GRADOS < ANGULO THEN 
GIROS = ANGULO - GRADOS
FOR N = 0 TO GIROS 
Posicion_2 = Posicion_2 - 10
SERVO Pin_2 , Posicion_2
DELAYMS 50
NEXT
ENDIF

IF GRADOS = ANGULO THEN GIROS = GRADOS
DISABLE

GOTO inicio_2 

inicio_3:

HSERIN [DEC GRADOS]
CLS
PRINT AT 1,1,"GRADOS SERVO N.3", AT 2,6, DEC GRADOS
IF GRADOS > ANGULO THEN 
GIROS = GRADOS - ANGULO
FOR N = 0 TO GIROS 
Posicion_3 = Posicion_3 + 16
SERVO Pin_3 , Posicion_3
DELAYMS 50
NEXT
ENDIF

IF GRADOS < ANGULO THEN 
GIROS = ANGULO - GRADOS
FOR N = 0 TO GIROS 
Posicion_3 = Posicion_3 - 10
SERVO Pin_3 , Posicion_3
DELAYMS 50
NEXT
ENDIF

IF GRADOS = ANGULO THEN GIROS = GRADOS
DISABLE

GOTO inicio_3
```
 
se que deben haber errores garrafales en lo q se refiere a las interrupciones y les pido disculpas y de nuevo gracias por su tiempo y ojala me puedan ayudar


----------



## mendek (Dic 27, 2012)

Que tal foro, una vez mas programando los microcontroladores me tope con un dolor de cabeza y el punto es que intenté probar el siguiente programa en un pic 16f84a y todo bien, el problema surge cuando lo meto a un pic 16f887 no jala mas que la parte del "PROG"

```
Device = 16F887
Xtal = 4

 Symbol LED= PORTB.1
 Symbol LED2=PORTB.2
 INTCON=%00011000
 On Interrupt GoTo interrupcion ;  En caso de interrupción ir a subrutina interrupción
 INTCON=%10010000               ; el bit 7 habilita las interrupciones en general
                                ;  El bit 4 habilita la  interrupción B.0
 
 PROG:
  High LED
  DelayMS 200
  Low LED
  DelayMS 200
  GoTo PROG
  
  Disable                       ; Desabilita las interrupciones en el handler
  
  interrupcion:              
  High LED2
  DelayMS 2000
  Low LED2
  INTCON=%10010000              ; Habilita la interrupción B.0 (INTCON.1=0)
  Resume                        ; Retorna al programa donde ocurrió la interrupción 
  Enable                        ; Habilita las interrupciones después del handler
  End
```



ya busque para ver si eran las palabras de configuración pero nada, por ahí me dijeron que probablemente serian los registros pero no he encontrado mucho, espero me puedan hechar la mano que ya no se mas donde buscar, desde ya muchas gracias.


----------



## ricbevi (Dic 27, 2012)

Hola...Empieza por descargar y leer la hoja de datos desde acá  http://ww1.microchip.com/downloads/en/devicedoc/41291f.pdf que es el fabricante.
Ese micro controlador tiene en el puerto B también entradas analógicas así que habra que avisarle en algun registro que lo usaras de forma digital para que actué el pin como entrada de la interrupción.
Saludos.

Ric.


----------



## mendek (Dic 27, 2012)

bueno leyendo el datasheet vi que se trata (según yo) del registro IOCB, pero no estoy muy seguro de como modificarlo y lo que hice fue poner IOCB=%00000001, espero me puedan sacar de la duda, gracias.

PROBLEMA RESUELTO

para los que lleguen a tener mi problema, sepan que lo que hice fue poner IOCB.0=1 y problema arreglado, ya pueden disponer de la interrupciones con el PIC16F887, que al final es lo mismo que IOCB=%00000001, solo que me equivoque al ponerlo en proton.


----------



## dietalia (Nov 3, 2013)

Hola Jairo.
      No se si estarás aún en activo en este foro, ya que la entrada es antigua, pero leído la explicación que le das a un compañero con respecto a las interrupciones y me queda una duda: La palabra "disable" esta antes que la etiqueta in: que es donde (creo) que va cuando se produce una interrupción, por lo que entiendo que no pasa por esa linea, luego no inabilita las interrupciones. Lo mismo ocurre con el return, la palabra enable está detrás del return, por lo que tampoco habilitaría las interrupciones al no pasar por esa linea. 

                Espero que me perdones por haber "interceptado" la conversación, pero hace tiempo que tengo esa duda y espero que puedas disiparmela. 

                          Saludos y gracias.






Jairo dijo:


> Hola
> 
> para solucionar tu problema prueba lo siguiente
> cambia lo siguiente
> ...


----------



## D@rkbytes (Nov 3, 2013)

La última intervención de Jairo en el Foro fue en 01/09/2011, posiblemente no te responda.
Y lo más seguro es que se haya equivocado al escribir ese fragmento de código.

Debe de esta forma...
*Disable *' Deshabilita interrupciones en el controlador.
My_Int:
' Código durante interrupción.
*Resume*        ' Regresa al programa principal.
*Enable*        ' Habilita interrupciones después del controlador.

Saludos.


----------



## Piccolo (Ene 26, 2014)

Buenas. Tengo problemas con las interrupciones de proton ide simuladas en isis.
A ver si alguno de ustedes cráneos me tira un mano..
Les explico, después de que mi programa recibe un interrupción de Usart automáticamente pone a 0 el INTCON.7 y después no hay manera de pasarlo de nuevo a 1

Les dejo el código fuente.

```
Device 16F873A
Xtal 20


 
 
        Hserial_Baud    = 9600                 ' Baudios que se trasmiten
        Hserial_Clear   = On
        Hserial_SPBRG   =32                    '129
        Rsin_Timeout    =200
        On_Hardware_Interrupt GoTo Inter
  
 'Serial Conf
        RCSTA.7=1                           'RCSTA.SPEN
        RCSTA.4=1                           'RCSTA.CREN
      
        
        TXSTA.7=1                           'TXSTA.CSRC     0
        TXSTA.5=1                           'TXSTA.TXEN
        TXSTA.4=0                           'TXSTA.SYNC     0
        TXSTA.2=0                           'TXSTA.BRGH      
        
' Int_Con configuracion interrupciones
        INTCON.7=1
        INTCON.6=1
        INTCON.0=0
' 'Option Reg 
        OPTION_REG.7 =1 
'Pie                      
        PIE1.6=1                            'Habilitacion interrupcion Adin
        PIE1.5=1                            'Habilitacion interrupcion RC
' Symbols
        Symbol RX_int = PIR1.5              'Bandera de interrupcci
       Symbol IntGie = OPTION_REG.7
       
'Varianles Comunicacin 
        Dim Codigo          As Byte         'Valor de Codigo
        Dim Pocicion        As Byte         'Valor de Pocicion 
        Dim Dato            As Byte         'Valor de Dato  
        

GoTo Inicio        
Disable
Inter:

    If  RX_int =1 Then
        High PORTB.2
        GoSub Rx_in
    End If
    Resume
    Enable

Return

Rx_in:
    HRSIn {200,Rx_out},Dec Codigo, Dec Pocicion , Dec Dato  
    Rx_out: 
    RX_int  = 0   
    'IntGie  = 1       
Return

Inicio:
    While 1=1
    Wend
Return
```


----------



## D@rkbytes (Ene 26, 2014)

Piccolo dijo:


> Les explico, después de que mi programa recibe un interrupción de Usart automáticamente pone a 0 el INTCON.7 y después no hay manera de pasarlo de nuevo a 1


Prueba así con estos cambios:

```
Device 16F873A
Xtal 20
 
; Configuración USART: (9600bps @ 20MHz. 9615bps Reales 0.16% Error.)
SPBRG =    $81    ; 10000001
TXSTA =    $24    ; 00100100
RCSTA =    $90    ; 10010000

On_Hardware_Interrupt GoTo Inter
        
' Int_Con configuracion interrupciones
INTCON = %11000000

'Pie                      
PIE1.6=1                            'Habilitacion interrupcion Adin
PIE1.5=1                            'Habilitacion interrupcion RC
' Symbols
Symbol RX_int = PIR1.5              'Bandera de interrupcci
;Symbol IntGie = OPTION_REG.7
       
'Varianles Comunicacin 
Dim Codigo          As Byte         'Valor de Codigo
Dim Posicion        As Byte         'Valor de Pocicion 
Dim Dato            As Byte         'Valor de Dato  
        

    Clear
        
    GoTo Inicio        
;Disable
Inter:
    Context Save
    If  RX_int =1 Then
        High PORTB.2
        GoSub Rx_in
    End If
    Context Restore
;    Enable

;Return

Rx_in:
    HRSIn {200,Rx_out}, Codigo, Posicion , Dato  
    Rx_out:
;    RX_int  = 0  
    HRSOut Dec3 Codigo, "-", Dec3 Posicion, "-", Dec3 Dato, 13,10  
    'IntGie  = 1       
Return

Inicio:
    While 1=1

    Wend
    
    End
;Return
```
Nota que cuando se usa *On_Hardware_Interrupt* se debe usar *Context Save *y *Context Restore

*Suerte.


----------



## Piccolo (Ene 26, 2014)

Sr. Muchisimas gracias !!


----------

