Autor Tema: Ayuda con con lenguaje ensamblador y pic16F684  (Leído 3639 veces)

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

Desconectado Ipanemag

  • PIC10
  • *
  • Mensajes: 1
Ayuda con con lenguaje ensamblador y pic16F684
« en: 21 de Junio de 2011, 12:23:58 »
Hola,

 Es la primera vez que posteo en el foro espero que alguien pueda ayudarme a resolver mi duda, resulta que tengo q convertir un codigo que esta en ensamblador a lenguaje C , estoy trabajando con el PIC 16F684 en un modulo de RF usandolo a èste (16F684) como el receptor y al (rf12f675) como transmisor. Se me ha complicado esta parte del codigo en el receiver  :

;----------------------------------------------------------------------
; Subroutine: TIMER
;   
; Description: Continually updates two higher order timers (SX1TMR and
;   SX2TMR) for use in LED timing.
;   
; Constants: none
;   
; Global Variables: SX1TMR, SX2TMR
;   
; Initialization: none
;   
; Output: SX1TMR, SX2TMR
;   
;----------------------------------------------------------------------

TIMER
        btfss   TOGFLG              ; TOGGLE forces this routine to spend
         goto   TIMER1              ;   1/2 of TMR0 in TIMER and 1/2 in TIMER1.

        movlw   B'01111111'
        addwf   TMR0, W             ; TOGGLE toggles back and forth to a   
        btfss   STATUS, C           ;    one the rate TMR0 overflows.
         retlw  0                   ; TMR0 overflow ~= 1ms (2^8*4us)

        bcf     TOGFLG
        incfsz  SX1TMR, F           ; SX1TMR resolution ~= 1ms
         retlw  0                   ; SX1TMR overflow ~= 0.25sec (2^8*1ms)

        incf    SX2TMR, F           ; SX2TMR resolution ~= 0.25sec
        retlw   0                   ; SX2TMR overflw ~= 1min (2^8*0.23sec) 

TIMER1
        movlw   B'01111111'         ; Timer routine spends half its time
        addwf   TMR0, W             ;   in TIMER1 waiting to set TOGGLE
        btfsc   STATUS, C           ;   to one again
         retlw  0

        bsf     TOGFLG
        retlw   0

Quisiera saber si esta rutina es solamente un delay en codigo C o hace algo mas , còmo podria poner en codigo C algo como esto. Les agradezco.!


Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: Ayuda con con lenguaje ensamblador y pic16F684
« Respuesta #1 en: 22 de Junio de 2011, 19:28:36 »
Hola, no es una simple demora, ya que, como el programa es solo una parte, supongo que hace un llamado desde el programa, y segun el valor que toma el TMR0, setea TOGFLG para producir un toggle... esto es solo por "comparacion" del timer cero, sin aplicar ninguna interrupcion, ni cambio de valor en el timer...  y aparentemente es para producir un "destello" en algun led, pero sin dejar de atender otras partes del programa...
Si colocas una "demora" simplemente... no atenderia otras partes del programa mientras esta "ocupado" perdiendo el tiempo...  ;-)

Saludos!
Norberto

pd? por que pasar a C si ya esta funcionando en asm?
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Ayuda con con lenguaje ensamblador y pic16F684
« Respuesta #2 en: 22 de Julio de 2011, 05:34:47 »
Ademas ASM es mas rapido ^^. lo que no recuerdo es si el 16F84 tiene interrupciones :S,, por que no le veo sentido usar una suma,, para saber cuando el timer supero el valor 0x80.. y luego si usar un solo contador si es que da el tiempo y sino anidarlo asi como lo hace el programa.. Lo veo facil, pero hubiera preferido una interrupcion xD. Otra cosa que me llama la antencion, y que lo pongo aca es: ¿Cuando pone a 0 el TMR0? (Respuesta abajo.)


Citar
TIMER
        btfss   TOGFLG              ; TOGFLG esta en 1 ? , si esta en 1 salto
         goto   TIMER1              ;   Si esta en cero me voy a TIMER1

        movlw   B'01111111'     ; Pongo el valor 0x7F en W0
        addwf   TMR0, W             ; hago la suma W0 = TMR0 + W0
        btfss   STATUS, C           ;  La suma supero los 8 bits ? es decir TMR0 es mayor a 0x80 entonces salto. O en tiempo  (2^8*4us) donde 2^8 es la cantidad de combinaciones con 8 bits y 4us es la frecuencia de la CPU
         retlw  0                   ; Si no supero el valor vuelvo al programa principal desde donde se llamo a esta seccion

        bcf     TOGFLG          ; Si supero el valor, pongo a 0 TOGFLG
        incfsz  SX1TMR, F     ; SX1TMR resolution ~= 1ms e incremento --- O sea incremento hasta que llegue al valor 0xFF, al incrementar una vez mas pasa a 0x00, mientras que no sea 0 salta
         retlw  0                   ; SX1TMR overflow ~= 0.25sec (2^8*1ms) ---- Aca vuelve al programa principal desde donde se llamo a esta seccion. Cuando se cumple que llega a 0 el valor de SX1TMR, han pasado aproximadamente 0.25 segundos

        incf    SX2TMR, F           ; SX2TMR resolution ~= 0.25sec -- Pero como hago para ahcer una demora mas grande?, y bueno, cada vez que llegue a 0 SX1TMR pasan 0.25 seg, entonces aca cuento cuantas veces paso por 0
        retlw   0                   ; SX2TMR overflw ~= 1min (2^8*0.23sec) -- Cuando este segundo registro llegue a 0 quiere decir que se cumplieron 2^8 veces el tiempo 0.25 seg y vuelve al programa principal como en los demas casos

TIMER1 -- El llegar aca me dice que es la primera vez que se llama la funcion, por lo cual TOGFLC esta en 0, o que ya el temporizador supero el valor 0x80, esta parte me asegura que solo se ejecute el incremento de los registros de arriba
               -- solo si el TMR0 tiene el valor esperado, sino mientras vuelve al programa principal.
        movlw   B'01111111'         ; Timer routine spends half its time
        addwf   TMR0, W             ;   in TIMER1 waiting to set TOGGLE
        btfsc   STATUS, C           ;   to one again
         retlw  0

        bsf     TOGFLG      -- En caso de no superarse el valor, esta bandera indica que es momento de  incrementar el valor de SX1TMR y/o SX2TMR, dependiendo de los valores de los mismos. Y vuelvo al programa nuevamente
        retlw   0

Bueno por lo visto no pone a 0 el TMR0, y lo unico que hace es que entre a sumar los registros solamente cuando el TMR0 tenga el valor 0x81, de ahi se pone a cero el TOGFLG y empieza a entrar en TIMER1 hasta que llegue a 0x00. donde se setea el bit TOGFLG y empieza a preguntarse en TIMER si llego al valor. y de vuelta el ciclo completo.
TOGFLG (intento de traducir TOGGLE FLAG supongo)
Bue eran las 5.30am cuando lo vi xD,, no se puede pedir mucho de mi a ese horario xD

P.D: Ahora que lo pienso un poco mejor, que enriedo que se pego el programador ese xD, podria haber hecho directamente una resta y listo,, sin tantos saltos xD, O sea asi:

Citar
TIMER
        movlw   B'10000000'     ; Valor 0x80 en W0
        subwf   TMR0, W           ; resto W0 = TMR0 - W0
        btfss   STATUS, Z          ; Si es igual, tengo cero de resultado en W0 y logro que la bandera Z se active
        retlw  0                        ; Si no es igual vuelvo

        incfsz  SX1TMR, F     ; Incremento el primer registro
        retlw  0                    ; hasta que no llegue a 0 nuevamente vuelvo

        incf    SX2TMR, F      ; Incremento segundo registro cuando el primero ya completo toda una vuelta
        retlw   0                   ; Y vuelvo

Pasado a C, con mi mal C por que NO SE xD, seria algo asi para q te des una idea:

Citar

TIMER(void)   --- Si es que se escribe asi xD

if ( TMR0 == 0x80)
{
      SX1TMR++;
      if (SX1TMR == 0x00)
            {
            SX2TMR++;
            }
}
Return(0);  --- Y esto igual xD je

E incluso podria ahi haber seteado los leds xD je , Asi en la otra parte del programa no tenia q estar fijandose cuando se pone a 0.. bueno espero tu respuesta.. aunque creo que no lo vas a tocar xD

Espero que de algo te sirva...
« Última modificación: 22 de Julio de 2011, 23:37:21 por KILLERJC »