Autor Tema: INTERRUPCIONES REALES EN PLUS  (Leído 9866 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
INTERRUPCIONES REALES EN PLUS
« en: 07 de Octubre de 2004, 07:51:00 »
HOLA AMIGOS.

HE DECIDIDO CAMBIAR LA INSTRUCCION COUNT PIN POR UNA RUTINA DE INTERRUPCION REAL es decir no la on _interrupt del plus .dado que mi cuenta rpm detiene la operacion del programa que tiene 2 ad funcinando durante 1 seg para darle tiempo al count pin de realizar un conteo preciso.
Entonces se me ocurrio , a ver si la teoria es correcta,lo siguente

Usar el TRM1 de 16 con un xtal de 32 768 para obtener una interrupcion cada segundo
debo usar xtal ? o alguna combinacion de prescaler /post me puede dar 1 seg exacto usando intosc..
 si es externo lo debo usar sincronico con el del pic o no

Usar esa interrupcion para leer el contenido del TRM0 ,es decir como base de tiempo(el TRM1)

Estare limitado a 15300 rpm dado que el TRM0 es de 8 bits y solo contara hasta 255 que por 60 seg dara esta cifra

Es correcta mi teoria o puedo utilizar alguna otra combinacion de TRMs para no detener la ejecucion del programa mientras se produce el conteo y la base de tiempo.
Necesito algun empujon para empezar con las benditas interrupciones

Gracias
khasistos

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #1 en: 09 de Octubre de 2004, 13:13:00 »
Hola pana Khasisots, por favor reviza el mail que te envie, hay mas info en este post http://miarroba.com/foros/ver.php?foroid=8826&temaid=2664719
Cualquier cosa me avisas pana, si tu programa no es muy pero muy complejo pudes usar esta interrupcion, pero si de antemano es un programa lleno de funciones muy especificas como dice el pana RGL a ensamblar.
Salu2 pana

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #2 en: 09 de Octubre de 2004, 14:03:00 »
Hola.
gracias pana por el aporte de sabiduria que estas haciendo ,agarrense porque voy a ampezar con los on_interrupt en Plus y va a haber mas de una duda .vamos con la primera como les dije la teoria es hacer al TRM1 base de tiempo con Xtal de 32768,entonces voy a cargar el valor 16 384 para que me de una interrupcion cada segundo con prescaler en 1,entonces :
El clock lo debo poner en sincronismo con el del micro?
Debo habilitar solo la interrupcion del TRM1 o las globales tambien?

saludos
K

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #3 en: 09 de Octubre de 2004, 14:32:00 »
Pana khasistos, las de cajon son las del registro INTCON.7 (global int) y las de desborde y de activacion estan en el registro PIE para el TMR1. aqui un poco de info para mejor entendimiento del TMR0antes de entrar de llenao a interrupcions)

PSA          Bit de asignamiento del predivisor de frecuencia:
   0 = Predivisor asignado a TMR0   
   1 = Predivisor asigando a Watchdog (WDT)
TOSE        Bit de selección de flanco activo cuando TMR0
   es configurado como Contador
   0 = Contaje se incrementa cada flanco ascendente    
   1 = Contaje se incrementa cada flanco descendente   
TOCS        Bit de seleción de la fuente del clock:
   0 = Configura TMR0 como Temporizador
   1 = Configura TMR0 como Contador
INTEDG     Bit de seleción de flanco activo de interrupción externa:
   0 = flanco descendente   
   1 = flanco ascendente
RPBU#     Resistencias pull - up de la puerta B:
   0 = Activadas   
   1 = Desactivadas

El registro TMR0 esta implementado físicamente en el pin RA4 del PORTA, este registro de 8 bits se configura como temporizador para determinar intervalos concretos de tiempo o como contador de impulsos externos .

La combinación binaria de los bits PS0, PS1 y PS2, del registro OPTION me definen el rango del divisor de frecuencias.
¿Como calcular el tiempo?
T = CI x TMR0 x DF
    CI   = Ciclo de instrucción
    TMR0 = Valor cargado en este registro.
    DF   = Rango escogido en el divisor de frecuencia(preescaler)
Por ejemplo si por software cargo un valor de 125 en el registro TMR0, entonces el valor que interviene en la fórmula es 130, valor que falta para que se desborde (llegue a 255) el registro TMR0.
Resumiendo:
Si ponemos al máximo los valores de la fórmula, rango de divisor de 256, TMR0 con 255 y un oscilador de 4 Mhz(no el externo), obtenemos un valor máximo de temporización de 65.28 milisegundos




Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #4 en: 09 de Octubre de 2004, 15:16:00 »
Hola Pana:

Voy entendiendo...solo que voy a utilizar el TMR1 pues permite tiempos mas largos dado que es de 16 bits,entonces al trabajar con 32768 de osc y cargando el TRM1 con 32768 no entiendo porque no voy atener 1 seg de acuerdo a tu formula Si comienzo el conteo con 32768 le llevara 2 segundos al trm1(preescaler =1) saturarse (65535) pero si lo inicializo en 32768 saltara la interrupcion en 1 segundo.dime si me equivoco......
AHHH y por favor no me toques el puerto A esta en un hilo no olvides que ahi estan los AD trabajando y se estan cambiando los adcon1 dejalo tranquilo por favor ya veremos cuando tenga que leer el trm0 que oficia de contador de pulsos.....

Gracias por toda tu explicacion espero no te canses....

Abrazos
K

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #5 en: 09 de Octubre de 2004, 15:39:00 »
jajajajaja ok khasistos,
Mira la otra formula era con un reloj normalizado (osease a 1us de ciclo) tu estas usando otro, asi que no te preocupes por eso.
Para usar el Tmr1 es exactamente el mismo proceso, solo que el que temporiza esta ves es el Tmr1(eso ya lo dije  ) en el registro T1CON es el registro de control del Tmr1 con el bit 0 lo activas o desactivas, con el 2° eliges reloj externo e interno(en tu caso interno ya que lo vas a usar para esperar 1 seg), el bit 4 y 5 son el preescaler  el bit 3 es para apagar o encender el reloj del timer1(tu no lo necesitas ya que es intenbro) y el bit 2 para seleccionar si quiere sincronizar tu reloj externo(solo cuando cuando usas reloj externo osease no lo necesitas).
el desbordamiento por interrupcion em Tmr1 esta como te comente en el registro PIR1 bit 0 . acuerdate de activar el bit 7 del INTCON para habilitar TODAS las interrupcions(GIE). si usas reloj externo va a funcionar basicamente como contador y si usas el interno como temporizador(igual que con cualquier Tmr)
Salu2 pana

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #6 en: 09 de Octubre de 2004, 16:31:00 »
Pana Khasistos aqui t dejo un ejemplo con TMR1 de lata precision, jajajajaajjaa, me voy a volver relojero . Espero y quede mas que claro, solo una cosa, este trabaja con compensacion de tiempo a traves de una  formula de correccion de tiempo que tiene integrado, la excatitud es increible, y aun se puede mejorar.
Espero y te sea de ayuda
Un abrazo pana.

------------------------------------------------------------------------------------
DEVICE 16F628
        CONFIG INTRC_OSC_NOCLKOUT,WDT_OFF,PWRTE_ON,CP_OFF,BODEN_OFF,LVP_OFF,MCLRE_OFF
        ALL_DIGITAL ON
      DECLARE LCD_DTPIN PORTA.0
       DECLARE LCD_ENPIN PORTB.3
       DECLARE LCD_RSPIN PORTA.4
       DECLARE SDA_PIN PORTB.5
        DECLARE SCL_PIN PORTB.1      
       DIM _100THS                                
       DIM SECS
       DIM MINS
       DIM HOURS
       DIM DAYS
       DIM TEMP_100THS
       DIM TEMP_SECS
       DIM TEMP_MINS
       DIM TEMP_HOURS
       DIM TEMP_DAYS
        SYMBOL GIE = INTCON.7                          
        DIM TIEMPO AS TMR1L.WORD                
       SYMBOL MARGEN = 7                     " VARIABLE PARA MEJORAR EXACTITUD
       SYMBOL TMR1_VAL =((65536)-(XTAL*2500))+MARGEN " CALCULA LOS VALORES COMPENSANDO EL OSCILADOR PARA UNA INTERRUPCIÓN A 100HZ
   
       ON_INTERRUPT INTERRUMPIR              " Interrupciones RAPIDAS!!!
      GOTO INICIO                                      " JUMP THE INTERRUPT CODE

INTERRUMPIR:

       CLEAR T1CON.0                               " DETIENE TMR1
       TIEMPO = TIEMPO + TMR1_VAL            " COMPENSA EL TMR1
       SET T1CON.0                                 " LO ARRANCA DE NUEVO
   
       INC _100THS                                " INCREMENTA LA VARIABLE CENTESIMAS
       IF _100THS = 100 THEN                 " CHEKA SI YA LLEGO A 100
          CLEAR _100THS
          INC SECS                                              " INCREMENTA SEGUNDOS
          IF SECS = 60 THEN
              CLEAR SECS
              INC MINS                                            " INCREMENTA MINUTOS
              IF MINS = 60 THEN
                  CLEAR MINS
                  INC HOURS
                  IF HOURS = 24 THEN                      " INCREMENTA HORAS
                      CLEAR DAYS
                      INC DAYS                                    "INCREMNTA DIAS!!!!
                  ENDIF
              ENDIF
          ENDIF
      ENDIF
      CLEAR PIR1.0                   " LIMPIAMOS INT
      CONTEXT RESTORE                         " A RESTAURAR!!! Y SALIR DE LA INT VELOZMENTE
   
INICIO:
    CLEAR                                                      " LIMPIAMOS VARIABLES
   T1CON = %00000000                           " PREESCALER A 1:1
   PIR1.0 = 0                                  " LIMPIAMOS BANDERA DE INT
   INTCON = %11000000                          " INTERUPCIONES GLOBALES Y PERIFERICAS
   PIE1.0 = 1                                  
   T1CON.0 = 1                                 " ENCENDEMOS TMR1
   
    CLS                                        
    WHILE 1 = 1                                 " BUCLE SIN FIN!!!
    GIE = 0                                " DESHABILITAMOS INT
    WHILE GIE = 1 : GIE = 0 : WEND                " RUTINA DE SEGURIDAD!!
    TEMP_100THS = _100THS                       " SALVAMOS VARIABLES
    TEMP_SECS = SECS
    TEMP_MINS = MINS
    TEMP_HOURS = HOURS
    TEMP_DAYS = DAYS
    GIE = 1                                    " HABILITAMOS INT      
    PRINT AT 1,1,DEC2 TEMP_DAYS,":",DEC2 TEMP_HOURS,":",DEC2 TEMP_MINS,":",DEC2 TEMP_SECS,":",DEC2 TEMP_100THS  
    DELAYMS 100                                
  WEND                                          
  STOP

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #7 en: 10 de Octubre de 2004, 10:39:00 »
Hola:

De acuerdo a las enseñanzas del MAESTRO Lager aqui les posteo este pequeño programa que verifica el uso de la interrupcion del trm1 incrementando una variable y presentandola en el display ,funciona con Xtal de 32768 en oso/osi (RC0,RC1)
Y 877 A 20 MHZ.
funciona bien solo que por algun motivo aun desconocido por mi la variable no se incrementa mas de 255 no se que registro esta SALTANDO en overflow aun ....
Saludos
K
"****************************************************************
"*  Name    : int.BAS  
"*  Date    : 10/10/04

 
          DEVICE = 16F877
        XTAL = 20
      ALL_DIGITAL=TRUE
   
   
     LCD_DTPIN = PORTD.4   
     LCD_RSPIN = PORTE.0
    LCD_ENPIN = PORTE.1
   LCD_INTERFACE = 4   " 4-bit Interface
   LCD_LINES = 2
   LCD_TYPE = 0
   
    Dim TIMER1 as TMR1L.Word            " TRM1 es word (16 bits)
     Dim TICK as byte system
     ON_INTERRUPT Goto Int
    DIM PP1H AS BYTE SYSTEM
     DIM PP1H_TEMP AS BYTE SYSTEM
    Delayms 400                         " espero que el micro se estabilize
     CLS

Goto main                " salto al inicio del prog
             
Int:
PP1H_TEMP =PP1H  
PP1H=PP1H_TEMP
context restore

TIMER1 = 32768                      " cargo trm1 con mi valor
Clear PIR1.0                        "limpio el trm1 interrupt flag
INC TICK                            "incremento la variable tick en cada int.
 
MAIN:
   

T1CON = %00001011             " Enciendo TRM1 con prescaler 1 y oscilador Xtal
Clear PIR1.0                  " limpio el trm1 interrupt flag
Set PIE1.0                    " habilito TMR1 como interrupcion periferica  
INTCON =  %11000000           " Habilito las iterrupciones globales y perifericas
 
Print at 1,1,dec TICK
    

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #8 en: 10 de Octubre de 2004, 12:14:00 »
Me da gusto que ya este funcionando con tu reloj pana khasistos, otra cosa para nada soy maestro, solo puse lo basico de interrupciones y estoy casi seguro que en este momento has de saber mas que yo.  
Veo un problema, estas usando para tick(que noes una variable del sistema) la definicion equivocada, ademas en byte solo guardaria el limite de tu problema 255, cambiala  Word y reviza.
El otro problema esta en tu interrupcion:
Int:
PP1H_TEMP =PP1H  <--- estas guardando bien el s.v
PP1H=PP1H_TEMP  <--- este esta restaurando!!! este no va aqui
context restore    <-- este va al final de toda la interrupcion
                                   <--- no veo donde deshabilitas la int??
TIMER1 = 32768 " cargo trm1 con mi valor    
Clear PIR1.0 "limpio el trm1 interrupt flag
INC TICK "incremento la variable tick en cada int.
                          <--- donde vuelves a habilitar la int
REviza tu estructura completa pana no se si te funcione asi, pero no es la mas adecuada
Un abrazo pana

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #9 en: 10 de Octubre de 2004, 12:26:00 »
Aqui tu Ejercicio funcionando, por favor reviza bien la sintaxis, es importante entender por que va colocado cada comando y donde para que siempre el trabajo sea optimo en cuanto a tiempos y espacio ocupado :
Dim TIMER1 as TMR1L.Word " TRM1 es word (16 bits)
Dim TICK as word
DIM PP1H AS BYTE SYSTEM
DIM PP1H_TEMP AS BYTE SYSTEM
Goto main " salto al inicio del prog
-------------------------------------------------------------------------------------
Int:
PP1H_TEMP =PP1H  <---- guardamos todas las v.s
CLEAR T1CON.0       <-----detenemos el tmr1
TIMER1 = 32768 " cargo trm1 con mi valor  <--tu codigo isr
INC TICK "incremento la variable tick en cada int.
SET T1CON.0           <-----encendemos el tmr1 , pero no esta en cero la bandera de int asi que es como si estuviera apagado
PP1H=PP1H_TEMP   <-----restauramos las v.s
Clear PIR1.0 "limpio el trm1 interrupt flag  <-- ahora si esta en cero ahora empieza a trabajar la int no antes
context restore  <--- restauramos status,fsr,w,etc
-----------------------------------------------------------------------------------
MAIN:
    CLEAR                                       " LIMPIAMOS VARIABLES
   T1CON = %00000000   " Desde el inicio apagamos tmr1, usamos un prescaler de 1:1
   PIR1.0 = 0                    " limpiamos bandera de int pero aun no comienza a trabajar
   INTCON = %11000000  " requisitos para que funcione cualquier int periferica y global
   PIE1.0 = 1                     "encendemos la int de tmr1    esta se queda perpetuamente asi          
   T1CON.0 = 1                 "Ahora si empieza a trabajar la int habilitando el Tmr1(ya no hay nada que ativar)
   CLS                          
-------------------------------------------------------------------------------------
while 1=1                              "bucle infinito aqui sucedera la int siempre no antes
Print at 1,1,dec TICK
Delayms 100 " espero que el micro se estabilize
wend
end

Trata de poner siempre el ON_INTERRUPT despues de  declarar los fuses asi jamas te fallara
Un abrazo pana

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #10 en: 10 de Octubre de 2004, 17:10:00 »
Hola Master lager
He hecho algunas correcciones en MAIN: con el registro T1CON y no por llevarte la contra sino pues he deducido que como dices debo parar el trm1 pero no el osc a XTAL ni la sincronizacion ,pues si asi lo hiciese el oscilador del TRM1 arancaria probablemente inestable asi que lo dejo habilitado andando y en sincronia solo paro el bit 0.
A ver si ahora das tu aprobacion pana,hasta ahora he logrado gracias a ti un hermoso contador de 65535 segundos.Por algo se empieza
"****************************************************************
"*  Name    : int.BAS  
"*  Date    : 10/10/04

 
          DEVICE = 16F877
        XTAL = 20
       ON_INTERRUPT Goto Int
      ALL_DIGITAL=TRUE
   
   
     LCD_DTPIN = PORTD.4   
     LCD_RSPIN = PORTE.0
    LCD_ENPIN = PORTE.1
   LCD_INTERFACE = 4   " 4-bit Interface
   LCD_LINES = 2
   LCD_TYPE = 0
   
    Dim TIMER1 as TMR1L.Word            " TRM1 es word (16 bits)
     Dim TICK as word
     
    DIM PP1H AS BYTE SYSTEM
     DIM PP1H_TEMP AS BYTE SYSTEM
    Delayms 400                         " espero que el micro se estabilize
     CLS

Goto main                " salto al inicio del prog
             
Int:
PP1H_TEMP =PP1H  
clear T1CON.0                        "detengo el TRM1
TIMER1 = 32768                      " cargo trm1 con mi valor

INC TICK                            "incremento la variable tick en cada int.
SET T1CON.0                         "enciendo el TRM1
PP1H=PP1H_TEMP
Clear PIR1.0                          "limpio el trm1 interrupt flag
context restore  



MAIN:
Clear
T1CON = %00001010              "solo paro el TRM1 y configuro 1:1 y XTAL en osi/ oso

Clear PIR1.0                  " limpio el trm1 interrupt flag
Set PIE1.0                    " habilito TMR1 como interrupcion periferica  
INTCON =  %11000000           " Habilito las iterrupciones globales y perifericas
T1CON = %00001011             " Enciendo TRM1 con prescaler 1 y oscilador Xtal
while 1=1 "bucle infinito aqui sucedera la int siempre no antes
Print at 1,1,dec TICK
Delayms 100 " espero que el micro se estabilize
wend
end

ABRAZO
K
    

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #11 en: 10 de Octubre de 2004, 17:21:00 »
De maestro a lo mejor los gises que tengo por aqui y nada masEXCELENTE tu observacion Khasistos, ni me habia dado cuenta del problemon que traeria detener a cada rato el osc .
Salu2 pana

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #12 en: 10 de Octubre de 2004, 17:49:00 »
Gracias pana:
Bueno ahora voy a pooner el trmo como contador de pulsos y lo que hicimos sera para la base de tiempos ,entonces como NO voy a habilitar interrupcion para el TRM0 puedo poner un symbol X=TRM0
y luego leer la cuenta en la interrupcion??por ej Pulsos=X

o como seria la forma de leer la cuenta del trm0 en la interrupcion??
OJO pana no te pido un SUPER desarrollo simplemente la expresion mas simple de leer el valor del trm0 OK?No voy a llegar a desbordar al trm0 asi que no habilitare las int del mismo..

Abrazo
K

Desconectado lager

  • PIC18
  • ****
  • Mensajes: 258
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #13 en: 10 de Octubre de 2004, 19:01:00 »
Haber pana khasistos, antes que nada, acuerdate que la interrupcion de tiempo con el tmr1 que hiciste, a la larga va a tener un retraso o margen de error que en largos periodos tienes que  restaurar para que nunca sea mucha la falla, claro esto en el ejmplo de reloj(por que va a permanecer 1 año 2 años encendido o meses o dias, claro si no lo muerde el perro, ) en  el caso de este uso, lo podriamos despreciar momentaneamente estableciendo que siempre habra una interrupcion cada 1 seg. Solo queria dejar en claro este punto por que el tema de timers de muy alta precision es extenso tambien.
Si sabes que cada seg va haber una interrupcion  ahora decides usar  el tmr0 como contador hay que hablitarlo como tu sabes desde option_reg aun asi nos enfrentaremos al detalle de la frrecuencia maxima que soportara el tmr0 ya que acurdate que  solo cuenta hasta 255(e aqui la preferencia de usar tmr1 o tmr2 como contador)  cada segundo se va a hacer un muestreo de los pulsos contados, yo  creo que te va a sobrer tiempo. Lo que se me ocurre es lo siguiente(claro es olo una idea)
Que arranque el periodo de muestreo, usamos el desbrode dela int de tmr0 (obviamente cada ves que desborda limpiamos,contamos  y salimos de la int al final se toman el numero de interrupciones por 256 mas el valor de tmr0 como valor final de muestreo, supongamos que fue 1000 este valor dividido entre el segundo nos dara la frecuencia, claro este claculo solo se hara AL FINAL del muestreo, para no tener un margen de error amplio.Reviza el ejemplo que te envie

Salu2 pana

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: INTERRUPCIONES REALES EN PLUS
« Respuesta #14 en: 10 de Octubre de 2004, 19:25:00 »
Hola Pana

Lo de la precision del reloj la tengo clara eso se puede ajustar cambiando el valor de carga en el trm1 o como se hace en el ejemplo del reloj ,creo que luego de poner en funcionamiento el trm0 sera facil ajustar haciendo coincidir el valor del generador de frec con el mostrado en el display ,ya se que a lo mejor hay alguna dif en el segundo por alguna instruccion que se ejecuta y no la hemos tomado en cuenta.,tambien pana esta claro que tenemos un contador de 256 asi que la frec max sera de 15 300 siempre y cuando no le ponga un prescaler ...y como yo todavia no tengo un F1 me sobran...Entonces mientras no llege a 15300 rpm no va a desbordar el tmr0.Tambien tu teoria es interesante ahi no habria limitaciones se incrementaria una variable durante el periodo de muestra al final leeriamos cuantas veces se desbordo mas el numero que tenga el TMR0 en el momento que TRM1 llego a desbordarse..pero piensa que hasta ayer las interrupciones eran solo cerebrales mias y hoy gracias a ti ya estoy metido y haciendo funcionar cosas .vamos despacio voy a empezar a hacer funcionar el "Limitado" entonces dime como lo leo durante la interrupcion es decir como "tomo "su valor.....Symbol X=TMR0 y luego dentro del handler  Pulsos=X..puede ser??Creo saber como habilitar el TMR0 y como limpiarlo asi que en eso no te preocupes que ya me van a surgir dudas...JA JA

abrazos y gracias
K