Autor Tema: Problema con Interrupcion en TMR0  (Leído 6666 veces)

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

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Problema con Interrupcion en TMR0
« en: 26 de Agosto de 2012, 15:45:13 »
Hola, necesito de vuestra ayuda, porque despues de quince dias ya no se como conseguir el proposito que quiero, necesito poner  ContTICKS a 1 y ContRtcc a 0 dentro de la interrupcion al cabo de 20ms aproximadamente, luego ya ajustare el tiempo hasta los 20ms exactos.
Esto es lo que tengo:
Código: [Seleccionar]
;******************************************************************************************************
; FileName: MainPWM.asm
;******************************************************************************************************

;------------------------------------------------------------------------------
; PROCESSOR DECLARATION
;------------------------------------------------------------------------------
list p = PIC16873A ; Seleccionar procesador.-
#include "P16F873A.inc" ; Incluir archivo P16F873A.inc

;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file.  See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; VARIABLES
;------------------------------------------------------------------------------
CBLOCK H'20'
W_Temp
STATUS_Temp
ContRtcc
ContTICKS
ENDC;
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; CONSTANTES
;------------------------------------------------------------------------------
;Pulsador equ 0 ; Definimos Pulsador como el bit 0 de un registro, en este caso PORTA.-
;Led equ 1 ; Definimos Led como el bit 1 de un registro, en este caso PORTA.-
 
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG H'00' ; Aqui comienza el micro.-
  GOTO Inicio ; Salto a Inicio de mi programa.-
ORG H'04' ; Salta al vector de Interrupcion.-
GOTO Inicio_ISR
ORG H'05' ; Origen del codigo de programa.-

;------------------------------------------------------------------------------
; VECTOR DE INTERRUPCION
;------------------------------------------------------------------------------
Inicio_ISR ;**** Guardado de registro W y STATUS.-
movwf W_Temp ; Copiamos W a un registro Temporario.-
swapf STATUS,W ; Invertimos los nibles del registro STATUS.-
movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-

ISR ;**** Atendemos la Interrupcion.-
btfss INTCON,T0IF
goto Fin_ISR
incf ContRtcc,F
movlw 0x04
subwf ContRtcc,0
btfss STATUS,Z
goto Actualizar_TMR0
goto AjusteFino

Actualizar_TMR0
movlw 0x00
movwf TMR0
bcf INTCON,T0IF
goto Fin_ISR

AjusteFino
movlw .33
movwf TMR0
bcf STATUS,Z
bcf INTCON,T0IF
movlw 0x05
subwf ContRtcc,0
btfss STATUS,Z
goto Fin_ISR
bsf ContTICKS,0
bcf ContRtcc,0

Fin_ISR ;**** Restauramos los valores de W y STATUS.-
swapf STATUS_Temp,W ; Invertimos los nibles de STATUS_Temp.-
movwf STATUS
swapf W_Temp,F ; Invertimos los nibles y lo guardamos en el mismo registro.-
swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
retfie ; Salimos de la Interrupcion.-

;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
Inicio    ;**** Configuracion de Puertos ****
bcf STATUS,RP0
bcf STATUS,RP1 ; Bank 0.-
clrf PORTA ; Limpiamos PORTA.-
clrf TMR0 ; Limpiamos TMR0.-
clrf INTCON ; Desactivamos interrupciones y limpiamos T0IF.-
bsf STATUS,RP0 ; Bank 1.-
movlw 0x06
movwf ADCON1 ; I/O digitales.-
movlw b'00000000'
movwf TRISA ; RA<0> input RA<1:7> output.-
movlw b'10000011'
movwf OPTION_REG
bcf STATUS,RP0 ; Bank 0.-
movlw 0x00
movwf TMR0
bsf INTCON,T0IE ; Habilitamos interrupcion TMR0.-
bsf INTCON,GIE ; Habilitamos todas las interrupciones.-

loop nop
goto loop

END ; Fin del codigo.-
Agradeceria de vuestra ayuda.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado Nubbeo

  • PIC10
  • *
  • Mensajes: 12
Re: Problema con Interrupcion en TMR0
« Respuesta #1 en: 26 de Agosto de 2012, 21:58:18 »
Hola,

No estas poniendo ConTICKS en 1 y ContRtcc en 0.

   bsf         ContTICKS,0   <-Estas poniendo en 1 el bit 0 de ConTICKS
   bcf         ContRtcc,0      <-Estas poniendo en 0 el bit 0 de ContRtcc

Deberias hacer:
   movlw   0x01
   movwf   ConTICKS
   clrf      ContRtcc

Saludos

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #2 en: 27 de Agosto de 2012, 04:28:28 »
Hola Nubbeo gracias por responder, dos cosas, la primera es que no consigo modificar nunca estas dos variables, el programa no pasa por ellas y no soy capaz de ver el porque, si pruebas de simularlo lo veras.
Y como segunda cosa que igual me equivoco, en la parte de clrf   ContRtcc ahi tienes razon me equivoque ya que como se incrementa hasta llegar a 5 no estamos trabajando con un solo bit, pero en bsf   ContTICKS,0 como solo puede ser 1 o 0 creo que es correcto hacerlo de esta manera.
Seguire probando haber si doy con el fallo.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #3 en: 27 de Agosto de 2012, 07:19:27 »
Yo el problema que veo que ademas es muy comun, por lo menoa a mi me ha pasado muchas veces, es que cuando la cuenta de ContRtcc  llega  a 4 no lo pones a 0, y entonces te cuenta 255, desde 5 hasta que sea 4 otra vez. Cuando llega a 4 va a  AjusteFino ahi debes hacer un  clrf   ContRtcc, para que despues vuelva a contar hasta 4.

El registro ContTICKS no lo varias nunca ¿cuando quieres que varie este registro?

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #4 en: 27 de Agosto de 2012, 12:53:33 »
Gracias tapi8 por responder, voy a probar lo que tu me dices, aunque creo que ya lo prove, no lo se seguro porque tantas cosas he probado que creo que no me queda nada por probar  :5].
Referente al registro ContTICKS, si se debe modificar, la idea es contar 4 desbordes del TMR0 completos y otro incompleto para conseguir los 20ms que necesito,una vez tenga los 20ms pongo ContTICKS a 1 y borro ContRtcc para luego fuera de la interrupcion comprobar si ContTICKS esta a 1.
La idea es esta:
Código: [Seleccionar]
#int_RTCC
RTCC_isr()
{
   ++contRTCC;
   if(contRTCC==4)
   {
      set_TIMER0(AJUSTE_FINO_DE_RTCC);
   }
   if(contRTCC==5)
   {
      flagRTCC=1;
      contRTCC=0x00;
   }
}

Escrita originalmente por RedPic

Gracias de nuevo y Saludos!
Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #5 en: 27 de Agosto de 2012, 14:23:32 »
Bien, ya se lo que quieres. El mejor TIMER cuando se quiere una gran precision es TIMER1, que es de 16 bits, hasta 65535 puedes ajustar hasta 1uS A 4Mz y media millonesima a 8Mhz Y 200ns A 20Mhz, si necesitas buena precision pero NO a la millonesima TIMER0 te vale, en escala de 128 consigues 19968us cargando el offset con 100, como cuando entra en interrupcion te va a consumis 20us mas o menos le pone unos "nop" y ya tienes 20ms casi a la millonesima y muy sencillo de hacer ya que cuando salte la interrupcion haces lo que quieras hacer, sin contadores ni nada.

Tal y como lo tienes tu en preescaler de 16 si en vez de ponerlo a 0 le cargas 6 te da 4ms justos, pero como al realizar la rutina de interrupcion consumes ciclos (24 ciclos en tu programa) mejor cargarlo con 8 y te da en cada desborde 3968us y cuentas 5 desbordes y cuando desborde 5 veces haces:

CLRF  ContRtcc   ;para que quede a 0 para siguiente cuenta
BSF   ContTICKS,0 ; para señalizar que van 5 desbordes=20ms

Como te van a faltar unas millonesimas pones unos NOP, esto simulando en MPLAB ves cuantas millonesimas te faltan. Si es para manejar servos, que te conozco  :lol: :lol: tiene que dar buena precision, pero NO a la millonesima. Yo en tu caso usaria TIMER0 en preescaler 128 y directo sin ninguna complicacion.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #6 en: 27 de Agosto de 2012, 16:13:46 »
Gracias tapi8 por tu ayuda, voy a ver como lo hago si con TIMER1 para conseguir una buena precision, o por el contrario lo dejo por TIMER0
y añado nop, depende de lo que le pida al bot.
Os ire contando los avances y posteando las dudas que seguro surgiran.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #7 en: 28 de Agosto de 2012, 06:09:26 »
Yo creo que TIMER0 para los servos te vale de sobra, y de esta manera te quedan TIMER1 y TIMER2 para otrs cosas donde necesites mas precision.

Pones el TIMER a contar los pines donde esten conectados los servos a 1, cuentas con bucles los tiempos proporcionales a los grados que les quieras dar a cada uno, entre 0.3ms y 2.3ms (segun el servo) y vas haciendo:


CALL  DELAY   ; el tiempo proporcional a los grados
BCF SERVO_0   ; acaba dutty servo con menos grados
CALL  DELAY
BCF SERVO_1
etc

Creo que vale la pena hacerlo sin interrupcion (esto depende del resto del programa) porque cada 20ms empleas como maximo 2.3ms o 2.5ms segun sea el servo, en cada PWM de 20ms tienes 17.5 como minimo donde puedes hacer todo lo que quieras.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #8 en: 28 de Agosto de 2012, 13:01:16 »
Gracias por los consejos tapi8 ya te contare.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #9 en: 03 de Septiembre de 2012, 04:51:12 »
Hola de nuevo, sigo liado con los 20ms, he conseguido temporizar 20ms exactos en la primera pasada del programa, 40ms exactos en la segunda pasada, pero luego ya voy perdiendo microsegundos cada vez.
La que seria la tercera pasada pierdo 6us la cuarta 8us y asi sucesivamente, y no entiendo el porque, y al cabo de un tiempo se convertira en milisegundos.
Alguien podria explicarme como evitar esto, recuerdo haber visto un programa en ASM el cual conseguia la temporizacion exacta cada vez con la interrupcion del TMR0 pero no recuerdo donde.
Código: [Seleccionar]
;******************************************************************************************************
; FileName: MainPWM.asm
;******************************************************************************************************

;------------------------------------------------------------------------------
; PROCESSOR DECLARATION
;------------------------------------------------------------------------------
list p = PIC16873A ; Seleccionar procesador.-
#include "P16F873A.inc" ; Incluir archivo P16F873A.inc

;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file.  See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; VARIABLES
;------------------------------------------------------------------------------
CBLOCK H'20'
;W_Temp
;STATUS_Temp
FlagRTCC
FlagSERVO
ENDC;
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; CONSTANTES
;------------------------------------------------------------------------------
Servo equ 0 ; Definimos Pulsador como el bit 0 de un registro, en este caso PORTA.-
;Led equ 1 ; Definimos Led como el bit 1 de un registro, en este caso PORTA.-
 
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG H'00' ; Aqui comienza el micro.-
  GOTO Inicio ; Salto a Inicio de mi programa.-
ORG H'04' ; Salta al vector de Interrupcion.-
GOTO ISR
ORG H'05' ; Origen del codigo de programa.-

;------------------------------------------------------------------------------
; VECTOR DE INTERRUPCION
;------------------------------------------------------------------------------

ISR ;**** Atendemos la Interrupcion.-
btfss INTCON,T0IF
goto loop
bcf INTCON,T0IF
nop
nop
nop
nop
nop
nop
bsf FlagRTCC,0
retfie

;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
Inicio   ;**** Configuracion de Puertos ****
bcf STATUS,RP0
bcf STATUS,RP1 ; Bank 0.-
clrf PORTA ; Limpiamos PORTA.-
clrf TMR0 ; Limpiamos TMR0.-
clrf INTCON ; Desactivamos interrupciones y limpiamos T0IF.-
bsf STATUS,RP0 ; Bank 1.-
movlw 0x06
movwf ADCON1 ; I/O digitales.-
movlw b'00000000'
movwf TRISA ; RA<0> input RA<1:7> output.-
movlw b'10000110'
movwf OPTION_REG
bcf STATUS,RP0 ; Bank 0.-
movlw .100
movwf TMR0
bsf INTCON,T0IE ; Habilitamos interrupcion TMR0.-
bsf INTCON,GIE ; Habilitamos todas las interrupciones.-

loop btfss FlagRTCC,0
goto loop
bcf FlagRTCC,0
nop
movlw .100
movwf TMR0
goto loop
nop

END ; Fin del codigo.-

Saludos y Gracias!
« Última modificación: 03 de Septiembre de 2012, 04:53:30 por Miquel_S »
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #10 en: 03 de Septiembre de 2012, 05:57:14 »
En la primera te sale 20.009 porque hace la configuracion, despues te da siempre 19.992, si sumas las dos primeras te salen 40.001, pero esa primera no la debes tener en cuenta ya que solo pasa una vez, el tiempo que te vale es 19.992 que creo que para manejar servos te vale de sobra, si le ones 8 NOP mas te dara exacto, no se si te vale la pena, eso tu veras. La desviacion es de 0.04% que creo que es aceptable

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #11 en: 03 de Septiembre de 2012, 06:21:06 »
De nuevo gracias, acatare tu opinion tapi8.

Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #12 en: 03 de Septiembre de 2012, 13:35:26 »
Si no quieres gastar mas memoria de programa sustituye los NOP por GOTO $+1  y ya te da exacto, creo que tuve que poner uno mas, pruebalo asi, a mi me salen 20ms exactos, excepto la primera vez por lo que ya te dije.. Al hacer GOTO en vez de Nop, consume dos ciclos de instruccion en vez de un ciclo:




Código: [Seleccionar]
;******************************************************************************************************
; FileName: MainPWM.asm
;******************************************************************************************************

;------------------------------------------------------------------------------
; PROCESSOR DECLARATION
;------------------------------------------------------------------------------
list p = PIC16873A ; Seleccionar procesador.-
#include "P16F873A.inc" ; Incluir archivo P16F873A.inc

;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file.  See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; VARIABLES
;------------------------------------------------------------------------------
CBLOCK H'20'
;W_Temp
;STATUS_Temp
FlagRTCC
FlagSERVO
ENDC;
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; CONSTANTES
;------------------------------------------------------------------------------
Servo equ 0 ; Definimos Pulsador como el bit 0 de un registro, en este caso PORTA.-
;Led equ 1 ; Definimos Led como el bit 1 de un registro, en este caso PORTA.-
 
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG H'00' ; Aqui comienza el micro.-
  GOTO Inicio ; Salto a Inicio de mi programa.-
ORG H'04' ; Salta al vector de Interrupcion.-
GOTO ISR
ORG H'05' ; Origen del codigo de programa.-

;------------------------------------------------------------------------------
; VECTOR DE INTERRUPCION
;------------------------------------------------------------------------------

ISR ;**** Atendemos la Interrupcion.-
btfss INTCON,T0IF
goto loop
bcf        INTCON,T0IF
goto      $+1
goto      $+1
goto      $+1
goto      $+1
goto      $+1
goto      $+1
goto      $+1
; nop
; nop
; nop
; nop
; nop
; nop
bsf FlagRTCC,0
retfie

 ;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
Inicio    ;**** Configuracion de Puertos ****
bcf STATUS,RP0
bcf STATUS,RP1 ; Bank 0.-
clrf PORTA ; Limpiamos PORTA.-
clrf TMR0 ; Limpiamos TMR0.-
clrf INTCON ; Desactivamos interrupciones y limpiamos T0IF.-
bsf STATUS,RP0 ; Bank 1.-
movlw 0x06
movwf ADCON1 ; I/O digitales.-
movlw b'00000000'
movwf TRISA ; RA<0> input RA<1:7> output.-
movlw b'10000110'
movwf OPTION_REG
bcf STATUS,RP0 ; Bank 0.-
movlw .100
movwf TMR0
bsf INTCON,T0IE ; Habilitamos interrupcion TMR0.-
bsf INTCON,GIE ; Habilitamos todas las interrupciones.-

loop btfss FlagRTCC,0
goto loop
bcf FlagRTCC,0
nop
movlw .100
movwf TMR0
goto loop
nop

END

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #13 en: 03 de Septiembre de 2012, 16:41:39 »
Gracias por el dato tapi8 seguire tu consejo  :-/

Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #14 en: 11 de Septiembre de 2012, 17:03:35 »
Aunque lleve dias sin decir nada sigo vivo  :mrgreen: pero estoy intentando comparar dos variables.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.