Tutorial Asm Pic16f84 y Pic16f877a

42
ASM MICROPROCESADORES I SU AMIGABLE BESINO: ANGHEL PMQ PRACTICA 1 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ; ;Leer el estado de los 5 interruptores E0-E4 conectados a RA0-RA4 y reflejar el nivel lógico de ;los mismos sobre los leds S0-S4 conectados en RB0-RB4 List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluye el fichero P16F84.INC que contiene la definición con los nombres ;de los registros internos org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 de la memoria de datos clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;Puerta A se configura como entrada bcf STATUS,RP0 ;Selecciona banco 0 de la memoria de datos Loop movf PORTA,W ;Leer las entradas RA0-RA4 movwf PORTB ;Reflejar en las salidas goto Loop ;Bucle sin fin end ;Fin del programa fuente ; PRACTICA 2 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Una lámpara conectada en RB0 se controla mediante dos interruptores conectados en RA0 y RA1. ;Cuando cualquiera de los interruptores cambie de estado, la lámpara también lo hará. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluye el fichero P16F84.INC que contiene la definición ;con los nombres de los registros internos Temp equ 0x0c ;Variable temporal que se almacena en la posición 0x0c org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción

description

Programación en Ensamblador(ASM) para PIC

Transcript of Tutorial Asm Pic16f84 y Pic16f877a

Page 1: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

PRACTICA 1 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ; ;Leer el estado de los 5 interruptores E0-E4 conectados a RA0-RA4 y reflejar el nivel lógico de ;los mismos sobre los leds S0-S4 conectados en RB0-RB4 List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluye el fichero P16F84.INC que contiene la definición con los nombres ;de los registros internos

org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 de la memoria de datos clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;Puerta A se configura como entrada bcf STATUS,RP0 ;Selecciona banco 0 de la memoria de datos Loop movf PORTA,W ;Leer las entradas RA0-RA4 movwf PORTB ;Reflejar en las salidas goto Loop ;Bucle sin fin end ;Fin del programa fuente

; PRACTICA 2 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Una lámpara conectada en RB0 se controla mediante dos interruptores conectados en RA0 y RA1. ;Cuando cualquiera de los interruptores cambie de estado, la lámpara también lo hará. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluye el fichero P16F84.INC que contiene la definición ;con los nombres de los registros internos Temp equ 0x0c ;Variable temporal que se almacena en la posición 0x0c org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción

Page 2: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 de la memoria de datos clrf TRISB ;Puerta B se configura como salida movlw b'00000011' movwf TRISA ;RA0 y RA1 se configuran como entrada bcf STATUS,RP0 ;Selecciona banco 0 de la memoria de datos clrf Temp ;Pone a 0 el registo o variable temporal Loop movf PORTA,W ;Leer el estado de la puerta A andlw b'00000011' ;Filtra la información leída y nos quedamos con el estado de RA0 y RA1 movwf Temp ;Almacena temporalmente btfsc STATUS,Z ;RA0=0 y RA1=0 ??

goto Apagar ;Si, la lámpara se apaga movlw b'00000001' subwf Temp,W btfsc STATUS,Z ;RA0=1 y RA1=0 ?? goto Encender ;Si, la lámpara se enciende movlw b'00000010' subwf Temp,W btfsc STATUS,Z ;RA0=0 y RA1=1 ?? goto Encender ;Si, la lámpara se enciende Apagar bcf PORTB,0 ;No, la lámpara se apaga goto Loop Encender bsf PORTB,0 ;La lámpara se enciende goto Loop end ;Fin del programa fuente ; PRACTICA 3 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Programa combinacional ; ;Según el estado de los interruptores RA0 y RA1, activar los leds RB0-RB7 conectados a la ;puerta B, conforme a la siguiente tabla de la verdad: ; ; RA1 RA0 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 ; -- -- -- -- -- -- -- -- -- -- ; 0 0 1 0 1 0 1 0 1 0 ; 0 1 0 1 0 1 0 1 0 1 ; 1 0 0 0 0 0 1 1 1 1

Page 3: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; 1 1 1 1 1 1 0 0 0 0 List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluir la definición de los registros internos Temp equ 0x0c ;Variable temporal org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida

movlw b'00001001' movwf OPTION_REG ;Preescaler de 1:2 asociado al WDT movlw b'00000011' movwf TRISA ;RA0 y RA1 se configuran como entrada bcf STATUS,RP0 ;Selecciona banco 0 Loop: clrwdt ;Refrescar el WDT movf PORTA,W ;Carga el valor de la PUERTA A andlw b'00000011' ;Filtra el estado de RA0 y RA1 movwf Temp ;Almacena temporalmente btfsc STATUS,Z ;Están a 00 ? goto Secuencia_00 ;Si movlw b'00000001' subwf Temp,W btfsc STATUS,Z ;Están a 01 ? goto Secuencia_01 ;Si movlw b'00000010' subwf Temp,W btfsc STATUS,Z ;Están a 10 ? goto Secuencia_10 ;Si Secuencia_11 movlw b'11110000' movwf PORTB ;Salida de la secuencia 11 goto Loop Secuencia_00 movlw b'10101010' movwf PORTB ;Salida de la secuencia 00 goto Loop Secuencia_01 movlw b'01010101' movwf PORTB ;Salida de la secuencia 01 goto Loop Secuencia_10 movlw b'00001111' movwf PORTB ;Salida de la secuencia 10 goto Loop end ;Fin del programa fuente

Page 4: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; ; PRACTICA 4 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Programa secuencial ; ;Mediante dos pulsadores conectados en RA0 y RA1 se controla la salida RB0 que gobierna un ;zumbador de alarma. Una transición a "1" en RA0 provoca su activación, una transición en RA0 ;su desactivación. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluir la definición de los registros internos

org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00001001' movwf OPTION_REG ;Preescaler de 1:2 asociado al WDT movlw b'00000011' movwf TRISA ;RA0 y RA1 se configuran como entrada bcf STATUS,RP0 ;Selecciona banco 0 Loop: clrwdt ;Refrescar el WDT btfsc PORTA,0 ;RA0=1 ?? goto Alarma_On ;Si btfss PORTA,1 ;RA1=1 ?? goto Loop ;No Alarma_Off bcf PORTB,0 ;Si, conecta la alarma goto Loop Alarma_On btfsc PORTA,1 ;RA1 también en ON ?? goto Alarma_Off ;Si, desconectar alarma bsf PORTB,0 ;No, activar alarma goto Loop end ;Fin del programa fuente ; ; PRACTICA 5 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Empleando el TMR0; juego de luces ;

Page 5: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

;El programa activa secuencialmente, de una en una, las ocho salidas de la puerta B (RB0-RB7), ;provocacndo un efecto de desplazamiemto de dcha. a izda. Cada salida se mantiene activada ;durante un intervalo de 0.1" (100mS). Dicho intervalo se controla mediante el TMR0. ; ;El TMR0 se carga con el valor 195 y, trabajando a 4MHz, evoluciona cada 1 uS. Como a su vez ;se le asocia un preescaler de 256, el desbordamiento se prodicirá al de 49.9 ms List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluir la definición de los registros internos Temp equ 0x0c ;Variable temporal Delay equ 0x0d ;Variable para temporización org 0x00 ;Vector de Reset goto Inicio

org 0x05 ;Salva el vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00000111' movwf OPTION_REG ;Preescaler de 1:256 asociado al TMR0 bcf STATUS,RP0 ;Selecciona banco 0 movlw b'00000001' movwf Temp ;1er. valor a sacar bcf STATUS,C Loop movwf PORTB ;Salida del valor correspondiente movlw .2 movwf Delay ;Una temporización de 50 mS se repetirá 2 veces Loop_0 movlw ~.195 movwf TMR0 ;Carga el TMR0 con el complemento del valor 195 bcf INTCON,T0IF ;Restaura el flag de desbordamiento del TMR0 Loop_1 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Se ha desbordado el TMR0 ?? goto Loop_1 ;No, todavía no han transcurrido los 50 mS decfsz Delay,F ;Se ha repetido 2 veces la temporización de 50 mS (0.1") goto Loop_0 ;No rlf Temp,F ;Si, Desplaza a la izquierda para obtener el siguiente movf Temp,W ;valor a sacar por la puerta B goto Loop end ;Fin del programa fuente

; ; PRACTICA 6 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Usando el preescaler, más juego de luces

Page 6: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; ;El programa activa secuencialmente, de una en una, las ocho salidas de la puerta B (RB0-RB7), ;provocacndo un efecto de desplazamiemto de dcha. a izda. Cada salida se mantiene activada ;durante un intervalo de tiempo variable en función de las entradas RA0-RA2, que seleccionan ;los 8 valores posibles del preescaler comprendidos entre 1:2 y 1:256. ; ;El TMR0 realiza una cuenta de 50 eventos que se repite 200 veces. La temporización mínima es ;de 20mS (preesacler 1:2) y la máxima 2.5" (preescaler 1:256) List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluir la definición de los registros internos Temp equ 0x0c ;Variable temporal Delay equ 0x0d ;Variable para temporización

org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 movlw b'00000111' movwf TRISA ;RA0-RA2 actúan como entradas clrf TRISB ;Puerta B se configura como salida bcf STATUS,RP0 ;Selecciona banco 0 movlw b'00000001' movwf Temp ;1er. valor a sacar bcf STATUS,C Loop movf PORTA,W ;Lee las entradas RA0-RA2 andlw b'00000111' bsf STATUS,RP0 ;Selecciona banco 1 movwf OPTION_REG ;Ajusta valor del preescaler según las entradas bcf STATUS,RP0 ;Selecciona el banco 0 movf Temp,W movwf PORTB ;Salida del valor correspondiente movlw .200 movwf Delay ;Una temporización de 50 eventos se repetirá 200 veces Loop_0 movlw ~.50 movwf TMR0 ;Carga el TMR0 con el complemento del valor 50 bcf INTCON,T0IF ;Restaura el flag de desbordamiento del TMR0 Loop_1 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Se ha desbordado el TMR0 ?? goto Loop_1 ;No, todavía no han transcurrido los 50 mS decfsz Delay,F ;Se ha repetido 200 veces la temporización de 50 eventos ? goto Loop_0 ;No rlf Temp,F ;Si, Desplaza a la izquierda para obtener el siguiente goto Loop end ;Fin del programa fuente

Page 7: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; PRACTICA 7 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;El modo "sleep" y el "wake-up" (despertar) mediante el watch-dog Timer (WDT) ; ;Este ejemplo pretende mostrar el empleo de la instrucción SLEEP para poner al PIC en el ;modo standby de bajo consumo. El despertar del mismo se producirá cada vez que el WDT rebase. ;En ese momento se producirá un incremento del valor de la puerta B que actuará como contador ;binario y nuevamente se volverá a la situaciónd de standby. ; ;El preescaler se asociará al WDT y estará comprendido entre 1 y 128, dependiendo del estado ;lógico de los interruptores RA0-RA2.

; ;El valor nominal del WDT es de 18mS. Es decir, con un preescaler de 1, el pic "despertará" ;cada 18mS, con un prrescaler de 128, lo hará cada 2,3 segundos. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;RA0-RA4 entradas movlw b'00001000' movwf OPTION_REG ;Preescaler de 1 para el WDT bcf STATUS,RP0 ;Selecciona banco 0 Loop sleep ;Modo Standby incf PORTB,F ;Incrementa el contador binario sobre la puerta B movf PORTA,W andlw b'00000111' ;Lee el estado de los interruptores RA0-RA2 iorlw b'00001000' bsf STATUS,RP0 ;Selecciona el banco 1 movwf OPTION_REG ;Ajusta valor del preescaler bcf STATUS,RP0 ;Selecciona el banco 1 goto Loop ;Volver al modo Standby end ;Fin del programa fuente

Page 8: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; PRACTICA 8 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;El modo TMR0 como contador de eventos externos ; ;El ejemplo pretende mostrar el funcionamiento del TMR0 en el modo contador. Mediante las ;entradas RA0-RA3 se introduce el número de pulsos a contar. Por RA4 se aplican dichos pulsos ;Cuando se alcance el valor deseado se disparan dos salidas durante un tiempo. La salida RB1 se ;utiliza para desconectar la fuente de entrada de pulsos y RB0 para activar cualquier otro ;dispositivo (p.e. un relé, en led, etc.) ;El WDT se empleará a modo de temporizador para determinar el tiempo de disparo de ambas ;salidas

List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva vector de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;RA0-RA4 entradas movlw b'00111111' movwf OPTION_REG ;Preescaler de 256 para el WDT. El TMR0 evoluciona a ;cada flanco descendente aplicado por RA4 bcf STATUS,RP0 ;Selecciona banco 0 Loop movf PORTA,W andlw b'00001111' ;Lee las entradas RA0-RA3 xorlw b'11111111' ;Complementa el valor leído (el TMR0 es ascendente) addlw .1 movwf TMR0 ;Carga el TMR0 con el valor leído bsf PORTB,1 ;Activa la entrada de pulsos a contar bcf INTCON,T0IF ;Repone el flag del TMR0 Espera clrwdt ;Refresca el WDT btfss INTCON,T0IF ;Ha finalizado la cuenta ?? goto Espera ;No bcf PORTB,1 ;Desconecta la entrada de pulsos a contar bsf PORTB,0 ;Activa la salida a relé, led, etc. clrwdt ;El WDT se refresca y comienza la temporización sleep ;El modo standby se mantiene hasta que el WDT desborde ;transcurridos aprox. 2" (18mS*256 de preescaler) bcf PORTB,0 ;Desactiva la salida a relé, led, etc. goto Loop end ;Fin del programa fuente

Page 9: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; PRACTICA 9 ; ; Autor:BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ; ;La interrupción del TMR0. ; ;Se trata de comprobar la interrupción provocada por el TMR0. El programa ;lee constantemente el estado de los interruptores conectados a RA0 y RA1 para reflejarlo en ;los leds conectados a RB0 y RB1 respectivamente. Al mismo tiempo el TMR0 ;genera una interrupción cada 0.05 seg. (50 mS) que se repetirá 5 veces con objeto ;de hacer intermitencia de 250 mS sobre el led conectado a RB7.

List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos Temp equ 0x0c ;Variable para la temporización Temp_2 equ 0x0d ;Registro temporal org 0x00 ;Vector de Reset goto Inicio org 0x04 ;Vector de interrupción ;Programa de tratamiento de la interrupción Tratamiento btfss INTCON,T0IF ;Ha sido el TMR0 ?? goto Fin_Tratamiento ;No bcf INTCON,T0IF ;Si, repone flag del TMR0 decfsz Temp,F ;Se ha repetido la interrupción 5 veces ?? goto Seguir ;No Con_si_0 movlw 5 movwf Temp ;Repone el contador nuevamente con 5 movlw b'10000000' xorwf PORTB,F ;RB7 cambia de estado Seguir movlw ~.195 movwf TMR0 ;Repone el TMR0 con el complemento de 195 Fin_Tratamiento retfie ;Retorno de interrupción Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;Puerta A se configura como entrada movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 asignado al TMR0 bcf STATUS,RP0 ;Selecciona banco 0 ;El TMR0 se incrementa cada 1 uS. Si se emplea un preescaler de 256, deberá sufrir 195 ;incrementos para provocar una interrupción cada 50000 uS (50 mS). Si esta se repite 5 ;veces, el tiempo total transcurrido es de 250000 uS (250 mS). Se debe usar el

Page 10: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

;complemento de 195 movlw ~.195 movwf TMR0 ;Carga el TMR0 con el complemeto de 195 movlw 0x05 movwf Temp ;Nº de veces a repetir la interrupción movlw b'10100000' movwf INTCON ;Activa la interrupción del TMR0 Loop clrwdt ;Refresca el WDT movf PORTA,W andlw b'00000011' ;Lee el estado de RA0 y RA1 movwf Temp_2 ;Lo salva temporalmente movf PORTB,W andlw b'10000000'

iorwf Temp_2,W movwf PORTB ;Salida por RB0 y RB1 respentando valor actual de RB7 goto Loop end ;Fin del programa fuente ; ; PRACTICA 10 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ; ;Otras interrupciones ; ;Los dispositivos PIC pueden provocar interrupción por otras dos causas diferentes además de ;por la del TMR0. Una de ellas es por la detección de una señal de un determinado flanco por ;la entrada RB0/INT. La otra es por el cambio de estado lógico producido en cualquiera de las ;líneas de entrada RB4-RB7. ; ;El ejemplo pretende mostrar la detección y tratamiento de cada una de estas nuevas fuentes de ;interrupción. Cuando se produce la interrupción RB0/INT se activa la salida RA0 durante 1". ;Cuando se produce la interrupción por cambio de estado en RB4-RB7 se activa la salida RA1 ;durante 1". List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos Temp equ 0x0c ;Variable para la temporización org 0x00 ;Vector de Reset goto Inicio org 0x04 ;Vector de interrupción ;Programa de tratamiento de la interrupción

Page 11: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

Tratamiento btfsc INTCON,INTF ;Ha sido el RB0/INT ?? goto Tratar_INTF ;Si btfss INTCON,RBIF ;No, ha sido cambio en RB4-RB7 ? goto Fin_Tratamiento ;No, falsa interrupción Cambio_RB4_RB7 bsf PORTA,1 ;Activa salida RB1 goto Fin Tratar_INTF bsf PORTA,0 ;Activa salida RB0 ;Se hace un delay de 1 segundo antes de reponer los correspondientes flags de interrupción. ;De esta forma se evitan posibles rebotes que puediera haber en las entradas. Fin movlw .20 ;Comienza una temporización de 1"

movwf Temp ;Inicia una variable temporal Seguir bcf INTCON,T0IF ;Repone el flag del TMR0 movlw ~.195 movwf TMR0 ;Repone el TMR0 con el complemento de 195 Delay_50mS clrwdt ;Comienza un bucle de temporización de 50mS btfss INTCON,T0IF ;Fin de los 50 mS ?? goto Delay_50mS ;Todavía no nop decfsz Temp,F ;Se ha repetido 20 veces los 50mS ?? goto Seguir ;No Fin_Tratamiento clrf PORTA ;Si, ha pasado 1". Desconecta las salidas movf PORTB,W ;Lee estado actual de las entradas RA4-RA7 para reponer bcf INTCON,RBIF ;el flag de interrupción por cambio en RB4-RB7. Hay que ;hacerlo en este órden bcf INTCON,INTF ;Repone el flag de interrupción por RBO/INT retfie ;Retorno de interrupción Inicio clrf PORTA ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISA ;Puerta A se configura como salidas movlw b'11111111' movwf TRISB ;Puerta B se configura como entrada movlw b'01000111' ;Preescaler de 256 asignado al TMR0 y movwf OPTION_REG ;RB0/INT sensible al flanco ascendente bcf STATUS,RP0 ;Selecciona banco 0 movf PORTB,W ;Lee el estado inicial de las entradas RB4-RB7 movlw b'10011000' movwf INTCON ;Activa la interrupcines INTF y RBIF Loop sleep ;El dispositivo queda en standby goto Loop end ;Fin del programa fuente

Page 12: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; PRACTICA 11 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Decodificador BCD a 7 segmentos ; ;Mediante los cuatro interruptores conectador a RA0-RA3 se aplica el código BCD de los números ;comprendidos entre 0 y 9. El programa obtiene el código de 7 segmentos para representar dicho ;número sobre un display de ánodo común, en el que cada segmento particular se activa mediante ;nivel lógico "0" List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Incluir la definición de los registros internos

Temp equ 0x0c ;Variable temporal org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5 retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9 Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00001001' movwf OPTION_REG ;Preescaler de 1:2 asociado al WDT movlw b'00001111' movwf TRISA ;RA0-RA3 se configuran como entrada bcf STATUS,RP0 ;Selecciona banco 0 Loop: clrwdt ;Refrescar el WDT movf PORTA,W andlw b'00001111' ;Lee las entradas RA0-RA3 movwf Temp ;Almacena valor leído movlw 0x0a subwf Temp,W btfsc STATUS,Z ;El valor es igual a 0x0A ?? goto NULO ;Si btfsc STATUS,C ;No, el valor es mayor a 0x0A ??

Page 13: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

goto NULO ;Si movf Temp,W call Tabla_7_seg ;Convierte el valor a código de 7 segmentos movwf PORTB ;Lo deposita en la puerta de salida para visualizarlo goto Loop NULO movlw b'11111111' ;El valor de entrada no estaba comprendido entre 0 y 9 movwf PORTB ;El display permanece apagado goto Loop end ;Fin del programa fuente ;

; PRACTICA 12 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Contador UP/DOWN decimal de un dígito ; ;Sobre el display 7 segmentos conectado a la puerta B se visualizará el número de pulsos ;aplicados por la entrada RA0. RA1 determina si la cuenta es ascendente (a "1") ;o descendente List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos Contador equ 0x0c ;Variable del contador org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva el vector de interrupción ;********************************************************************************** ;Tabla_7_seg: Esta rutina convierte el código BCD presente en los 4 bits de menos peso ;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también ;en el reg. W Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5 retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9

Page 14: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;Puerta A se configura como entrada movlw b'00000110' movwf OPTION_REG ;Preescaler de 128 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 clrf Contador ;Puesta a 0 del contador Loop movf Contador,W call Tabla_7_seg ;Convierte BCD a 7 segmentos movwf PORTB ;Visualiza el valor del contador

Wait_0 clrwdt ;Refrescar el WDT btfss PORTA,0 ;Subida de la señal RA0 ? goto Wait_0 ;No sleep ;Modo standby en espara de 18mS. Elimina rebotes Wait_1 clrwdt ;Refrescar el WDT btfsc PORTA,0 ;Bajada de RA0 (pulso) ?? goto Wait_1 ;No sleep ;Modo standby en espara de 18mS. Elimina rebotes btfss PORTA,1 ;RA1 = 1 ?? goto Down ;No, cuenta descendente Up incf Contador,F ;Incrementa contador movlw .10 subwf Contador,W btfss STATUS,Z ;Es mayor de 9 ?? goto Loop ;No clrf Contador ;Si, puesta a 0 del contador goto Loop Down decf Contador,F ;Decrementa el contador movlw 0xff subwf Contador,W btfss STATUS,Z ;Es menor de 0 ?? goto Loop ;No movlw .9 movwf Contador ;Si, puesta a 9 del contador goto Loop end ;Fin del programa fuente ; ; PRACTICA 13 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ;

Page 15: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; ;Generación de números aleatorios. El dado electrónico ; ;Se trata de generar un número aleatorio entre 1 y 6. Cuando RA0 está a "1", sobre el ;dsiplay 7 segmentos conectado a la puerta B, se van visualizando de forma secuecial ;los números del 1 al 6, con intervalos de 0.05". Al pasar RA0 a nivel "0", se visualiza ;el número aleatorio obtenido, durante un tiempo de 3". Luego el display se apaga y la ;secuencia se repite. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos Numero equ 0x0c ;Número aleatorio Delay_Cont equ 0x0d ;Contador de intervalos Temporal equ 0x0e ;Variable temporal

org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva vector de interrupción ;********************************************************************************** ;Tabla_7_seg: Esta rutina convierte el código BCD presente en los 4 bits de menos peso ;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también ;en el reg. W Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5 retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9 ;********************************************************************************* ;Delay_var: Esta rutina de propósito general realiza una temporización variable ;entre 50 mS y 12.8". Se emplea un preescaler de 256 y al TMR0 se le carga con 195. ;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De ;esta forma, el TMR0 debe contar 195 eventos que, con un preescaler de 256 hace una ;intervalo total de 50000 uS/50 mS (195 * 256). Dicho intervalo de 50 mS se repite ;tantes veces como indique la variable "Delay_cont", es por ello que el delay mínimo ;es de 50 mS ("Delay_cont=1) y el máxima de 12.8" (Delay_cont=255). Delay_var: bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw ~.195 movwf TMR0 ;carga el TMR0 con el complemento de 195 Intervalo clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 al de 50mS ?? goto Intervalo ;Todavía no

Page 16: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return Inicio movlw b'11111111' movwf PORTB ;Pone a "1" los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011111' movwf TRISA ;Puerta A se configura como entrada movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0

Loop clrwdt ;Refrescar el WDT btfss PORTA,0 ;Activado RA0 ?? goto Loop ;Todavía No movf TMR0,W ;Ahora si. movwf Numero ;Captura el valor del TMR0 (Nº aleatorio) ;El número aleatorio es, mediante restas consecutivas, dividido entre 6. De esta forma ;el último resto será entre 0 y 5 que será incrementado en una unidad para que defini- ;tivamente de un número entre 1 y 6 Divide: movlw .6 subwf Numero,W ;Resta 6 al número aleatorio movwf Numero ;lo guarda sublw .5 btfss STATUS,C ;Mira si es menor de 5 goto Divide ;No incf Numero,F ;El número queda entre 1 y 6 ;Esta secuencia de instrucciones tiene por misión presentar sobre el display los números ;del 1 al 6 a intervalos de 0.05" con objeto de dar una sensación de movimiento del dado. ;Dicho movimiento se mantiene mientras RA0 esté a "1". Al ponerse a "0" se presenta el ;número aleatorio capturado previamente desde el TMR0 Dado: movlw .6 movwf Temporal ;Inicia el contador del dado RA0_1 clrwdt ;Refresco del WDT btfss PORTA,0 ;Mira si RA0 está a 1 goto Salida ;No, visualiza el aleatorio movf Temporal,W ;Número a visualizar call Tabla_7_seg ;Conversión a BCD movwf PORTB ;Visualiza sobre el display movlw .1 movwf Delay_Cont ;Variable de temporización call Delay_var ;temporiza 0.05" decfsz Temporal,F ;Siguiente número goto RA0_1 goto Dado

Page 17: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

Salida: sleep ;Elimina rebotes movf Numero,W ;Recoge el aleatorio call Tabla_7_seg ;Lo convierte en 7 segmentos movwf PORTB ;Salida a Display movlw d'60' movwf Delay_Cont ;Inicia variable de temporización call Delay_var ;Temporiza 3" movlw b'11111111' movwf PORTB ;Apaga el display goto Loop end ;Fin del programa fuente

; ; PRACTICA 14 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Multiplexado de displays ; ;El ejemplo presenta un subrutina que realiza el multiplexado o barrido de 3 displays de ;ánodo común y que visualiza el valor actual de las variables D0, D1 y D2 a las que se ;supone previamente cargadas. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos DIG0 equ 0x0c ;Variable para el dígito 0 DIG1 equ 0x0d ;Variable para el dígito 1 DIG2 equ 0x0e ;Variable para el dígito 2 Delay_Fijo equ 0x0f ;Variable para temporización fija Delay_Cont equ 0x10 ;Variable para temporización variable org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva vector de interrupción ;********************************************************************************** ;Tabla_7_seg: Esta rutina convierte el código BCD presente en los 4 bits de menos peso ;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también ;en el reg. W Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5

Page 18: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9 ;********************************************************************************** ;Display: Esta rutina activa secuencialmente cada uno de los dígitos D0, D1 y D2 ;conectados a RA0, RA1 y RA2 respectivamente, a la vez que visualiza en cada uno de ;ellos el contenido de las variables DIG1, DIG2 y DIG3, previa conversión a 7 segmentos Display bsf PORTA,0 ;Activa dígito 0 movf DIG0,W ;Carga variable DIG0 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG0 sobre el dígito 0 call Delay ;Temporiza 1mS

bcf PORTA,0 ;Desactiva dígito 0 movlw b'11111111' movwf PORTB ;Desactiva segmentos bsf PORTA,1 ;Activa dígito 1 movf DIG1,W ;Carga variable DIG1 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG1 sobre el dígito 1 call Delay ;Temporiza 1mS bcf PORTA,1 ;Desactiva dígito 1 movlw b'11111111' movwf PORTB ;Desactiva segmentos bsf PORTA,2 ;Activa dígito 2 movf DIG2,W ;Carga variable DIG2 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG2 sobre el dígito 2 call Delay ;Temporiza 1mS bcf PORTA,2 ;Desactiva dígito 2 movlw b'11111111' movwf PORTB ;Desactiva segmentos return ;Fin del multiplexado ;********************************************************************************** ;Delay: Rutina de temporización por software. Un bucle hace decermentar una variable hasta ;alcanzar 0. El tiempo que consume su ejecución es del orden de 1mS, dado que la ejecución de ;tres instrucciones que consumen 4 uS, se repite 255 veces ; Delay clrf Delay_Fijo ;Se manda repetir el bucle 255 veces Delay_1 nop ;Consume 1 uS decfsz Delay_Fijo,F ;Consume 1 uS goto Delay_1 ;Consume 2 uS return ;********************************************************************************* ;Delay_var: Esta rutina de propósito general realiza una temporización variable ;entre 5 mS y 1.2". Se emplea un preescaler de 256 y al TMR0 se le carga con 19. ;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De ;esta forma, el TMR0 debe contar 19 eventos que, con un preescaler de 256 hace una ;intervalo total de 5000 uS/5 mS (19 * 256). Dicho intervalo de 5 mS se repite

Page 19: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

;tantes veces como indique la variable "Delay_cont", es por ello que el delay mínimo ;es de 5 mS ("Delay_cont=1) y el máxima de 1.2" (Delay_cont=255). Delay_var: bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw ~.19 movwf TMR0 ;carga el TMR0 con el complemento de 195 Intervalo clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 al de 50mS ?? goto Intervalo ;Todavía no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return Inicio movlw b'11111111' movwf PORTB ;Pone a "1" los latch de salida

clrf PORTA ;Desconecta los dígitos bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011000' movwf TRISA ;RA0-RA2 se configuran como salidas movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 movlw 1 movwf DIG2 movlw 2 movwf DIG1 movlw 3 movwf DIG0 ;Carga en las variables el valor a visualizar (123) Loop clrwdt ;Refrescar el WDT call Display ; movlw .1 movwf Delay_Cont call Delay_var goto Loop end ;Fin del programa fuente ; ; PRACTICA 15 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Contador UP/DOWN de 3 dígitos ; ;Se trata de un contador UP/DOWN de 3 dígitos que cuenta desde 000 hasta 999. La entrada de ;pulsos a contar se aplica por RA4 es sensible al flanco descendente. La entrada RA3 determina ;si la cuenta es ascendente "1" o descendente "0"

Page 20: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos DIG0 equ 0x0c ;Variable para el dígito 0 DIG1 equ 0x0d ;Variable para el dígito 1 DIG2 equ 0x0e ;Variable para el dígito 2 Delay_Fijo equ 0x0f ;Variable para temporización fija org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva vector de interrupción ;********************************************************************************** ;Tabla_7_seg: Esta rutina convierte el código BCD presente en los 4 bits de menos peso

;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también ;en el reg. W Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5 retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9 ;********************************************************************************** ;Display: Esta rutina activa secuencialmente cada uno de los dígitos D0, D1 y D2 ;conectados a RA0, RA1 y RA2 respectivamente, a la vez que visualiza en cada uno de ;ellos el contenido de las variables DIG1, DIG2 y DIG3, previa conversión a 7 segmentos Display bsf PORTA,0 ;Activa dígito 0 movf DIG0,W ;Carga variable DIG0 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG0 sobre el dígito 0 call Delay ;Temporiza 1mS bcf PORTA,0 ;Desactiva dígito 0 movlw b'11111111' movwf PORTB ;Desactiva segmentos bsf PORTA,1 ;Activa dígito 1 movf DIG1,W ;Carga variable DIG1 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG1 sobre el dígito 1 call Delay ;Temporiza 1mS bcf PORTA,1 ;Desactiva dígito 1 movlw b'11111111' movwf PORTB ;Desactiva segmentos bsf PORTA,2 ;Activa dígito 2

Page 21: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

movf DIG2,W ;Carga variable DIG2 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG2 sobre el dígito 2 call Delay ;Temporiza 1mS bcf PORTA,2 ;Desactiva dígito 2 movlw b'11111111' movwf PORTB ;Desactiva segmentos return ;Fin del multiplexado ;********************************************************************************** ;Delay: Rutina de temporización por software. Un bucle hace decermentar una variable hasta ;alcanzar 0. El tiempo que consume su ejecución es del orden de 1mS, dado que la ejecución de ;tres instrucciones que consumen 4 uS, se repite 255 veces ; Delay clrf Delay_Fijo ;Se manda repetir el bucle 255 veces

Delay_1 nop ;Consume 1 uS decfsz Delay_Fijo,F ;Consume 1 uS goto Delay_1 ;Consume 2 uS return ;**************************************************************************************** ;Incrementa en una unidad las variables DIG0, DIG1 y DIG2 con el correspondiente ajuste BCD ; Incrementa incf DIG0,F ;Incrementa DIG0 en una unidad movlw 0x0a subwf DIG0,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG0 ;Si, ajusta a 0 variable DIG0 incf DIG1,F ;Incrementa DIG1 movlw 0x0a subwf DIG1,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG1 ;Si, ajusta a 0 variable DIG1 incf DIG2,F ;Incrementa DIG2 movlw 0x0a subwf DIG2,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG2 ;Si, agista a 0 variable DIG2 return ;******************************************************************************************* ;Decrementa en una unidad las variables DIG0, DIG1 y DIG2 con el correspondiente ajuste BCD ; Decrementa decf DIG0,F ;Decrementa DIG0 en una unidad movlw 0xff subwf DIG0,W btfss STATUS,Z ;Es menor de 0 ? return ;No movlw .9 movwf DIG0 ;Si ajuste de DIG0

Page 22: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

decf DIG1,F ;Decrementa DIG1 movlw 0xff subwf DIG1,W btfss STATUS,Z ;Es menor de 0 ? return ;No movlw .9 movwf DIG1 ;Si, ajusta DIG1 decf DIG2,F ;Decrementa DIG2 movlw 0xff subwf DIG2,W btfss STATUS,Z ;Es menor de 0 ? return ;No movlw .9 movwf DIG2 ;Si, ajusta DIG2 return

Inicio movlw b'11111111' movwf PORTB ;Pone a "1" los latch de salida clrf PORTA ;Desconecta los dígitos bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011000' movwf TRISA ;RA0-RA2 se configuran como salidas movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 clrf DIG0 clrf DIG1 clrf DIG2 ;Carga las variables con valor inicial 000 Loop clrwdt ;Refrescar el WDT btfsc PORTA,4 ;Flanco ascendente en RA4 ?? goto Descendente ;Si call Display ;No, mantiene el refresco del display goto Loop ;Esperar Descendente clrwdt ;Refrescar el WDT btfss PORTA,4 ;Flanco descendente en RA4 goto Pulso ;Si, ha habido un pulso en RA4 call Display ;No, mantiene el refresco del display goto Descendente ;Esperar Pulso btfss PORTA,3 ;RA3 está a "1" ?? goto Dec_Cont ;No call Incrementa ;Si, incrementa el contador goto Loop ;Esperar al siguiente pulso Dec_Cont call Decrementa ;Decrementar el contador goto Loop ;Esperar el siguiente pulso end ;Fin del programa fuente

Page 23: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; ; PRACTICA 16 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;Cronómetro digital ; ;Se trata de un cronómetro capaz de medir lapsus de tiempo de hasta 99.9 segundos. El pulsador ;conectado a RA4 actúa de START/STOP mientras que RA3 actúa como puesta a 00.0 List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos

DIG0 equ 0x0c ;Variable para el dígito 0 DIG1 equ 0x0d ;Variable para el dígito 1 DIG2 equ 0x0e ;Variable para el dígito 2 Delay_Fijo equ 0x0f ;Variable para temporización fija W_Temp equ 0x10 ;Registro temporal para el W STATUS_Temp equ 0x11 ;Registro temporal para el registro de estado Delay_Cont equ 0x12 ;Variable de temporización org 0x00 ;Vector de Reset goto Inicio org 0x04 goto Interrupcion ;Vector de interrupción org 0x05 ;Salva vector de interrupción ;********************************************************************************** ;Tabla_7_seg: Esta rutina convierte el código BCD presente en los 4 bits de menos peso ;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también ;en el reg. W Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5 retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9 ;********************************************************************************** ;Display: Esta rutina activa secuencialmente cada uno de los dígitos D0, D1 y D2 ;conectados a RA0, RA1 y RA2 respectivamente, a la vez que visualiza en cada uno de ;ellos el contenido de las variables DIG1, DIG2 y DIG3, previa conversión a 7 segmentos Display bsf PORTA,0 ;Activa dígito 0

Page 24: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

movf DIG0,W ;Carga variable DIG0 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG0 sobre el dígito 0 call Delay ;Temporiza 1mS bcf PORTA,0 ;Desactiva dígito 0 movlw b'11111111' movwf PORTB ;Desactiva segmentos bsf PORTA,1 ;Activa dígito 1 movf DIG1,W ;Carga variable DIG1 call Tabla_7_seg ;Convierte a 7 segmentos andlw b'01111111' ;Activa el punto decimal en el dígito 1 movwf PORTB ;Visualiza DIG1 sobre el dígito 1 call Delay ;Temporiza 1mS bcf PORTA,1 ;Desactiva dígito 1 movlw b'11111111'

movwf PORTB ;Desactiva segmentos bsf PORTA,2 ;Activa dígito 2 movf DIG2,W ;Carga variable DIG2 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG2 sobre el dígito 2 call Delay ;Temporiza 1mS bcf PORTA,2 ;Desactiva dígito 2 movlw b'11111111' movwf PORTB ;Desactiva segmentos return ;Fin del multiplexado ;********************************************************************************** ;Delay: Rutina de temporización por software. Un bucle hace decermentar una variable hasta ;alcanzar 0. El tiempo que consume su ejecución es del orden de 1mS, dado que la ejecución de ;tres instrucciones que consumen 4 uS, se repite 255 veces ; Delay clrf Delay_Fijo ;Se manda repetir el bucle 255 veces Delay_1 nop ;Consume 1 uS decfsz Delay_Fijo,F ;Consume 1 uS goto Delay_1 ;Consume 2 uS return ;**************************************************************************************** ;Incrementa en una unidad las variables DIG0, DIG1 y DIG2 con el correspondiente ajuste BCD ; Incrementa incf DIG0,F ;Incrementa DIG0 en una unidad movlw 0x0a subwf DIG0,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG0 ;Si, ajusta a 0 variable DIG0 incf DIG1,F ;Incrementa DIG1 movlw 0x0a subwf DIG1,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG1 ;Si, ajusta a 0 variable DIG1 incf DIG2,F ;Incrementa DIG2

Page 25: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

movlw 0x0a subwf DIG2,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG2 ;Si, agista a 0 variable DIG2 return ;*************************************************************************************** ;Interrupción: Programa de tratamiento que se ejecuta cada vez que desborde el TMR0. Este ;se carga con 195 que junto con un preescaler de 256 genera interrupción cada 50mS. Cuando ;se producen dos interrupciones (0.1") se actualiza el valor de los contadores. Interrupcion btfss INTCON,T0IF ;Ha sido el TMR0 ?? retfie ;No, falsa interrupción bcf INTCON,T0IF ;Si, reponer flag del TMR0

movwf W_Temp ;Salva el registro W swapf STATUS,W movwf STATUS_Temp ;Salva el registro de estado movlw ~.195 movwf TMR0 ;Recarga el TMR0 para la siguiente temporización decfsz Delay_Cont,F ;Ha habido dos interrupciones ?? goto Inter_Fin ;No movlw .2 movwf Delay_Cont ;Si, repone el contador de interrupciones con 2 call Incrementa ;Actualiza el contador del cronómetro Inter_Fin swapf STATUS_Temp,W movwf STATUS ;Recupera el registro de estado swapf W_Temp,F swapf W_Temp,W ;Recupera el registro W retfie Inicio movlw b'11111111' movwf PORTB ;Pone a "1" los latch de salida clrf PORTA ;Desconecta los dígitos bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011000' movwf TRISA ;RA0-RA2 se configuran como salidas movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 Loop clrf DIG0 clrf DIG1 clrf DIG2 ;Puesta a 000 del contador bcf INTCON,T0IF ;Repone flag del TMR0 Loop_1 clrwdt ;Refrescar el WDT btfsc PORTA,4 ;Flanco ascendente en RA4 ?? goto Descendente ;Si call Display ;No, mantiene el refresco del display goto Loop_1 ;Esperar

Page 26: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

Descendente clrwdt ;Refrescar el WDT btfss PORTA,4 ;Flanco descendente en RA4 goto START ;Si, ha habido un pulso en RA4 call Display ;No, mantiene el refresco del display goto Descendente ;Esperar ;Se comienza a cronometrar START movlw ~.195 movwf TMR0 ;Carga el TMR0 con 195 (interrupción cada 50mS) movlw .2 movwf Delay_Cont ;Inicia variable de temporización bsf INTCON,T0IE ;Habilita interrupción del TMR0 bsf INTCON,GIE ;Permiso general de interrupciones

Crono_Fin clrwdt btfsc PORTA,4 ;Flanco ascendente en RA4 ? goto STOP ;Si, parada del cronómetro call Display ;No, mantiene el refresco del display goto Crono_Fin ;Sigue cronometrando ;Secuencia de parada del cronómetro y puesta a 000 STOP bcf INTCON,GIE ;Se detiene la interrupción del TMR0 Fin_1 clrwdt btfss PORTA,4 ;Flanco descendente de RA4 ?? goto Fin_2 ;Si call Display ;Aún no se ha soltado RA4, refrescar el display goto Fin_1 ;Esperar a que se suelte RA4 Fin_2 clrwdt btfsc PORTA,3 ;Flanco ascendente en RA3 ? goto Fin_3 ;Si call Display ;No, mantiene el refresco del display goto Fin_2 ;Esperar a que se active RA3 Fin_3 clrwdt btfss PORTA,3 ;Flanco descendente en RA3 ? goto Loop ;Si, ha habido pulso para puesta a 0 del cronómetro call Display ;No, mantiene el refresco del display goto Fin_3 ;Esperar a que se suelte RA3 end ;Fin del programa fuente ; ; PRACTICA 17 ; ; Autor: BARRABAZ ; (c) Microsystems Engineering (Bilbao) ; ;La memoria EEPROM de datos. La máquina "Su Turno"

Page 27: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

; ;Sobre los display D0 y D1 se visualiza el número de turno entre 00 y 99. Cada vez que se ;aplica un pulso por RA4 el contador se incrementa una unidad al tiempo que se activa una señal ;acústica conectada a RA2 durante 0.5". La entrada RA3 se emplea para cponer a 00 el contador. ; ;El valor de la cuenta es constantemente registrado en la EEPROM de datos. Si hubiera un fallo ;de alimentación, el contador visualiza el último estado. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos DIG0 equ 0x0c ;Variable para el dígito 0 DIG1 equ 0x0d ;Variable para el dígito 1 Delay_Fijo equ 0x0e ;Variable para temporización fija Delay_Cont equ 0x0f ;Variable de temporización

N_Bytes equ 0x10 ;Nº de bytes a grabar/leer en la EEPROM org 0x00 ;Vector de Reset goto Inicio org 0x05 ;Salva vector de interrupción ;**************************************************************************************** ;EE_Write: Graba n bytes a partir de la primera posición de la EEPROM de datos. El número ;de bytes a grabar está contenido en la variable N_Bytes. EE_Write movlw .2 movwf N_Bytes ;Inicia Nº de bytes a leer clrf EEADR ;Dirección 0 de EEPROM movlw DIG0 movwf FSR ;Inicia índice con el 1er. byte a grabar EE_Write_1 movf INDF,W movwf EEDATA ;Carga dato a grabar bsf STATUS,RP0 ;Selecciona banco 1 bsf EECON1,WREN ;Permiso de escritura movlw b'01010101' movwf EECON2 movlw b'10101010' movwf EECON2 ;Secuencia establecida por Microchip bsf EECON1,WR ;Orden de escritura bcf EECON1,WREN ;Desconecta permiso de escritura Wait btfss EECON1,EEIF ;Fin de escritura ?? goto Wait ;No, todavía no ha finalizado la escritura bcf EECON1,EEIF ;Reponer flag de fin de escritura bcf STATUS,RP0 ;Selección banco 0 incf FSR,F ;Si, siguiente byte a escribir incf EEADR,F ;Siguiente posición de EEPROM decfsz N_Bytes,F ;Decrementa el contador de bytes. Es 0 ?? goto EE_Write_1 ;No, faltan bytes por grabar return ;Si, fin de escritura ;************************************************************************************** ;EE_Read: Leer tantos bytes de la EEPROM de datos como se indique en la variable N_Bytes.

Page 28: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

;Se empieza a leer desde la posición 0 de la EEPROM y los datos leídos se depositan a partir ;de la posición indicada por FSR EE_Read movlw .2 movwf N_Bytes ;Nº de bytes a leer clrf EEADR ;1ª dirección EEPROM a leer movlw DIG0 movwf FSR ;1ª direección a almacenar lo leído EE_Read_1 bsf STATUS,RP0 ;Selección de banco 1 bsf EECON1,RD ;Orden de lectura bcf STATUS,RP0 ;Selección de banco 0 movf EEDATA,W movwf INDF ;Almacena dato recien leído incf EEADR,F ;Siguiente dirección de EEPROM a leer incf FSR,F ;Siguiente posición de almacenamiento

decfsz N_Bytes,F ;Se han leído todos los bytes deseados ?? goto EE_Read_1 ;No, nueva lectura return ;Si ;********************************************************************************** ;Tabla_7_seg: Esta rutina convierte el código BCD presente en los 4 bits de menos peso ;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también ;en el reg. W Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor ;del registro W retlw b'11000000' ;Código 7 seg. del dígito 0 retlw b'11111001' ;Código del 1 retlw b'10100100' ;2 retlw b'10110000' ;3 retlw b'10011001' ;4 retlw b'10010010' ;5 retlw b'10000010' ;6 retlw b'11111000' ;7 retlw b'10000000' ;8 retlw b'10011000' ;9 ;********************************************************************************** ;Display: Esta rutina activa secuencialmente cada uno de los dígitos D0 y D1 ;conectados a RA0 y RA1 respectivamente, a la vez que visualiza en cada uno de ;ellos el contenido de las variables DIG0 y DIG1, previa conversión a 7 segmentos Display bsf PORTA,0 ;Activa dígito 0 movf DIG0,W ;Carga variable DIG0 call Tabla_7_seg ;Convierte a 7 segmentos movwf PORTB ;Visualiza DIG0 sobre el dígito 0 call Delay ;Temporiza 1mS bcf PORTA,0 ;Desactiva dígito 0 movlw b'11111111' movwf PORTB ;Desactiva segmentos bsf PORTA,1 ;Activa dígito 1 movf DIG1,W ;Carga variable DIG1 call Tabla_7_seg ;Convierte a 7 segmentos

Page 29: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

movwf PORTB ;Visualiza DIG1 sobre el dígito 1 call Delay ;Temporiza 1mS bcf PORTA,1 ;Desactiva dígito 1 movlw b'11111111' movwf PORTB ;Desactiva segmentos return ;Fin del multiplexado ;********************************************************************************** ;Delay: Rutina de temporización por software. Un bucle hace decermentar una variable hasta ;alcanzar 0. El tiempo que consume su ejecución es del orden de 1mS, dado que la ejecución de ;tres instrucciones que consumen 4 uS, se repite 255 veces ; Delay clrf Delay_Fijo ;Se manda repetir el bucle 255 veces Delay_1 nop ;Consume 1 uS decfsz Delay_Fijo,F ;Consume 1 uS

goto Delay_1 ;Consume 2 uS return ;**************************************************************************************** ;Incrementa en una unidad las variables DIG0 y DIG1 con el correspondiente ajuste BCD ; Incrementa incf DIG0,F ;Incrementa DIG0 en una unidad movlw 0x0a subwf DIG0,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG0 ;Si, ajusta a 0 variable DIG0 incf DIG1,F ;Incrementa DIG1 movlw 0x0a subwf DIG1,W btfss STATUS,Z ;Es mayor de 9 ?? return ;No clrf DIG1 ;Si, ajusta a 0 variable DIG1 return Inicio movlw b'11111111' movwf PORTB ;Pone a "1" los latch de salida clrf PORTA ;Desconecta los dígitos bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011000' movwf TRISA ;RA0-RA2 se configuran como salidas movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 ;En la secuencia de inicio es necesario conocer si la EEPROM de datos contiene valores de ;contaje apropiados en sus dos primeras posiciones y que se corresponderán con DIG0 y DIG1. ;Esos valores deben estar comprendidos entre 00 y 09. En caso contrario significa que la ;memoria EEPROM de datos no ha sido utilizada o bien se empleó en otras aplicaciones. call EE_Read ;Lee los dos primeros bytes y los deposita en

Page 30: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

;las variable DIG0 y DIG1 movlw 0x09 subwf DIG0,W btfsc STATUS,C ;DIG0 > 09 ?? goto Clear ;Si, el contador a de ponerse a 00 movlw 0x09 subwf DIG1,W btfss STATUS,C ;DIG1 > 09 ?? goto Loop ;No, DIG0 y DIG1 están entre los valores correctos Clear clrf DIG0 clrf DIG1 call EE_Write ;Pone le contador a 00 Loop clrwdt ;Refresca el WDT

btfsc PORTA,4 ;Flanco ascendente en RA4 ?? goto Descendente ;Si, esperar el descendente para incrementar contador btfsc PORTA,3 ;Flanco ascendente en RA3 (borrado) ?? goto Borrar ;Si, puesta a 00 del contador call Display ;No, mantiene el refresco del display goto Loop ;Esperar Descendente bsf PORTA,2 ;Activa señal sonora clrwdt ;Refrescar el WDT btfss PORTA,4 ;Flanco descendente en RA4 goto Inc_Cont ;Si, ha habido un pulso en RA4 call Display ;No, mantiene el refresco del display goto Descendente ;Esperar Inc_Cont call Incrementa ;Incrementa el contador call EE_Write ;Actualiza el contador en la EEPROM movlw .250 movwf Delay_Cont ;Inicia variable de temporización Inc_Cont_1 clrwdt call Display ;Refresca el display (el refresco tarda 2 mS) decfsz Delay_Cont,F ;Repite el refresco 250 veces (500 mS) goto Inc_Cont_1 bcf PORTA,2 ;Desconecta la señal sonora goto Loop Borrar clrwdt call Display ;Refresca el display btfsc PORTA,3 ;Flanco descendente en RA3 ? goto Borrar ;No clrf DIG0 clrf DIG1 ;Si, borrar el contador call EE_Write goto Loop end ;Fin del programa fuente b. Archivo fuente Ensamblador .asm

Page 31: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

LIST P=16F877A #INCLUDE "P16F877A.INC" ORG 0 BSF STATUS,RP0 ;Ir al Banco 1 CLRF TRISB ;Puerto RB como Salida BCF STATUS,RP0 ;Regresar al banco 0 MOVLW 0x55 MOVWF PORTB ;Mostrar dato en el Puerto RB SLEEP ;Detener procesador END c. Archivo Listado .lst 00001 LIST P=16F877A 00002 #INCLUDE "P16F877A.INC" 00003 ORG 0

0000 1683 00004 BSF STATUS,RP0 0001 0186 00005 CLRF TRISB 0002 1283 00006 BCF STATUS,RP0 0003 3055 00007 MOVLW 0X55 0004 0086 00008 MOVWF PORTB 0005 0063 00009 SLEEP 00010 END Modificar el programa del Ejemplo de manera tal que el puerto RB muestre el dato si y solo si por el puerto RD se ingresa el primer digito del C.I. del primer integrante (ordenado alfabéticamente por apellido) del grupo de trabajo. LIST P=16F877A #INCLUDE "P16F877A.INC" ORG 0 BSF STATUS,RP0 ;Banco 1 CLRF TRISB ;PuertoB como salida MOVLW 0x0F ;0x0F a W MOVWF TRISD ;PuertoD como entrada nible bajo BCF STATUS,RP0 ;Banco 0 CLRF PORTB ;Estado bajo al puerto B CLRF PORTD BUCLE: MOVF PORTD,W ;Portd a W ANDLW 0x0F ;Enmascaramos el puerto D XORLW 0x06 ;Igualamos el numero con el carnet de identidad CI ("3") BTFSS STATUS,Z ;Verificamos si es igual GOTO RESET ;Saltar MOVLW 0X55 ;PuertoD a W MOVWF PORTB ;Mostramos en Puerto B BCF STATUS,Z ;Estado bajo a la bandera Z GOTO BUCLE ;Saltar RESET: CLRF PORTB ;Limpiar el puerto B GOTO BUCLE ;Saltar END

Page 32: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

LIST P=16F877 INCLUDE "P16F877.INC" ORG 0X000 ; ORIGEN DEL CODIGO BSF STATUS,RP0 ; IR BANCO 1 MOVLW B'00111111' ; PORTD COMO ENTRADA MOVWF TRISD CLRF TRISB ; PORTB COMO SALIDA BCF STATUS,RP0 ; IR BANCO 0 BUCLE MOVF PORTD,W ; W=PORTA MOVWF PORTB ; PORTB=W GOTO BUCLE ; IR BUCLE ;DISEÑO DE barrabas END ; FIN DEL PROGRAMA

LIST P=16F877A #INCLUDE "P16F877A.INC" ORG 0 BSF STATUS,RP0 MOVLW 0XFF MOVWF TRISB MOVLW 0X0F MOVWF TRISB BCF STATUS,RP0 CLRF PORTB ANGHEL BTFSC PORTB,0 BSF PORTB,7 BTFSS PORTB,0 BCF PORTB,7 BTFSC PORTB,1 BSF PORTB,6 BTFSS PORTB,1

Page 33: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

BCF PORTB,6 BTFSC PORTB,2 BSF PORTB,5 BTFSS PORTB,2 BCF PORTB,5 BTFSC PORTB,3 BSF PORTB,4 BTFSS PORTB,3 BCF PORTB,4 GOTO ANGHEL ; realisado por barraz

END

LIST p=16F877A #INCLUDE "P16F877A.INC" ORG 0x00 ; Inicio de programa N EQU 0x00 cont1 EQU 0x20 cont2 EQU 0x21 BCF STATUS,RP0 ; Accede a banco 0 BCF STATUS,RP1 CLRF PORTB ; Limpia PORTB BSF STATUS,RP0 ; Accede a banco 1 CLRF TRISB ; Configura todas las patitas de PORTB como salidas BCF STATUS,RP0 ; Regresa a banco 0 BARRZ MOVLW 0X01 ; La línea Rb0 de PORTB toma el valor 1, se enciende el LED MOVWF PORTB

Encledsec CALL Retardo ; Llamada a la rutina de retardo RLF PORTB,1 ; Recorre el bit de RB0 a RB7 BTFSS PORTB,7 GOTO Encledsec ; Va a la etiqueta Encledsec CALL Retardo GOTO BARRZ Retardo ; Rutina de retardo MOVLW N

Page 34: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

MOVWF cont1 Rep1 MOVLW N MOVWF cont2 Rep2 DECFSZ cont2,1 GOTO Rep2 DECFSZ cont1,1 GOTO Rep1 RETURN ; Retorno a la llamada de rutina de retardo.

;realisado por barrabas

END ; Fin de programa

LIST p=16F877A #INCLUDE "P16F877A.INC" ORG 0x00 ; Inicio de programa N EQU 0x00 cont1 EQU 0x20 cont2 EQU 0x21 BCF STATUS,RP0 ; Accede a banco 0 BCF STATUS,RP1 CLRF PORTB ; Limpia PORTB BSF STATUS,RP0 ; Accede a banco 1 CLRF TRISB ; Configura todas las patitas de PORTB como salidas BCF STATUS,RP0 ; Regresa a banco 0 MOVLW 0X01 ; La línea RB0 de PORTB toma el valor 1, se enciende el LED MOVWF PORTB Encledsec CALL Retardo ; Llamada a la rutina de retardo RLF PORTB,1 ; Recorre el bit de RB7 a RB0 BTFSS PORTB,7 GOTO Encledsec ; Va a la etiqueta Encledsec RETORNAR CALL Retardo ; Llamada a la rutina de retardo RRF PORTB,1 ; Recorre el bit de RB7 a RB0 BTFSS PORTB,0 GOTO RETORNAR ; Va a la etiqueta Encledsec

Page 35: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

GOTO Encledsec Retardo ; Rutina de retardo MOVLW N MOVWF cont1 Rep1 MOVLW N MOVWF cont2 Rep2 DECFSZ cont2,1 GOTO Rep2 DECFSZ cont1,1 GOTO Rep1 RETURN ; Retorno a la llamada de rutina de retardo.

diseño de barrabas END ; Fin de programa

LIST P=16F877A #INCLUDE "P16F877A.INC" var1 EQU 0x20 var2 EQU 0x21 ORG 0 BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 CLRF PORTB UNOS: BSF STATUS,C RLF PORTB,F CALL ESPERA MOVF PORTB,W XORLW 0xFF BTFSS STATUS,Z GOTO UNOS CEROS: BCF STATUS,C RRF PORTB,F CALL ESPERA MOVF PORTB,W XORLW 0 BTFSS STATUS,Z GOTO CEROS GOTO UNOS ESPERA: DECFSZ var1,F GOTO ESPERA

Page 36: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

DECFSZ var2,F GOTO ESPERA RETURN END

2. Archivo fuente Ensamblador .asm

Modificar el programa del Ejemplo añadiendo un switch en el pin RD.0 de manera tal que si el valor ingresado por el switch es 1, entonces el conteo se realiza en forma ASCENDENTE de otra manera el conteo se realiza en forma DESCENDENTE. LIST P=16F877A #INCLUDE "P16F877A.INC" AUX1 EQU 0X20 AUX2 EQU 0X21 ORG 0 BSF STATUS,RP0 MOVLW 0X00 MOVWF TRISB BCF STATUS,RP0 CLRF PORTB CASA: PRUEBA: CALL RETARDO INCF PORTB,F BTFSC PORTD, 0 ; comprueba el estado del bit 0 del puerto A GOTO PRUEBA ; si no cambia, vuelve a comprobarlo LAZO:

Page 37: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

CALL RETARDO ; Llamada a la rutina de retardo DECF PORTB,F BTFSS PORTD,0 GOTO LAZO ; Va a la etiqueta Encledsec GOTO CASA RETARDO MOVLW 0 MOVWF AUX2 MOVWF AUX1 RET1: DECFSZ AUX1,F GOTO RET1

DECFSZ AUX2,F GOTO RET1 RETURN ;DISEÑO DE BARRAZ END a) Se compara el dato del puerto de entrada PORTC con el número 13. Pueden darse tres posibilidades en la salida de RB: Si PORTC es igual a 13, todos los leds se encienden y el programa termina. Si PORTC es mayor a 13, en el puerto RB.0 se muestra la secuencia de leds donde 1 led se desplaza de izquierda a derecha partiendo en el bit 0 y terminando en bit7 (añadir el retardo necesario para visualizar la secuencia). Si PORTC es menor a 13 todos los leds de salida parpadean 5 veces y luego se apagan. LIST P=16F877A #INCLUDE "P16F877A.INC" AUX1 EQU 0X20 AUX2 EQU 0X21 CONT EQU 0X22 ORG 0 BSF STATUS,RP0 MOVLW 0XFF MOVWF TRISC MOVLW 0X00 MOVWF TRISB BCF STATUS,RP0 CLRF PORTB MOVF PORTC,W ANDLW 0X0F SUBLW .13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Page 38: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

BTFSS STATUS,C CALL ROTACION BTFSC STATUS,Z CALL TERMINA BTFSC STATUS,C CALL PARPADEA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ROTACION BSF PORTB,0 ; La línea RB0 de PORTB toma el valor 1, se enciende el LED Encledsec:

CALL RETARDO ; Llamada a la rutina de retardo RLF PORTB,1 ; Recorre el bit de RB7 a RB0 BTFSS PORTB,7 GOTO Encledsec ; Va a la etiqueta Encledsec RETORNAR: CALL RETARDO ; Llamada a la rutina de retardo RRF PORTB,1 ; Recorre el bit de RB7 a RB0 BTFSS PORTB,0 GOTO RETORNAR ; Va a la etiqueta Encledsec GOTO Encledsec RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PARPADEA movlw 5 movwf CONT CASA CALL RETARDO MOVLW 0XFF ; MOVWF PORTB CALL RETARDO MOVLW 0X00 MOVWF PORTB DECFSZ CONT,f GOTO CASA SLEEP RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TERMINA MOVLW 0XFF MOVWF PORTB SLEEP RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RETARDO MOVLW 0

Page 39: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

MOVWF AUX2 MOVWF AUX1 RET1: DECFSZ AUX1,F GOTO RET1 DECFSZ AUX2,F GOTO RET1 RETURN ;DISEÑO DE BARRAZ END b) Se leen las tres líneas más bajas del puerto RC, que fijan el número de leds que se iluminarán a

la salida del puerto RB. Así por ejemplo, si lee el dato 5, en los leds conectados al puerto B se iluminarán los primeros 5 leds ‘00011111’ LIST P=16F877A #INCLUDE "P16F877A.INC" ORG 0 BSF STATUS,RP0 MOVLW 0XFF MOVWF TRISC CLRF TRISB BCF STATUS,RP0 CLRF PORTB PRINCIPAL: MOVF PORTC,W ANDLW 0X07 MOVWF 20H CLRF 21H MOVF 20H,F BTFSC STATUS,Z GOTO SALIDA DESPL_OTRAVEZ: BSF STATUS,C RLF 21H,F DECFSZ 20H,F GOTO DESPL_OTRAVEZ SALIDA: MOVF 21H,W MOVWF PORTB GOTO PRINCIPAL

Page 40: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

;DISEÑO DE BARRAZ END c) A través de un pulsador conectado al bit RD.0 se muestran en los 4 leds conectados a RC, el número de pulsos ingresados. Cuan este número supera 15 los leds parpadean 3 veces y luego el programa termina. LIST P=16F877A #INCLUDE "P16F877A.INC" AUX1 EQU 0X21 AUX2 EQU 0X22 CONT EQU 0X23 ORG 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BSF STATUS,RP0 MOVLW 0XFF MOVWF TRISD MOVLW 0XF0 MOVWF TRISC BCF STATUS,RP0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CLRF PORTC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PRINCIPAL: NADA: MOVWF 21H MOVF PORTD,W BTFSC PORTD,0 GOTO NADA MOVF 21H,W ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ANDLW 0X01 ADDWF 20H,1 MOVF 20H,F ;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOVF 20H,W MOVWF PORTC SUBLW .16 BTFSC STATUS,Z CALL PARPADEA CLRW CLRF 21H GOTO PRINCIPAL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PARPADEA movlw 3 movwf CONT CASA CALL RETARDO MOVLW 0XFF ;

Page 41: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

MOVWF PORTC CALL RETARDO MOVLW 0X00 MOVWF PORTC DECFSZ CONT,f GOTO CASA CLRF 20H SLEEP RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RETARDO MOVLW 0 MOVWF AUX2 MOVWF AUX1

RET1: DECFSZ AUX1,F GOTO RET1 DECFSZ AUX2,F GOTO RET1 RETURN ;DISEÑO DE BARRAZ END d) Se obtiene un valor de temperatura en grados Fahrenheit (F) de los 4 bits inferiores del puerto D (RD0 a RD3). Se convierte este valor a grados Celsius (C). El resultado se muestra en los 8 bits del puerto B (RB0 a RB7) LIST P=16F877A #INCLUDE "P16F877A.INC" VAR EQU 0x20 ORG 0 BSF STATUS,RP0 CLRF TRISB MOVLW 0x0F MOVWF TRISD BCF STATUS,RP0 CLRF PORTB CLRF PORTD BUCLE: MOVF PORTD,W MOVWF VAR COMF VAR,F ;RESTA AL W MOVLW .1 ;RESTA AL W ADDWF VAR,W ;RESTA AL W ADDLW .32 MOVWF VAR RRF VAR,F MOVF VAR,W MOVWF PORTB goto BUCLE ;SLEEP ;DISEÑO DE BARRAZ END

Page 42: Tutorial Asm Pic16f84 y Pic16f877a

ASM MICROPROCESADORES I

SU AMIGABLE BESINO: ANGHEL PMQ

e) Se tienen 2 pulsadores en RD.0 y RD.1. Al presionar el pulsador en RD.0 el número mostrado en los leds en RC se incrementa. Al presionar el pulsador en RD.1 el número mostrado en los leds en RC se decrementa. Si se presionan ambos pulsadores, los leds se apagan y el programa termina. LIST P=16F877A #INCLUDE "P16F877A.INC" AUX1 EQU 0X20 AUX2 EQU 0X21 ORG 0 BSF STATUS,RP0 MOVLW 0X00 MOVWF TRISB BCF STATUS,RP0

CLRF PORTB PRUEBA: CALL RETARDO ; Llamada a la rutina de retardo BTFSC PORTD,1 ; comprueba el estado del bit 1 del puerto DECF PORTB,F ; DECREMENTA EN PUERTO PORTB BTFSS PORTD,0 ; comprueba el estado del bit 0 del puerto GOTO PRUEBA ; si no cambia, vuelve a comprobarlo LAZO: CALL RETARDO ; Llamada a la rutina de retardo BTFSC PORTD,0 ; comprueba el estado del bit 0 del puerto INCF PORTB,F ; INCREMENTA EN PUERTO PORTB BTFSS PORTD,1 ; comprueba el estado del bit 1 del puerto GOTO LAZO ; si no cambia, vuelve a comprobarlo BTFSS PORTD,0 ; comprueba el estado del bit 0 del puerto GOTO PRUEBA ; Va a la etiqueta CLRF PORTB SLEEP RETARDO MOVLW 0 MOVWF AUX2 MOVWF AUX1 RET1: DECFSZ AUX1,F GOTO RET1 DECFSZ AUX2,F GOTO RET1 RETURN ;DISEÑO DE BARRAZ END