Autor Tema: Problema con interrupcion del TMR1  (Leído 2340 veces)

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

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4069
Problema con interrupcion del TMR1
« en: 02 de Junio de 2011, 09:58:19 »
Hola amigos:

Adjunto un programita para ver sime echais un capote.
Resulta que me pongo a simularlo con PSI y todo parece ir bien hasta que entra en la interrupcion. Hecho lo cual no sale de alli nunca, al menos simulandolo nunca la veo salir de alli. Espero vuestras gentiles ayudas.

El codigo:
Código: [Seleccionar]

Define CONF_WORD = 0x2f50
Define CONF_WORD_2 = 0x3ffc
Define CLOCK_FREQUENCY = 4  'Frecuencia del reloj en Mhz

'--------------------------------  SECCIÓN DE DEFINES  -------------------------------------------
'*************************************************************************************************

Define SIMULATION_WAITMS_VALUE = 1  'Ignora los valores de Waitms. Solo para simulador

'******************************** SECCIÓN DE ETIQUETAS *******************************************

'******************************** SECCIÓN DE VARIABLES********************************************

Dim e_inicial As Bit  'Variable del estado inicial del equipo al arranque
Dim e_presostato As Bit  'variable del estado del presostato.
Dim e_valvula As Bit  'Variable del estado de la electroválvula.
Dim t_averia As Word  'Contador del tiempo para indicar avería.
Dim t_valvula As Word  'Contador del tiempo de actuación de la electroválvula.
Dim t_aver_work As Word  'Variable con valor del contador de avería.
Dim t_valv_work As Word  'Variable con valor del contador de actuación válvula.
Dim prueba_averia As Word  'Variable con tiempo de prueva de avería.
Dim prueba_valvula As Word  'Variable on tiempo de prueba de válvula.
Dim work_averia As Word  'Variable con tiempo de trabajo de avería.
Dim work_valvula As Word  'Variable con tiempo de trabajo válvula.

'---------------------- Asignación de valores a las variables ------------------------------

t_averia = 0  'Se resetea el contador auxiliar de la avería.
t_valvula = 0  'Se resetea el contador auxiliar delcontrol de la válvula.
e_inicial = 1  'Se inicializa el estado después de dar tensión al equipo.
e_valvula = 0  'Se Inicializa el estado de la válvula.
e_presostato = 0  'Se inicializa el estado del presostato.
prueba_averia = 20  'Tiempo de avería en modo trabajo. 20x0,5sg=10sg.
prueba_valvula = 4  'Tiempo actuación válvula en modo trabajo. 4x0,5sg=2sg.
work_averia = 1200  'Tiempo de avería en modo trabajo. 1200x0,5sg=600sg.=10minutos.
work_valvula = 120  'Tiempo actuación válvula en modo trabajo. 1200x0,5sg=600sg.=10minutos.

'------------------ Reasignación de nombres a los pines del micro --------------------------

Symbol averia = RA0  'Salida digital activación de señal de avería.
Symbol valvula = RA1  'Salida digital activación de electroválvula.
Symbol compresor = RB0  'Entrada digital del estado del compresor.
Symbol presostato = RB1  'Entrada digital del estado del presostato.
Symbol prueba = RB7  'Entrada digital para establecer el modo prueba del equipo.

'------------------------------ Definición de puertos -------------------------------------
AllDigital
OSCCON = 0x7e  'Set intrc To 8mhz, se usara reloj interno a 8Mh
TRISA = %00000000  'Puerto A los configurado como salidas digitales.
TRISB = %11111111  'Puerto B configurado como entradas digitales.

'-------------------- Inicializacion de timers e interrupciones ---------------------------

T1CON.TMR1CS = 0  'Bit de seleccion de reloj para el timer1, interno Fosc/4
T1CON.T1CKPS0 = 1  'Bit de seleccion del prescaler para el reloj del timer1.Divisor por 8.
T1CON.T1CKPS1 = 1  'Bit de seleccion del prescaler para el reloj del timer1.Divisor por 8.
TMR1H = 0xff  'carga el registro del contador para que desborde cada 500mSeg, byte alto
TMR1L = 0xfd  'carga el registro del contador para que desborde cada 5000mSeg, byte bajo
'TMR1H = 0x0b  'carga el registro del contador para que desborde cada 500mSeg, byte alto
'TMR1L = 0xdc  'carga el registro del contador para que desborde cada 5000mSeg, byte bajo

'*************************************************************************************************
'--------------------------------      PROGRAMA PRINCIPAL    -------------------------------------
'*************************************************************************************************

main:
'establecimiento de las condiciones iniciales.

averia = 0  'Al inicio, se deja la indicación de avería desactivada.
valvula = 0  'Al inicio, se deja la válvula desactivada.
e_inicial = 0  'Al inicio, se resetea el estado inicial.
e_valvula = 0  'Al inicio se resetea el estado de la válvula
e_presostato = 0  'Al inicio, se resetea el estado del presostato.

'Comienzo del programa principal

If prueba = 1 Then
t_aver_work = prueba_averia  'Tiempo para avería en modo prueba. 20x0,5sg=10sg.
t_valv_work = prueba_valvula  'Tiempo actuación válvula en modo prueba.4x0,5sg=2sg.
Else
t_aver_work = work_averia  'Tiempo avería en modo trabajo. 1200x0,5sg=600sg.=10minutos.
t_valv_work = work_valvula  'Tiempo actuación válvula en modo trabajo.120x0,25sg=60sg.
Endif

INTCON.PEIE = 1  'Habilitacion de interrupciones de perifericos
T1CON.TMR1ON = 1  'Desaciva el contador del TMR1
PIE1.TMR1IE = 1  'Activa las interrupciones del timer1
Enable  'INTCON.GIE habilita todas las interrupciones globales

inicio:
While compresor = 0  'Siempre que el compresor esté parado
valvula = 0  'se desactiva la válvula,
T1CON.TMR1ON = 0  'paramos el contador del TMR1
Goto inicio  'y seguimos con la secuencia general.
Wend

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

If e_inicial = 0 Then  'Si es la 1º puesta en marcha del equipo
valvula = 1  'se activa la válvula,
e_valvula = valvula  'se guarda su estado,
e_inicial = 1  'se cambia el estado inicial
e_presostato = presostato  'se guarda el estado del presostato,
Else
If e_valvula = 0 Then  'Si la valvula estaba desactivada, => si compresor=1
valvula = 0  'seguimos con la válvula desactivada o
Else
valvula = 1  'en caso contario la desactivamos.
Endif
If e_presostato <> presostato Then  'Si el presostato está como su estado guarado
e_presostato = presostato  'Al haber cambiado el presostato, guardamos su estado,
t_averia = 0  ''reseteamos el contador para la avería,
Endif
Endif

T1CON.TMR1ON = 1  'activamos el contador del TMR1
Goto inicio
'************************************ FIN DEL PROGRAMA ***************************************

End  'Fin del programa

'**********************************************************************************************
'**********************************************************************************************
'**********************************************************************************************

'------------------------------------ INTERRUPCIONES ----------------------------------------

On Interrupt  'Inicio de las interrupciones, desactivamos las interrupciones.
Save System  'Guarda los valores del sistema.

T1CON.TMR1ON = 0  'Se para el contador del TMR1.
If compresor = 0 Then  'Si el compresor está parado,
valvula = 0  'se desactiva la válvula.
Else
t_valvula = t_valvula + 1  'Incrementamos el tiempo de actuación de la válvula.
If t_valvula = t_valv_work Then  'Se compruba si válvula ha completado su ciclo de 1'.
If e_valvula = 1 Then  'si estaba activada
valvula = 0  'la desactivamos y
e_valvula = 0  'guardamos su estado.  En caso contrario
Else
valvula = 1  'Como estada desactivada, la activamos
e_valvula = 1  'y guardamos su estado.
Endif
Endif

t_averia = t_averia + 1  'incrementamos el contdaor del tiempo de la avería.
If t_averia = t_aver_work Then  'Se compruba si avería ha completado su ciclo de 10'.
bloqueo:
averia = 1  'se da señal de avería
valvula = 0  'se desactiva la válvula
Goto bloqueo  'y permanecemos en este estado hasta quitar alimentación.
Else  'sino hay avería recargamos los contadores
TMR1H = 0xff  'carga el registro del contador para que desborde cada 500mSeg, byte alto
TMR1L = 0xfd  'carga el registro del contador para que desborde cada 5000mSeg, byte bajo

'TMR1H = 0x0b  'carga del contador, desborde cada 500mSeg, byte alto.
'TMR1L = 0xdc  'carga del contador desborde cada 500mSeg, byte bajo.
T1CON.TMR1ON = 1  'Se activa el contador del TMR1.
Endif
Endif
Resume  'activamos de nuevo las interrupciones y retornamos al programa antes del salto.
Gracias de nuevo
F.
Todos los días se aprende algo nuevo.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re: Problema con interrupcion del TMR1
« Respuesta #1 en: 02 de Junio de 2011, 10:33:32 »
Yo no veo donde borras la bandera de interrupcion del TMR1. Si no la borras antes de salir del servicio de interrupcion, se va a volver a ejecutar la interrupcion.

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4069
Re: Problema con interrupcion del TMR1
« Respuesta #2 en: 02 de Junio de 2011, 13:08:49 »
Gracias, en principio era eso
errores de principinate :oops: :oops: :oops: :oops: :oops:
Ahora solo me queda corregir/depurar el programa para que haga todo lo que quiero.

F.
Todos los días se aprende algo nuevo.

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4069
Re: Problema con interrupcion del TMR1
« Respuesta #3 en: 03 de Junio de 2011, 13:02:38 »
Bueno creo que ya funciona como queria. Adjunto el listado por si alguien lo quiere reutilizar en algun proyectito. Tambien seguro que quizas se pueda mejorar y/o simplicar, así que si alguien se anima, mas abajo lo dejo. De todas formas aunque esta comentado explico brevemente su funcionamineto:

En primer lugar, nada mas dar tension, verifica si la entrada prueba está activada. Con eso variamos los tiempos para comprbar tanto el hardware como el software de forma rapida ya que los tiempos pueden ser largos a la hora de las comprobaciones.

Despues se queda en espera hasta que detecta que RB0 esta a 1 si es asi activa la salida RA1(valvula) en periodos de 1' de activacion y 1' de descanso. A la vez tambien se va comprobando si cambia de estado el pin RB1(presostato), si no cambia a los 10' se deja la electrovalvula desactivada y se activa la salida RA1(averia). Cuando esto se produce se queda en un bucle en esa situacion hasta un nuevo apagado del equipo.
Cada vez que detecta un cambio en "presostato" el tiempo de la averia se resetea y si la entrada "compresor" pasa a valer 0 (apagado), entonces se paran los tiempos(no se resetean) y se deja la valvula desactivada. Si "compresor" pasa a 1 (en marcha) entonces los tiempos se ponen de nuevo a contar hasta alcanzar sus valores establecidos y la valvula recupera el ultimo estado que tenia al pasar "compresor" a 0.
¡¡ Que les venga bien"

Código: [Seleccionar]
Define CONF_WORD = 0x2f50
Define CONF_WORD_2 = 0x3ffc
Define CLOCK_FREQUENCY = 4  'Frecuencia del reloj en Mhz
'Define SIMULATION_WAITMS_VALUE = 1  'Ignora los valores de Waitms. Solo para simulador

'******************************** SECCIÓN DE ETIQUETAS *******************************************

'******************************** SECCIÓN DE VARIABLES********************************************

Dim e_inicial As Bit  'Variable del estado inicial del equipo al arranque
Dim e_presostato As Bit  'variable del estado del presostato.
Dim e_valvula As Bit  'Variable del estado de la electroválvula.
Dim t_averia As Word  'Contador del tiempo para indicar avería.
Dim t_valvula As Word  'Contador del tiempo de actuación de la electroválvula.
Dim t_aver_work As Word  'Variable con valor del contador de avería.
Dim t_valv_work As Word  'Variable con valor del contador de actuación válvula.
Dim prueba_averia As Word  'Variable con tiempo de prueva de avería.
Dim prueba_valvula As Word  'Variable on tiempo de prueba de válvula.
Dim work_averia As Word  'Variable con tiempo de trabajo de avería.
Dim work_valvula As Word  'Variable con tiempo de trabajo válvula.

'---------------------- Asignación de valores a las variables ------------------------------

t_averia = 0  'Se resetea el contador auxiliar de la avería.
t_valvula = 0  'Se resetea el contador auxiliar delcontrol de la válvula.
e_inicial = 0  'Se inicializa el estado después de dar tensión al equipo.
e_valvula = 0  'Se Inicializa el estado de la válvula.
e_presostato = 0  'Se inicializa el estado del presostato.
prueba_averia = 20  'Tiempo de avería en modo trabajo. 20x0,5sg=10sg.
prueba_valvula = 4  'Tiempo actuación válvula en modo trabajo. 4x0,5sg=2sg.
work_averia = 1200  'Tiempo de avería en modo trabajo. 1200x0,5sg=600sg.=10minutos.
work_valvula = 120  'Tiempo actuación válvula en modo trabajo. 1200x0,5sg=600sg.=10minutos.

'------------------ Reasignación de nombres a los pines del micro --------------------------

Symbol averia = RA0  'Salida digital activación de señal de avería.
Symbol valvula = RA1  'Salida digital activación de electroválvula.
Symbol compresor = RB0  'Entrada digital del estado del compresor.
Symbol presostato = RB1  'Entrada digital del estado del presostato.
Symbol prueba = RB7  'Entrada digital para establecer el modo prueba del equipo.

'------------------------------ Definición de puertos -------------------------------------
AllDigital
OSCCON = 0x7e  'Set intrc To 4mhz, se usara reloj interno a 4Mh
TRISA = %00000000  'Puerto A los configurado como salidas digitales.
TRISB = %11111111  'Puerto B configurado como entradas digitales.

'-------------------- Inicializacion de timers e interrupciones ---------------------------

T1CON.TMR1CS = 0  'Bit de seleccion de reloj para el timer1, interno Fosc/4
T1CON.T1CKPS0 = 1  'Bit de seleccion del prescaler para el reloj del timer1.Divisor por 8.
T1CON.T1CKPS1 = 1  'Bit de seleccion del prescaler para el reloj del timer1.Divisor por 8.
TMR1H = 0x0b  'carga el registro del contador para que desborde cada 500mSeg, byte alto
TMR1L = 0xdc  'carga el registro del contador para que desborde cada 5000mSeg, byte bajo

'*************************************************************************************************
'--------------------------------      PROGRAMA PRINCIPAL    -------------------------------------
'*************************************************************************************************

main:
'establecimiento de las condiciones iniciales.

averia = 0  'Al inicio, se deja la indicación de avería desactivada.
valvula = 0  'Al inicio, se deja la válvula desactivada.

'Comienzo del programa principal

If prueba = 1 Then
t_aver_work = prueba_averia  'Tiempo para avería en modo prueba. 20x0,5sg=10sg.
t_valv_work = prueba_valvula  'Tiempo actuación válvula en modo prueba.4x0,5sg=2sg.
Else
t_aver_work = work_averia  'Tiempo avería en modo trabajo. 1200x0,5sg=600sg.=10minutos.
t_valv_work = work_valvula  'Tiempo actuación válvula en modo trabajo.120x0,25sg=60sg.
Endif

INTCON.PEIE = 1  'Habilitacion de interrupciones de perifericos
T1CON.TMR1ON = 1  'Desaciva el contador del TMR1
PIE1.TMR1IE = 1  'Activa las interrupciones del timer1
Enable  'INTCON.GIE habilita todas las interrupciones globales

inicio:
While compresor = 0  'Siempre que el compresor esté parado
valvula = 0  'se desactiva la válvula,
T1CON.TMR1ON = 0  'paramos el contador del TMR1
Goto inicio  'y seguimos con la secuencia general.
Wend

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

If e_inicial = 0 Then  'Si es la 1º puesta en marcha del equipo
valvula = 1  'se activa la válvula,
e_valvula = 1  'se guarda su estado,
e_inicial = 1  'se cambia el estado inicial
e_presostato = presostato  'se guarda el estado del presostato,
T1CON.TMR1ON = 1  'activamos el contador del TMR1
Endif

While compresor = 1  'Siempre que el compresor este en marcha,
T1CON.TMR1ON = 1  'activamos el contador del TMR1.
If e_valvula = 0 Then  'Si la valvula estaba desactivada, => si compresor=1
valvula = 0  'seguimos con la válvula desactivada o
Else
valvula = 1  'en caso contario la desactivamos.
Endif

If e_presostato <> presostato Then  'Si el presostato está como su estado guardado
e_presostato = presostato  'Al haber cambiado el presostato, guardamos su estado,
t_averia = 0  ''reseteamos el contador para la avería,
Endif
Wend

Goto inicio
'************************************ FIN DEL PROGRAMA ***************************************

End  'Fin del programa

'**********************************************************************************************
'**********************************************************************************************
'**********************************************************************************************

'------------------------------------ INTERRUPCIONES ----------------------------------------

On Interrupt  'Inicio de las interrupciones, desactivamos las interrupciones.
Save System  'Guarda los valores del sistema.

T1CON.TMR1ON = 0  'Se para el contador del TMR1.
If compresor = 0 Then  'Si el compresor está parado,
valvula = 0  'se desactiva la válvula.
Else
t_valvula = t_valvula + 1  'Incrementamos el tiempo de actuación de la válvula.
If t_valvula = t_valv_work Then  'Se compruba si válvula ha completado su ciclo de 1'.
t_valvula = 0  'Se resetea el tiempo de actuacion de la válvula.
If e_valvula = 1 Then  'Si la válvula estaba activada
valvula = 0  'la desactivamos, y
e_valvula = 0  'guardamos su estado.  En caso contrario
Else
valvula = 1  'activamos la válvula y
e_valvula = 1  'guardamos su estado.
Endif
Endif

t_averia = t_averia + 1  'incrementamos el contador del tiempo de la avería.
If t_averia = t_aver_work Then  'Se compruba si avería ha completado su ciclo de 10'.
bloqueo:
averia = 1  'se da señal de avería
valvula = 0  'se desactiva la válvula
Goto bloqueo  'y permanecemos en este estado hasta quitar alimentación.
Endif

TMR1H = 0x0b  'carga del contador, desborde cada 500mSeg, byte alto.
TMR1L = 0xdc  'carga del contador desborde cada 500mSeg, byte bajo.
T1CON.TMR1ON = 1  'Se activa el contador del TMR1.

Endif

PIR1.TMR1IF = 0  'borra el flag de salto del tmr1

Resume  'activamos de nuevo las interrupciones y retornamos al programa antes del salto.


F.
Todos los días se aprende algo nuevo.