Usando Macros
March 18, 2008 at 5:23 pm | In HowTo, Tutorial | 9 CommentsEl 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
Leave a comment
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.
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
Comment by Marcos — April 19, 2008 #
Hola Marcos, gracias por tu comentario, me da gusto que te haya servido este blog.
Comment by micropic — April 19, 2008 #
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.
Comment by Carlos — April 29, 2008 #
Somehow i missed the point. Probably lost in translation
Anyway … nice blog to visit.
cheers, Fitfully.
Comment by Fitfully — June 18, 2008 #
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
Comment by Emi — August 7, 2008 #
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
Comment by McCollins — December 23, 2008 #
ahh el pic que debo utilizar el el 16f877
Comment by McCollins — December 23, 2008 #
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
Comment by McCollins — December 23, 2008 #
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
Comment by McCollins — January 20, 2009 #