Autor Tema: Call y PCL  (Leído 10945 veces)

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

Desconectado diazpd

  • PIC10
  • *
  • Mensajes: 13
Call y PCL
« en: 12 de Julio de 2009, 18:32:39 »
  :) Hola gente ! realmente soy nuevo en esto de los pics y estoy renegando con un " simple " programita que enciende leds en forma secuencial con un pic16f84a ...

La cuestion es que no puedo entender el tema del CALL y el bendito PC ( ya he leido en el foro http://www.todopic.com.ar/foros/index.php?topic=23623.0 ... y sigo sin entender , perdon pero soy muy cabeza dura , y no lo logro " VER " :( ... )

en el siguiente codigo me trabo en  las partes que estan en negrita ( no entiendo que hace )
bueno allá va y GRACIAS por la ayuda por adelantado  :-/

list     p=16f84a 
#include  p16f84a.inc

;se determinan los bits del registro de configuracion
__config _HS_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF

Cuenta EQU 0x0C
Led    EQU 0x0D
 
ORG 0

goto  inicio

ORG 5

inicio

    bsf  STATUS, 0x5   ;selecciono el banco de memoria 1

    movlw B'11000011'  ;se eligen los pines de los led como
    movwf TRISB        ;...salidas el resto como entrada 

    movlw B'00000111'  ;asigno clock interno y preescala 256
    movwf OPTION_REG
   
    bcf STATUS, 0x5    ;elijo banco de memoria 1
 
    movlw .16
    movwf Cuenta
    movlw .6
    movwf TMR0         ;timer en valor 6
    bcf INTCON, T0IF   ;se borra la bandera del timer0
    movwf B'00111100'  ;se inicializa el puerto B -leds apagados-
    movwf PORTB

   
bucle

 
    btfss INTCON, T0IF ;espera hasta que se produsca el overflow del timer0
    goto bucle

    bcf INTCON, T0IF   ;limpia la bandera del overflow
    movlw .6
    movwf TMR0         ;recarga el timer
    decfsz Cuenta,F    ;comprueba si la variable Cuenta llego a cero
    goto bucle

   
   movlw  .16     ;recarga la variable Cuenta
   movwf Cuenta
   decfsz Led,F   ;determina que led activar  ???
   goto _Cont   
   movlw .4       ;recarga la variable Led
   movwf Led   
   

_Cont
   
   movlw .1       ???
   call TablaLed   ;recurre a la tabla para activar el led deseado
   movwf PORTB
   goto bucle

TablaLed       
     
  subwf  Led,W      ??
  addwf  PCL          ??
  retlw  B'00110100' ;Led 3
  retlw  B'00111000' ;Led 2
  retlw  B'00101100' ;Led 5
  retlw  B'00011100' ;Led 4

end

Desconectado juan47

  • PIC10
  • *
  • Mensajes: 27
Re: Call y PCL
« Respuesta #1 en: 13 de Julio de 2009, 12:17:40 »
Hola a todos:
Yo tambien soy nuevo en el manejo de PIC y del lenguaje en ensamblador.
Es la primera vez que escribo en el foro,con lo que pido perdon de antemano y no deseo molestar a nadie.

La instruccion DECFSZ  yo no te  sabria esplicar ,pues soy bastante novato en este evento ,pero en esta misma web en la pagina de inicio
apartado apuntes estan las instrucciones en assambler que son bastante orientativas ,aunque para mi que soy un poco obtuso no
me saque de muchas dudas al no saber como emplearlas correctamente.
Sin mas intormision en el asunto y esperando que algun amable compañero que sepa mas en estos quehaceres se despide con
todo respeto:
juan47




« Última modificación: 13 de Julio de 2009, 15:50:27 por juan47 »

Desconectado jim_17

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 309
    • Blog personal
Re: Call y PCL
« Respuesta #2 en: 13 de Julio de 2009, 13:59:58 »
Yo también soy un poco novato en esto del lenguaje ensamblador pero creo que te voy a poder ayudar, si me equivoco por favor que me corrija algun miembro del foro que entienda más que yo (que hay muchos).

1. decfsz Led,F
Esta operación hace un decremento de la variable LED, y lo guarda en el mismo registro. Date cuenta que al principio de todo la variable LED esta inicializada con un 0, ya que no le damos valor al principio. Entonces decfsz, lo podemos traducir por Decremento Registro y Salta siguiente instrucción si es 0. Entonces tal y como esta puesto, con esta instrucción lo que hacemos es seleccionar el numero que queremos encender.

2. movlw .1
Esta operación añade el numero 1 (en decimal) al registro de trabajo W. Para indicar que es un numero decimal ponemos un punto seguido del numero.

3. subwf  Led,W

Hacemos la operacion LED - W y el resultado de la operación la guardamos en W.

4. addwf  PCL
Supongamos que en LED tengamos el valor 4. Entonces hacemos LED - W (w tenia cargado el valor 1) y el resultado lo guardamos en W, (4-1=3) W=3. Entonces ejecutamos addwf PCL, PCL es un registro que apunta a la siguiente linea de código que estamos ejecutando. La explicación es un poco liosa, por eso vamos a verlo con un ejemplo.

(Registro LED cargado con el numero 4, registro W cargado con el valor 1)

1.   subwf  Led,W      ;(W=4-1, W=3)
2.  addwf  PCL          ; En el momento de ejecutar la instrucción pcl esta apuntando a la dirección 3, si le sumamos 3+3, PCL apuntará a la dirección 6 y
3.  retlw  B'00110100' ; ejecutara esta parte de código retlw  B'00011100' que nos retornará el valor 00011100 (en binario) al registro de trabajo W
4.  retlw  B'00111000' ;
5.  retlw  B'00101100' ;
6.  retlw  B'00011100' ;



Salu2 y espero que se haya entendido un poco.
Share the world !

Blog's

http://www.area0x33.com

Desconectado diazpd

  • PIC10
  • *
  • Mensajes: 13
Re: Call y PCL
« Respuesta #3 en: 18 de Julio de 2009, 20:47:22 »
ok ! gracias a TODOS !! , con el SIMULADOR del MPLAB pude ver donde estaba el problema   :-/
Faltaba cargar la variable LED antes de decrementarla ! les dejo una copia del codigo corregido


inicio

    bsf  STATUS, 0x5   ;selecciono el banco de memoria 1

    movlw B'11000011'  ;se eligen los pines de los led como
    movwf TRISB        ;...salidas el resto como entrada 

    movlw B'00000111'  ;asigno clock interno y preescala a TMR0 en 256
    movwf OPTION_REG
   
    bcf STATUS, 0x5    ;elijo banco de memoria 0
 
    movlw .16
    movwf Cuenta
    movlw .6
    movwf TMR0         ;timer en valor 6
    movlw .4           ;carga la variable Led
    movwf Led
    bcf INTCON, T0IF   ;se borra la bandera del timer0
    movlw B'00111100'  ;se inicializa el puerto B -leds apagados-
    movwf PORTB

   
bucle

 
    btfss INTCON, T0IF ;espera hasta que se produsca el overflow del timer0
    goto bucle

    bcf INTCON, T0IF   ;limpia la bandera del overflow
    movlw .6           ;recargo el timer
    movwf TMR0         ;recargo el timer
    decfsz Cuenta,F    ;comprueba si la variable Cuenta llego a cero
    goto bucle

   
   movlw  .16     ;recarga la variable Cuenta
   movwf Cuenta
   decfsz Led,F   ;determina que led activar
   goto _Cont   
   movlw .4       ;recarga la variable Led
   movwf Led   
   

_Cont
   
   movlw .1        ;registro W=1
   call TablaLed   ;recurre a la tabla para activar el led deseado
   movwf PORTB
   goto bucle

TablaLed         
     
  subwf  Led,W          ;registro W=1
  addwf  PCL             ;sumo W + PCL ( y salta el CP segun resultado de cuenta  )
  retlw  B'00110100'  ;enciende Led 3
  retlw  B'00111000'  ;enciende Led 2
  retlw  B'00101100'  ;enciende Led 5
  retlw  B'00011100'  ;enciende Led 4

end