Autor Tema: Ayuda con interrupcion para el timer1!!.  (Leído 8804 veces)

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

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #15 en: 06 de Marzo de 2007, 16:23:04 »
Gracias Mauricio por las explicaciones, pero claro definir esas variables no es lo no veía, es de como hacer los incrementos en el low cada vez que el timer 2 gire, y como hacer en el high para incrementar en 1, cada vez que el low gire...

Yo no entiendo mucho, pero creo que para esto uso la interrupcion, como me dijiste de quitarla, como podría ir incrementado cada variable?.

Saludos.

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #16 en: 06 de Marzo de 2007, 17:04:32 »
Gracias Mauricio por las explicaciones, pero claro definir esas variables no es lo no veía, es de como hacer los incrementos en el low cada vez que el timer 2 gire, y como hacer en el high para incrementar en 1, cada vez que el low gire...

Yo no entiendo mucho, pero creo que para esto uso la interrupcion, como me dijiste de quitarla, como podría ir incrementado cada variable?.

Yo no te dije de quitar la interrupción. te dije que puedes usarla o no, es a tu gusto.  Lo que sí te dije es que no uses el timer1 de esa forma. 

Para hacer los incrementos en la variable de 16 bits, haces algo así.  Cuando se enciende el TMR2IF tu lo pudes detectar directamente haciendo un loop o bien lo haces con una interrupción habilitada.  Entonces al habilitarse haces lo siguiente:


    bcf     PIR1,TMR2IF
    incf    MIVAR16+0,f
    btfss   STATUS,C
    goto    _CONTINUA
    incf    MIVAR16+1,f

_CONTINUA:
   ...

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #17 en: 07 de Marzo de 2007, 07:07:50 »
Gracias Mauricio,

El timer2 ya esta trabajando.
El problema es la interrupcion, no soy capaz de hacer que cuando la variable tmr2hL = 0 incremente en 1 el valor de la variable tmr2hH. Si pongo btfss si es 0 salta y si es 1 tambien, y si pongo btfsc, no salta ni siendo 0 ni siendo 1.

Alguna forma de que solo salte la siguiente instruccion si es 0 el valor de la variable tmer2hL.
Te pongo la interrupción

Interrupt           movwf   intWsave
                        movf    STATUS,W
                        movwf   intStatusSave
                        bcf     PIR1,TMR2IF       ; Clear the timer2 interrupt
                        incf    tmr2hL,F          ; and advance high counter LOW.
                        btfss   STATUS,C
                        goto    jump
                        incf    tmr2hH,F          ; and advance high counter HIGH.
jump                 movf    intStatusSave,W
                        movwf   STATUS
                        swapf   intWsave,F
                        swapf   intWsave,W
                        retfie

La configuracion del timer2 la dejé asi, creo que no me dejé nada, funciona bien en teoría en el simulador, cuando llega a 100 conteos se resetea el TMR2, pasa a la interrupcion aumenta el tmr2hL y sigue contando... pero una vez se resetea el tmr2hL no soy capaz que se vaya incrementando el tmr2hH.

Creo que no se me escapa nada te dejo aqui :

START               clrf    STATUS           ; Clear Status
                        clrf    INTCON           ; Disable interrupts
                        clrf    PCLATH           ; Keep in lower KByte
                        clrf    PORTA            ; Clear ports
                        clrf    PORTB

                        bsf     STATUS,RP0       ; Select bank 1
                        clrf   ANSEL           ; All pins are Digital
                        movlw   H'07'
                        movwf   CMCON           ; Turn off comparators
                        movlw   B'00010000'      ; i/o port value
                        movwf   TRISA
                        movlw   B'00000001'      ; i/o port value
                        movwf   TRISB
                        movlw   B'10000101'      ; pullup off, prescaler=64,
                        movwf   OPTION_REG       ; Set the OPTION register
                        bcf     STATUS, RP0      ; Select bank 0
                       
                        movlw   b'00000101'      ; Prescaler=1:4(1us) TMR2=ON
                        movwf   T2CON            ; config T2CON
                        bsf     INTCON,GIE       ; Enable Global Interrupt
                        bsf     INTCON,PEIE      ; and peripheral
                        bsf     STATUS, RP0      ; Select bank 1
                        bsf     PIR1,TMR2IF      ; unmask the timer2 interrupt
                        bsf     PIE1,TMR2IE      ; and enable interrupt.
                        movlw   0x64             ; Fix PR2 to 100 counts
                        movwf   PR2              ; So TMR2 count until 100us
                        bcf     STATUS, RP0      ; Select bank 0

Gracias por la ayuda.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #18 en: 07 de Marzo de 2007, 12:37:13 »
El problema es la interrupcion, no soy capaz de hacer que cuando la variable tmr2hL = 0 incremente en 1 el valor de la variable tmr2hH. Si pongo btfss si es 0 salta y si es 1 tambien, y si pongo btfsc, no salta ni siendo 0 ni siendo 1.

Alguna forma de que solo salte la siguiente instruccion si es 0 el valor de la variable tmer2hL.
                        incfsz    tmr2hL,F          ; and advance high counter LOW.
                        goto    jump
                        incf    tmr2hH,F          ; and advance high counter HIGH.
jump                 movf    intStatusSave,W
                        movwf   STATUS
                        swapf   intWsave,F
                        swapf   intWsave,W
                        retfie

P.D. Perdona que no te ayude mas, pero me quedé atrasado en el hilo y leer 15 posts...ufff!
« Última modificación: 07 de Marzo de 2007, 12:39:55 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #19 en: 07 de Marzo de 2007, 13:03:37 »
Bruno,

Ahora si funciona correctamente!!, muchas gracias, me ayudasteis mucho, y he aprendido bastante con el simulador.
Ahora tengo que cuadrar los límites de corte, para esto no habrá problema, y el tema de las tablas, que si me surge algo ya lo comentaré.
Muchas gracias a ti y a Mauricio. :-/

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #20 en: 07 de Marzo de 2007, 13:21:09 »
De nada! Ahora deslumbranos con el invento.
Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #21 en: 07 de Marzo de 2007, 15:56:36 »
Hola, estoy intentando hacer un retardo fijo, segun el valor del contador.

De forma que :

(valor contador) *( tiempo instruccion*tiempo queda interacion)/ us conteo contador = 0,06*contador
Sería valor contador *0,25us*4/100us, esto es 0,25 de instruccion del pic*4 porque esta interacion de retardo gasta 4 instrucciones.
ASi 1/100 = 0,01 *k *valor del contador. Por ello tengo que multiplicar, ese k debe ser k=6.

fixed35              bcf    03,0
                        rlf    perl,F
                        rlf    perh,F
                        incf    perl,F          ; Less than 3509 rpm
                        incf    perh,F
bucle2                  nop
                        decfsz  perl,F
                        goto    bucle2
                        decfsz  perh,F
                        goto    bucle2

La idea es retardar el valor de tiempo que recoge el contador * por un valor fijo, porque quiero que haga como si dijeramos un 80% del valor del contador de retardo.

Ese bucle gasta 4 instruccion cada interaccion, las tres primeras lineas se que hacen k=2, vamos que multiplica el valor del contador x 2, lo que quiero es de la misma forma que sea *6 y no *2.

No entiendo muy bien lo que hace bcf 3,0

Si me podeis explicar que hace esa linea y aconsejarme como poder hacer eso.
Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #22 en: 07 de Marzo de 2007, 21:39:19 »
No entiendo muy bien lo que hace bcf 3,0
Si me podeis explicar que hace esa linea y aconsejarme como poder hacer eso.
Gracias.

Para comprender lo que hace el bcf 3,0 o bien más conocido como bcf STATUS,C deberías mirar esto:

http://www.todopic.com.ar/foros/index.php?topic=14812.msg91151#msg91151

perl y perh están funcionando como un registro de 16 bits(es decir, cada uno aporta 8 bits. perl los 8 mas bajos, perh los 8 mas altos).
Si te fijas, lo que hacen las rlf ahí es multiplicar el registro entero(perh perl) por 2.

Con respeto a lo otro, no sé qué querés hacer. ¿0,06? ¿De dónde sale eso? ¿De 60s/100? Tal vez si explicaras lo que estás haciendo y un poco mas globalmente lo que necesitás nos ubicaríamos más fácil.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #23 en: 08 de Marzo de 2007, 06:39:11 »
Hola Bruno,

bcf 3,0 pone a 0 el bit status para que sea *2 exactamente y luego con el rlf rota hacia la izquierda y *2, muy buen post!! está muy bien explicado gracias!!!.
Yo lo que quiero es multiplicar por 6. Asi que si lo pongo 2 veces estaré multiplicando *4, y si pongo otro más ya sería 8, como podría hacerlo por 6?. Yo suponia que se puede hacer repitiendo el rlf, pero no se si habría una forma más rápida de hacer esto en menos líneas...

La idea es simple, es querer hacer un retardo fijo, mirando el valor del contador total perl y perh, multiplicando por un valor fijo, con lo cual, sea cual sea el valor del contador en relacion a grados sería siempre el mismo retardo. Si en 360º tarda X tiempo (valor de contadores), para 20º menos, 21.6º/360º= 0.06. Asi que es multiplicar 0,06 * el valor del contador.
Se saca de tiempo en hacer la interaccion 1us (4 instrucciones de reloj* us en hacer una instruccion, 4*0.25=1).
1*k*valor contador/incremento contador (100us). Así 1/100*k*valor contador. 0,001*k*contador.
k=6, 0,006*contador. Ya tendría ese valor, solo me hace falta multiplicar *6 para que haga ese retardo fijo, siempre a los mismos grados será, sea cual sea el valor del contador... Espero que ahora me entiendas.

Asi que supongo que poniendo:

fixed35              bcf    03,0
                        rlf    perl,F           ;
                        rlf    perh,F          ; *2
                        rlf    perl,F           ;
                        rlf    perh,F          ;*4
                        rlf    perl,F           ;
                        rlf    perh,F          ;*8

                        incf    perl,F          ; Less than 3509 rpm
                        incf    perh,F
bucle2                  nop
                        decfsz  perl,F
                        goto    bucle2
                        decfsz  perh,F
                        goto    bucle2

El problema es que yo quiero *6, y no se si hay alguna forma de hacerlo en menos intrucciones. *4 retardaría 14.4º, y *8 retardaría (0.01*8)*360= 28.8º demasiados.
Ahora me quedó muy claro como funciona el rlf, y no sabia que bcf 03,0 era referente a status,C

Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #24 en: 08 de Marzo de 2007, 12:24:01 »
El problema es que yo quiero *6, y no se si hay alguna forma de hacerlo en menos intrucciones. *4 retardaría 14.4º, y *8 retardaría (0.01*8)*360= 28.8º demasiados.

¿Menos instrucciones?

Para multiplicar por 6, lo mas simple es recurrir a registros temporales para almacenar el dato.
Podemos decir que: registro*6 = (registro+registro)*3=(registro+registro+registro)*2=registro*2+registro*4

Como "no sé" multiplicar fácilmente ni por 6 ni por 3, me quedo con alguna de las 2 últimas igualdades porque sé sumar y multiplicar por 2. Finalmente selecciono la última porque es más rápido multiplicar por 2 a un registro que sumarlo a si mísmo.

Entonces podemos hacer asi:

                        bcf         STATUS,C  ;registro * 2
                        rlf          perl,F
                        rlf          perh,F

                        movf     perl,W        ;guardo entonces registro * 2 temporalmente
                        movwf   Templ
                        movf     perh,W
                        movwf   Temph

                        bcf        STATUS,C ;registro * 4
                        rlf         perl,F
                        rlf         perh,F               
                         
                        movf     Templ,W ;registro * 2 + registro * 4
                        addwf    perl,F
                        btfsc      STATUS,C
                        incf        perh,F
                        movf      Temph,W
                        addwf     perh,F

El problema con esta rutinaes que arrastra un error LINEAL por tardar más tiempo en calcular el valor del registro.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #25 en: 08 de Marzo de 2007, 19:27:13 »
Hola Bruno,

Gracias por el consejo, he estado pensando con estos consejos y creo que la mejor forma es hacer esto.
Añado dos nop al loop the retardo, con lo cual cada interacción serían 6 instrucciones, 6*0,25 = 1,5/100 *k(k=4) = 0,06.
Asi quedaría:

fixed35              bcf    03,0
                        rlf    perl,F           ;
                        rlf    perh,F          ; *2
                        rlf    perl,F           ;
                        rlf    perh,F          ;*4
                        incf    perl,F         ; Less than 3509 rpm
                        incf    perh,F
bucle2               nop
                        nop
                        nop
                        decfsz  perl,F
                        goto    bucle2
                        decfsz  perh,F
                        goto    bucle2

Referente al error lineal, podría contar el número de instrucciones que pasan desde que salta el loop the conteo, y restarle al valor final, que te parece?.

Gracias, un saludo.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #26 en: 08 de Marzo de 2007, 19:42:27 »
Hola

Ojo que cuando haces dos rotaciones seguidas, antes de cada rotacion debes asegurarte que STATUS,C valga 0 para que no "ensucie" la multiplicacion!.

fixed35              bcf    03,0
                        rlf    perl,F           ;
                        rlf    perh,F          ; *2
                         bcf    03,0
                        rlf    perl,F           ;
                        rlf    perh,F          ;*4

Es la unica forma de garantizar que la multiplicacion sea por 2 exacto.
Me parece bien la idea, pero no entiendo como pensas lograr "restarselo al valor final".

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #27 en: 09 de Marzo de 2007, 13:31:01 »
Bruno,

Si, tienes razón, faltaba limpiar el status, para asegurarnos que al girarlo no sea multiplicado por 2 perfectamente.
Referente al ajuste del error lineal, tienes toda la razón, no es posible, pero realmente he estado viendo el error máximo y es totalmente aceptable, asi que no hay problema.

Ahora estoy liado con las tablas. Y hay un problema. He estado leyendo de como usar el PCL y el PCLATH. Y más o menos lo entiendo, pero hay un problemilla. Ahora los valores que voy a usar no me caben en 1byte, necesitan ser de 2bytes, ya que podrian ser valores del orden de 1500 o 2000. Son 136 lineas cada tabla. Espero que me puedas decir, como hacerlo más o menos, con valores asi, no he visto nada.

En mi codigo, cargo la posición de la tabla en el toffset, llamo por un goto a la tabla, coge el valor de la posicion y lo paso a una variable. Este codigo funcionaba bien en f84A, ahora con el f88 y más crystal, con todos los ajustes ya no me cabe en un byte. Antes era así.

movwf   toffset          ; store offset
.
.
goto      igno

ign0      call    ignition0               ; read from table 0
.
.
ORG     0x100                            ; This table is locate in code page 1!!!!
ignition0                      ; Used as address lable to look-up table
    movlw   HIGH ignition0           ; This table is in Page 1
    movwf   PCLATH                    ; of the memory so set latch!
    movfw   toffset                       ; Get table offset, max 212
    addwf   PCL,F                    ; Add offset to PCL to jump into table
    RETLW   0x4B      ; 75 
    RETLW   0x4C      ; 76 
    RETLW   0x4D      ; 77
    RETLW   0x4F      ; 79
    RETLW   0x50      ; 80 
    RETLW   0x51      ; 81 
    RETLW   0x51      ; 81 
    RETLW   0x51      ; 81 
    RETLW   0x51      ; 81 
    RETLW   0x4F      ; 79 
    RETLW   0x4D      ; 77 
    RETLW   0x4A      ; 74 
    RETLW   0x47      ; 71 

Si sabes algun ejemplo o algun link donde expliquen de hacerlo para valores que ocupen 2bytes.
Gracias.

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #28 en: 13 de Marzo de 2007, 19:46:15 »
¿Cuando hablas de valores que ocupan 1 byte o 2, te refieres a que la tabla tendrá más de 1000 valores o a que los valores de la tabla debieran ser números de 2 bytes?

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Ayuda con interrupcion para el timer1!!.
« Respuesta #29 en: 14 de Marzo de 2007, 18:27:20 »
Mauricio,

Ya lo solventé. Eran tablas de 136 valores.  Y los valores pues llegan hasta D'2000' más o menos. Lo que he hecho es usar 2 tablas una con valorL y otra con valorH. Así que ahora uso el mismo offset para ver el valor en cada parte del low y high...

El problema que tengo es que al fijar el PR2 hasta 100. Y usar 2 variables en una interrupcion para tener un contador de 16bits con incrementos de 100us, cuando el programa entra en el loop de retardo( el programa usa el contador para sacar la freq de los pulsos y segun el contador entra en una tabla, coge el valor y retarda ese valor), pues al entrar en el loop the retardar el valor de la tabla, pues usando decfsz, drececiendo el valor hasta 0, pues si el valor es de 1000, pues habrá por lo menos 9 interrupciones, en las cuales se gastan 4us, y claro cuando vuelve al loop de retardo, pues en realidad  retarda esos 1000 + el valor gastado por la interrupcion. ASi que esto es bastante jodido de cuadrar...

Lo unico que se me ocurre es usar un contador para hacer el retardo, ya que es independiente uno del otro, si sabeis otra forma de poder hacerlo ya me contais.

Gracias por la ayuda.


 

anything