TODOPIC
Microcontroladores PIC => Programadores => Mensaje iniciado por: Ipanemag 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.!
-
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?
-
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.)
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:
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:
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...