Usando Macros

March 18, 2008 at 5:23 pm | In HowTo, Tutorial | 9 Comments

El uso de subrutinas lo vimos por primera vez en el tutorial Encendiendo y apagando LED’s… ahora con retardo! Ahí se vio la manera en la que se llama y se regresa de las subrutinas. También se dijo que el empleo de subrutinas hacía el código más entendible, otra forma de hacer el código entendible es mediante el uso de Macros.

Las macros son de alguna forma similares a las subrutinas ya que son conjuntos de intrucciones que se ejecutan de manera secuencial mediante una llamada a una orden de ejecución, sin embargo tiene diferencias muy significativas. Mientras que una subrutina aparece una sola vez en el código, cada vez que se “invoca” una macro se inserta el código de esta en el programa. Otra diferencia es que a una macro se le pueden especificar parámetros de entrada y a una subrutina no.

Una macro se define con la directiva macro especificando el nombre de la macro y los parámetros de entrada, si existieran, de la siguiente manera:
nombre_macro macro par1, par2,...
instrucción
instrucción
...

             endm

En el programa la definición de la macro debe aparecer antes de la línea en la que se llama la macro. Cuanto mientras se ejecuta el programa se encuentra una macro esta es reemplazada por el conjunto de instrucciones que aparecen en la definición de la macro. Una manera de asegurar eso es escribiendo las macros en un archivo include (.INC) y llamando a este include al momento de llamar el include de las definiciones del micro.

Las macros pueden ahorrar mucho tiempo de escritura ya que si hay partes del código que se repiten mucho se pueden escribir en una macro y ese código se insertaría de manera automática al llamar la macro. Veamos esto con un ejemplo. Los cambios de banco pueden ser muy repetitivos asi que si se quiere cambiar de banco se podrían definir unas macros de la siguiente manera:

banco0 macro             ; Definición de macro banco0
       bcf    STATUS,RP0 ; Bit RP0=0 = Banco 0
       endm              ; Termina definición de macro

banco1 macro             ; Definición de macro banco1
       bsf    STATUS,RP0 ; Bit RP0=1 = Banco 1
       endm             
; Termina definición de macro

Así si en el programa aparece el macro banco1 este será sustituido por el código bcf STATUS,RP0.

Con ese ejemplo tal vez no queda muy claro la ventaja de usar una macro ya que la macro solo contiene una instrucción y no utiliza parámetros, pero ahora que definimos esos macros definamos otro que designe un bit de un puerto como salida:

SALIDA macro    par1, par2 ; Definición de macro
       banco1              ; Macro para cambiar al banco 1
       bcf      par1, par2 ; Bit dado como salida
       banco0              ; Macro para cambiar al banco 0
       endm               
; Termina definición de macro

Para utilizar ese macro que contiene parámetros simplemente se llama de la siguiente manera:

       SALIDA   TRISA,3

Al llamara esa macro el primer parámetro dado TRISA toma el lugar de par1 mientras que el parámetro 3, el lugar de par2 generando el siguiente código:

    bsf STATUS,RP0 ; RP0 = 1 = Banco 1
    bcf TRISA,3    ; Bit 3 de Puerto A como entrada
    bcf STATUS,RP0 ; RP0 = 0 = Banco 0

Como se puede ver las macros hacen muy la escritura del código y al poder manejar parámetros proveen un medio para simplificar muchas operaciones.

Utilizando esos macros supongamos que realizamos un programa que ponga el alto el valor del bit 3 del puerto B. El código completo del programa sería:

    list    p=16f628a
    include p16f628a.inc
    include macros.inc ; Archivo con la definición de las macros

    org 0x00
    goto INICIO

    org 0x05
INICIO
    SALIDA  TRISB,3 ; Llamada a macro salida
    bsf     PORTB,3 ; Bit 3 del puerto B en alto

    goto    $       ; Ciclo infinito

    end

El programa principal es muy sencillo y legible. El archivo macros.inc donde se definen las macros quedaría así:

banco0 macro             ; Definición de macro banco0
       bcf    STATUS,RP0 ; Bit RP0=0 = Banco 0
       endm              ; Termina definición de macro

banco1 macro             ; Definición de macro banco1
       bsf    STATUS,RP0 ; Bit RP0=1 = Banco 1
       endm
             ; Termina definición de macro

SALIDA macro  par1, par2 ; Definición de macro SALIDA
       banco1            ; Llamada a macro banco1
       bcf    par1, par2 ; Bit dado como salida
       banco0            ; Llamada a macro banco0
       endm              ; Termina definición de macro

Teniendo en cuenta las dos diferencias mencionadas podemos entonces preguntarnos ¿son mejores las macros o las subrutinas?. La respuesta final la debe dar cada quien ya que dependiendo del caso se debería usar una o la otra.

Más información sobre macros se puede encontrar en el quinto capítulo de PIC microcontrollers, for beginners too, de Nebojsa Matic.

9 Comments »

RSS feed for comments on this post. TrackBack URI

  1. Hola desde Matamoros Tam., Mx.

    Permiteme falicitarte y agradecerte por tu blog, es mi primer dia en programacion de microcontroladores y ya termine los que me habian “encargado”. Soy programador de software pero siempre tuve curiosidad por los micros. Gracias de nuevo y seguire por aqui.

    Saludos

  2. Hola Marcos, gracias por tu comentario, me da gusto que te haya servido este blog.

  3. Saludos desde Guatemala! interesante las notas que tienen asi dan ganas de seguir aprendiendo sigan asi!
    ojala sigan con mas notas de assembler y haber cuando sacan algo de picbasic pro, pero por el momento tienen muchas cosas interesantes.

    saludos.

  4. Somehow i missed the point. Probably lost in translation :) Anyway … nice blog to visit.

    cheers, Fitfully.

  5. lo primero es decirte gracias por todo, es impresionante lo facil y bien esplicados que estan los temas. Para las personas como yo , que estamos empezando con los pics, esto es fabuloso. Ahora me gustaria que subieras algun trabajo sobre el USAR del 16F628a quiero comunicarme con un PC y no lo eh conseguido desde ya muchas gracias saludos desde uruguay

  6. Man eres un duro en assembler, te felicito un mundo. tengo un proyecto que me mando la universidad y no tengo idea de que hacer ni de cómo empezar es realizar un juego que se llama juego de la vida, por fa mándame tu email para mandarte las especificaciones del juego para que así me orientes, claro si cuentas con el tiempo, gracias

  7. ahh el pic que debo utilizar el el 16f877

  8. jeje se nota mi impericia en esto el pic bueh ya lo conocen el 16f877 de 40 paticas.
    Si necesitas o necesitan alguna otra especificación o si alguien aparte de micropic esta dispuesto a ayudarme por fa sabre agradecerles pmccollins@gmail.com

  9. Hola de nuevo, después de leer cuanto tutorial se me cruzara en la vida y al ver que nadie en el foro me pudo ayudar pues…..bueh pude resolver, aquí está el código si se animan léanlo y aporte como se pudiera mejorar…

    el codigo

    LIST P=16F877
    INCLUDE

    interruptor EQU 0×20

    contador_ledon EQU 0×21

    auxB EQU 0×23

    auxC EQU 0×25

    auxD EQU 0×26

    CONF_ADCON1 equ b’00000110′ ; valor para la configuracion PORTA E/S digital

    aux EQU 0×27

    CBLOCK 0×28
    R_ContA ; Contadores para los retardos.
    R_ContB
    R_ContC
    ENDC

    ORG 0×00

    GOTO INICIO

    ORG 0X05

    INICIO:

    bsf STATUS,RP0 ; Ir banco 1

    bcf STATUS,RP1

    movlw CONF_ADCON1 ; {Configurar el PORTA como digital

    movwf ADCON1 ;}

    CLRF TRISB ; PUERTOB SALIDA

    CLRF TRISC ; PUERTOC SALIDA

    CLRF TRISD ; PUERTOD SALIDA

    movlw b’000001′ ;{RA entrada
    movwf TRISA ;}

    bcf STATUS,RP0 ; Ir banco 0

    clrf PORTA
    clrf PORTB
    clrf PORTC
    clrf PORTD

    switch ;verifico el estado del interuptor

    movf PORTA,w ; garga w con el contenido del puerto A

    movwf interruptor ;

    xorlw b’00000000′ ;evalúo que conjunto de generación esta activo

    BTFSS STATUS,2 ; si el bit de status esta en cero brinco mustra el grupo B sino, muestra el A

    goto generacion_1B
    goto generacion_1A

    generacion_1A

    clrf PORTB ; limpio los puertos que

    clrf PORTC ; seran utilizado como

    clrf PORTD ; salida

    bsf PORTB,0 ; Enciendo cada Led agregándole un 1 lógico al bit 0 del puerto B

    bsf PORTB,3 ; un 1 lógico al bit 3 del puertoB

    bsf PORTD,3 ; un 1 lógico al bit 3 del puertoD

    ;++++++++ verifica si se cambia de estado del inteuptor +++++++++++++
    movf PORTA,w

    xorwf interruptor

    btfss STATUS,2 ; ++++ si el estado cambio llama al otro grupo de organismo ++++
    ; ++++ sino, se toma unos segundos encendido antes de cambiar a su estado futuro ++++

    goto generacion_1B ; ++++ no me interesa que retorne a la siguiente línea +++++

    call busy_waiting ; espera 5 segundos antesde cambiar

    goto generacion_2A

    generacion_2A

    clrf PORTB ; limpio los puertos que

    clrf PORTC ; seran utilizado como

    clrf PORTD ; salida

    bsf PORTB,0 ; Enciendo cada Led agregándole un 1 lógico al bit 0 del puerto B

    bsf PORTB,3 ; un 1 lógico al bit 3 del puertoB

    bsf PORTC,0 ; un 1 lógico al bit 0 del puertoc

    bsf PORTC,3 ; un 1 lógico al bit 3 del puertoc

    bsf PORTD,0 ; un 1 lógico al bit 0 del puertoD

    bsf PORTD,3 ; un 1 lógico al bit 3 del puertoD

    movf PORTA,w

    xorwf interruptor

    btfss STATUS,2 ; ++++ si el estado cambio llama al otro grupo de organismo ++++
    ; ++++ sino se toma unos segundos encendido antes de cambiar a su estado futuro ++++

    goto generacion_1B ; ++++ no me interesa que retorne a la siguiente línea +++++

    call busy_waiting ; espera 5 segundos antesde cambiar

    goto generacion_3A

    generacion_3A

    clrf PORTB ; limpio los puertos que

    clrf PORTC ; seran utilizado como

    clrf PORTD ; salida

    bsf PORTB,1 ; Enciendo cada Led agregándole un 1 lógico al bit 0 del puerto B

    bsf PORTB,2 ; un 1 lógico al bit 3 del puertoB

    bsf PORTC,1 ; un 1 lógico al bit 0 del puertoc

    bsf PORTC,2 ; un 1 lógico al bit 3 del puertoc

    bsf PORTD,1 ; un 1 lógico al bit 0 del puertoD

    bsf PORTD,2 ; un 1 lógico al bit 3 del puertoD

    movf PORTA,w

    xorwf interruptor

    btfss STATUS,2 ; ++++ si el estado cambio llama al otro grupo de organismo ++++
    ; ++++ sino se toma unos segundos encendido antes de cambiar a su estado futuro ++++
    goto generacion_1B ; ++++ no me interesa que retorne a la siguiente línea +++++

    call busy_waiting ; espera 5 segundos antesde cambiar

    goto generacion_2A

    generacion_1B

    clrf PORTB ; limpio los puertos que

    clrf PORTC ; seran utilizado como

    clrf PORTD ; salida

    bsf PORTC,0 ; un 1 lógico al bit 0 del puertoc

    bsf PORTC,1 ; un 1 lógico al bit 3 del puertoc

    bsf PORTD,0 ; un 1 lógico al bit 0 del puertoD

    movf PORTA,w

    subwf interruptor

    btfss STATUS,2 ; ++++ si el estado cambio llama al otro grupo de organismo ++++
    ; ++++ sino se toma unos segundos encendido antes de cambiar a su estado futuro ++++
    goto generacion_1A ; ++++ no me interesa que retorne a la siguiente línea +++++

    call busy_waiting ; espera 5 segundos antesde cambiar

    goto buscar_newgen

    ;+++++++++++++++++++++++chequeo vecinos del bit 0 del puerto D+++++++++++++++++++
    buscar_newgen

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon
    ;++++++++++++++++++++++++++++++fin chequeo +++++++++++++++++++++++

    ;+++++++++++++si el contador vale 2 deja el bit prendido++++++++
    movlw b’00000000′

    movwf auxD

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresD0 ;++++ ++++

    btfsc PORTD,0 ;+++creo q resuelvo el problema, bueh a dormir 3 horas y luego seguir, mi hallaca que me la guerden ++++++
    bsf auxD,0 ; ++++si contador vale 2 deja el led prendido++++

    goto bit1D

    tresD0
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroD0 ;++++ sino lo apaga ++++

    bsf auxD,0

    goto bit1D

    ceroD0

    bcf auxD,0
    goto bit1D

    bit1D ;+++++++++++++++++++++++chequeo vecinos del bit 1 del puerto D+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresD1 ;++++ ++++

    btfsc PORTD,1;++++ si hay un cero en el bit y el contador da 2 no hagas nada ve al otro, pero si hay un 1 en el bit mantenlo

    bsf auxD,1 ; ++++si contador vale 2 deja el led prendido++++

    goto bit2D

    tresD1
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroD1 ;++++ sino lo apaga ++++

    bsf auxD,1

    goto bit2D

    ceroD1

    bcf auxD,1
    goto bit2D

    bit2D ;+++++++++++++++++++++++chequeo vecinos del bit 2 del puerto D+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresD2 ;++++ ++++

    btfsc PORTD,2

    bsf auxD,2 ; ++++si contador vale 2 deja el led prendido++++

    goto bit3D

    tresD2
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroD2 ;++++ sino lo apaga ++++

    bsf auxD,2

    goto bit3D

    ceroD2

    bcf auxD,2
    goto bit3D

    bit3D ;+++++++++++++++++++++++chequeo vecinos del bit 3 del puerto D+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresD3 ;++++ ++++

    btfsc PORTD,3

    bsf auxD,3 ; ++++si contador vale 2 deja el led prendido++++

    goto PrtC ;++++verificar puerto C ++++

    tresD3
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroD3 ;++++ sino lo apaga ++++

    bsf auxD,3

    goto PrtC ;++++ verifica…

    ceroD3

    bcf auxD,3
    goto PrtC ;++++bueh verificar q pasa en los alrededores de cada bit en portC+++++

    PrtC ; +++ bueh a seguir buscando bit en 1 ++++

    movlw b’00000000′ ;+++++++++++++++++++++++ chequeo vecinos del bit 0 del puerto c +++++++++++++++++++

    movwf contador_ledon ; inicializo contador

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon
    ;++++++++++++++++++++++++++++++fin chequeo +++++++++++++++++++++++

    ;+++++++++++++si el contador vale 2 deja el bit prendido++++++++
    movlw b’00000000′

    movwf auxC

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresC0 ;++++ ++++

    btfsc PORTC,0

    bsf auxC,0 ; ++++si contador vale 2 deja el led prendido++++

    goto bit1C

    tresC0
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroC0 ;++++ sino lo apaga ++++

    bsf auxC,0

    goto bit1C

    ceroC0

    bcf auxC,0
    goto bit1C

    bit1C ;+++++++++++++++++++++++chequeo vecinos del bit 1 del puerto C+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresC1 ;++++ ++++

    btfsc PORTC,1

    bsf auxC,1 ; ++++si contador vale 2 deja el led prendido++++

    goto bit2C

    tresC1
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroC1 ;++++ sino lo apaga ++++

    bsf auxC,1

    goto bit2C

    ceroC1

    bcf auxC,1
    goto bit2C

    bit2C ;+++++++++++++++++++++++chequeo vecinos del bit 2 del puerto C+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    ;++++ igual fin chequeo++++

    ;+++ veo el resultado del contador para hacer las asiganciones +++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresC2 ;++++ ++++

    btfsc PORTC,2

    bsf auxC,2 ; ++++si contador vale 2 deja el led prendido++++

    goto bit3C

    tresC2
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroC2 ;++++ sino lo apaga ++++

    bsf auxC,2

    goto bit3C

    ceroC2

    bcf auxC,2
    goto bit3C

    bit3C ;+++++++++++++++++++++++chequeo vecinos del bit 3 del puerto D+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresC3 ;++++ ++++

    btfsc PORTC,3

    bsf auxC,3 ; ++++si contador vale 2 deja el led prendido++++

    goto PrtB ;++++verificar puerto C ++++

    tresC3
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroC3 ;++++ sino lo apaga ++++

    bsf auxC,3

    goto PrtB ;++++ verifica…. ++++

    ceroC3

    bcf auxC,3
    goto PrtB ;++++ sigh X-D aqui vamos otra vez verificar q pasa en los alrededores de cada bit en portB+++++

    PrtB; +++ aqui vamos de nuevo a seguir buscando bit en 1 ++++

    movlw b’00000000′ ;+++++++++++++++++++++++ chequeo vecinos del bit 0 del puerto c +++++++++++++++++++

    movwf contador_ledon ; inicializo contador

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon
    ;++++++++++++++++++++++++++++++fin chequeo +++++++++++++++++++++++

    ;+++++++++++++si el contador vale 2 deja el bit prendido++++++++
    movlw b’00000000′

    movwf auxB

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresB0 ;++++ ++++

    btfsc PORTB,0

    bsf auxB,0 ; ++++si contador vale 2 deja el led prendido++++

    goto bit1B

    tresB0
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroB0 ;++++ sino lo apaga ++++

    bsf auxB,0

    goto bit1B

    ceroB0

    bcf auxB,0
    goto bit1B

    bit1B ;+++++++++++++++++++++++chequeo vecinos del bit 1 del puerto C+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresB1 ;++++ ++++

    btfsc PORTB,1

    bsf auxB,1 ; ++++si contador vale 2 deja el led prendido++++

    goto bit2B

    tresB1
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroB1 ;++++ sino lo apaga ++++

    bsf auxB,1

    goto bit2B

    ceroB1

    bcf auxB,1
    goto bit2B

    bit2B ;+++++++++++++++++++++++chequeo vecinos del bit 2 del puerto C+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTD,1
    btfsc PORTD,1
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTB,1
    btfsc PORTB,1
    incf contador_ledon

    btfss PORTB,3
    btfsc PORTB,3
    incf contador_ledon

    btfss PORTC,1
    btfsc PORTC,1
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon

    ;++++ igual fin chequeo++++

    ;+++ veo el resultado del contador para hacer las asiganciones +++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresB2 ;++++ ++++

    btfsc PORTB,2

    bsf auxB,2 ; ++++si contador vale 2 deja el led prendido++++

    goto bit3B

    tresB2
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroB2 ;++++ sino lo apaga ++++

    bsf auxB,2

    goto bit3B

    ceroB2

    bcf auxB,2
    goto bit3B

    bit3B ;+++++++++++++++++++++++chequeo vecinos del bit 3 del puerto D+++++++++++++++++++

    movlw b’00000000′

    movwf contador_ledon ; inicializo contador

    btfss PORTD,0
    btfsc PORTD,0
    incf contador_ledon

    btfss PORTD,2
    btfsc PORTD,2
    incf contador_ledon

    btfss PORTD,3
    btfsc PORTD,3
    incf contador_ledon

    btfss PORTB,0
    btfsc PORTB,0
    incf contador_ledon

    btfss PORTB,2
    btfsc PORTB,2
    incf contador_ledon

    btfss PORTC,0
    btfsc PORTC,0
    incf contador_ledon

    btfss PORTC,2
    btfsc PORTC,2
    incf contador_ledon

    btfss PORTC,3
    btfsc PORTC,3
    incf contador_ledon

    ;++++ igual fin chequeo++++

    movf contador_ledon,w

    movwf aux

    movlw b’00000010′

    subwf aux,w

    btfss STATUS,2 ;++++si no da 2 ve cuanto vale contador++++

    goto tresB3 ;++++ ++++

    btfsc PORTB,3 ; igual reviso si es un 0 o un 1

    bsf auxB,3 ; ++++si contador vale 2 deja el led prendido++++

    goto newgen_B ;++++verificar puerto C ++++

    tresB3
    movf contador_ledon,w

    movwf aux

    movlw b’00000011′

    subwf aux,w

    btfss STATUS,2 ;++++ si el contador vale 3 deja el led prendido ++++

    goto ceroB3 ;++++ sino lo apaga ++++

    bsf auxB,3

    goto newgen_B

    ceroB3

    bcf auxB,3
    goto newgen_B

    newgen_B

    movf auxD,w
    movwf PORTD

    movf auxB,w
    movwf PORTB

    movf auxC,w
    movwf PORTC

    movf PORTA,w

    xorwf interruptor

    btfss STATUS,2 ; ++++ si el estado cambio llama al otro grupo de organismo ++++
    ; ++++ sino se toma unos segundos encendido antes de cambiar a su estado futuro ++++
    goto generacion_1A ; ++++ no me interesa que retorne a la siguiente línea +++++

    call busy_waiting ; espera 5 segundos antesde cambiar

    goto buscar_newgen

    ;+++++++++++++++++++++++++++++++++++++++++++++++++++

    busy_waiting ; La llamada “call” aporta 2 ciclos máquina.
    movlw d’50′ ; Aporta 1 ciclo máquina. Este es el valor de “N”.
    goto Retardo_1Decima
    Retardo_1Decima
    movwf R_ContC ; Aporta 1 ciclo máquina.
    R1Decima_BucleExterno2
    movlw d’100′ ; Aporta Nx1 ciclos máquina. Este es el valor de “M”.
    movwf R_ContB ; Aporta Nx1 ciclos máquina.
    R1Decima_BucleExterno
    movlw d’249′ ; Aporta MxNx1 ciclos máquina. Este es el valor de “K”.
    movwf R_ContA ; Aporta MxNx1 ciclos máquina.
    R1Decima_BucleInterno
    nop ; Aporta KxMxNx1 ciclos máquina.
    decfsz R_ContA,F ; (K-1)xMxNx1 cm (si no salta) + MxNx2 cm (al saltar).
    goto R1Decima_BucleInterno ; Aporta (K-1)xMxNx2 ciclos máquina.
    decfsz R_ContB,F ; (M-1)xNx1 cm (cuando no salta) + Nx2 cm (al saltar).
    goto R1Decima_BucleExterno ; Aporta (M-1)xNx2 ciclos máquina.
    decfsz R_ContC,F ; (N-1)x1 cm (cuando no salta) + 2 cm (al saltar).
    goto R1Decima_BucleExterno2 ; Aporta (N-1)x2 ciclos máquina.
    return ; El salto del retorno ap
    nop
    END


Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.