Está en la página 1de 30

;

; PRACTICA 1
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;
;Leer el estado de los 5 interruptores E0-E4 conectados a RA0-RA4 y reflejar el nivel lgico 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 definicin
con los nombres
;de los registros internos

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Una lmpara conectada en RB0 se controla mediante dos interruptores conectados en RA0 y RA1.
;Cuando cualquiera de los interruptores cambie de estado, la lmpara tambin lo har.

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Incluye el fichero P16F84.INC que contiene la definicin
;con los nombres de los registros internos
Temp equ 0x0c ;Variable temporal que se almacena en la posicin 0x0c

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

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 informacin leda 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 lmpara se apaga
movlw b'00000001'
subwf Temp,W
btfsc STATUS,Z ;RA0=1 y RA1=0 ??
goto Encender ;Si, la lmpara se enciende
movlw b'00000010'
subwf Temp,W
btfsc STATUS,Z ;RA0=0 y RA1=1 ??
goto Encender ;Si, la lmpara se enciende

Apagar bcf PORTB,0 ;No, la lmpara se apaga

goto Loop

Encender bsf PORTB,0 ;La lmpara se enciende

goto Loop

end ;Fin del programa fuente


;
; PRACTICA 3
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Programa combinacional
;
;Segn 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
; 1 1 1 1 1 1 0 0 0 0

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Incluir la definicin de los registros internos
Temp equ 0x0c ;Variable temporal

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

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 ;Estn a 00 ?
goto Secuencia_00 ;Si
movlw b'00000001'
subwf Temp,W
btfsc STATUS,Z ;Estn a 01 ?
goto Secuencia_01 ;Si
movlw b'00000010'
subwf Temp,W
btfsc STATUS,Z ;Estn 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

;
; PRACTICA 4
;
; Autor: Mikel Etxebarria
; (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 transicin a "1" en RA0 provoca su activacin, una transicin en RA0
;su desactivacin.

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Incluir la definicin de los registros internos

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

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 tambin en ON ??


goto Alarma_Off ;Si, desconectar alarma
bsf PORTB,0 ;No, activar alarma
goto Loop

end ;Fin del programa fuente

;
; PRACTICA 5
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Empleando el TMR0; juego de luces
;
;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 definicin de los registros internos

Temp equ 0x0c ;Variable temporal


Delay equ 0x0d ;Variable para temporizacin

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

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 temporizacin 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, todava no han transcurrido los 50 mS
decfsz Delay,F ;Se ha repetido 2 veces la temporizacin 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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Usando el preescaler, ms juego de luces
;
;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 funcin 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 temporizacin mnima es
;de 20mS (preesacler 1:2) y la mxima 2.5" (preescaler 1:256)

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Incluir la definicin de los registros internos

Temp equ 0x0c ;Variable temporal


Delay equ 0x0d ;Variable para temporizacin

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

Inicio clrf PORTB ;Borra los latch de salida


bsf STATUS,RP0 ;Selecciona banco 1
movlw b'00000111'
movwf TRISA ;RA0-RA2 actan 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 segn las entradas
bcf STATUS,RP0 ;Selecciona el banco 0
movf Temp,W
movwf PORTB ;Salida del valor correspondiente
movlw .200
movwf Delay ;Una temporizacin 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, todava no han transcurrido los 50 mS
decfsz Delay,F ;Se ha repetido 200 veces la temporizacin 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

;
; PRACTICA 7
;
; Autor: Mikel Etxebarria
; (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 instruccin 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 situacind de standby.
;
;El preescaler se asociar al WDT y estar comprendido entre 1 y 128, dependiendo del estado
;lgico 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 interrupcin

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

;
; PRACTICA 8
;
; Autor: Mikel Etxebarria
; (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 nmero 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 interrupcin

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 ledo (el TMR0 es ascendente)
addlw .1
movwf TMR0 ;Carga el TMR0 con el valor ledo
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 temporizacin
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

;
; PRACTICA 9
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;
;La interrupcin del TMR0.
;
;Se trata de comprobar la interrupcin 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 interrupcin 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 temporizacin


Temp_2 equ 0x0d ;Registro temporal

org 0x00 ;Vector de Reset


goto Inicio

org 0x04 ;Vector de interrupcin

;Programa de tratamiento de la interrupcin

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 interrupcin 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 interrupcin

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 interrupcin 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
;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 interrupcin
movlw b'10100000'
movwf INTCON ;Activa la interrupcin 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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;
;Otras interrupciones
;
;Los dispositivos PIC pueden provocar interrupcin por otras dos causas diferentes adems de
;por la del TMR0. Una de ellas es por la deteccin de una seal de un determinado flanco por
;la entrada RB0/INT. La otra es por el cambio de estado lgico producido en cualquiera de las
;lneas de entrada RB4-RB7.
;
;El ejemplo pretende mostrar la deteccin y tratamiento de cada una de estas nuevas fuentes de
;interrupcin. Cuando se produce la interrupcin RB0/INT se activa la salida RA0 durante 1".
;Cuando se produce la interrupcin 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 temporizacin

org 0x00 ;Vector de Reset


goto Inicio

org 0x04 ;Vector de interrupcin

;Programa de tratamiento de la interrupcin

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 interrupcin

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 interrupcin.
;De esta forma se evitan posibles rebotes que puediera haber en las entradas.

Fin movlw .20 ;Comienza una temporizacin 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 temporizacin de 50mS
btfss INTCON,T0IF ;Fin de los 50 mS ??
goto Delay_50mS ;Todava 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 interrupcin por cambio en RB4-RB7. Hay que
;hacerlo en este rden

bcf INTCON,INTF ;Repone el flag de interrupcin por RBO/INT


retfie ;Retorno de interrupcin

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

;
; PRACTICA 11
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Decodificador BCD a 7 segmentos
;
;Mediante los cuatro interruptores conectador a RA0-RA3 se aplica el cdigo BCD de los nmeros
;comprendidos entre 0 y 9. El programa obtiene el cdigo de 7 segmentos para representar dicho
;nmero sobre un display de nodo comn, en el que cada segmento particular se activa mediante
;nivel lgico "0"

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Incluir la definicin de los registros internos

Temp equ 0x0c ;Variable temporal

org 0x00 ;Vector de Reset


goto Inicio

org 0x05 ;Salva el vector de interrupcin

Tabla_7_seg addwf PCL,F ;Desplaza al PC tantas posiciones como indique el valor


;del registro W
retlw b'11000000' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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 ledo
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 ??
goto NULO ;Si

movf Temp,W
call Tabla_7_seg ;Convierte el valor a cdigo 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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Contador UP/DOWN decimal de un dgito
;
;Sobre el display 7 segmentos conectado a la puerta B se visualizar el nmero 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 interrupcin

;**********************************************************************************
;Tabla_7_seg: Esta rutina convierte el cdigo BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El cdigo 7 segmentos retorna tambin
;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' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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'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 seal 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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;
;Generacin de nmeros aleatorios. El dado electrnico
;
;Se trata de generar un nmero 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 nmeros del 1 al 6, con intervalos de 0.05". Al pasar RA0 a nivel "0", se visualiza
;el nmero 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 ;Nmero 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 interrupcin

;**********************************************************************************
;Tabla_7_seg: Esta rutina convierte el cdigo BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El cdigo 7 segmentos retorna tambin
;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' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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 propsito general realiza una temporizacin 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 mnimo
;es de 50 mS ("Delay_cont=1) y el mxima 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 ;Todava 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
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 ;Todava No
movf TMR0,W ;Ahora si.
movwf Numero ;Captura el valor del TMR0 (N aleatorio)

;El nmero 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 nmero entre 1 y 6

Divide: movlw .6
subwf Numero,W ;Resta 6 al nmero aleatorio
movwf Numero ;lo guarda
sublw .5
btfss STATUS,C ;Mira si es menor de 5
goto Divide ;No
incf Numero,F ;El nmero queda entre 1 y 6

;Esta secuencia de instrucciones tiene por misin presentar sobre el display los nmeros
;del 1 al 6 a intervalos de 0.05" con objeto de dar una sensacin de movimiento del dado.
;Dicho movimiento se mantiene mientras RA0 est a "1". Al ponerse a "0" se presenta el
;nmero 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 ;Nmero a visualizar
call Tabla_7_seg ;Conversin a BCD
movwf PORTB ;Visualiza sobre el display
movlw .1
movwf Delay_Cont ;Variable de temporizacin
call Delay_var ;temporiza 0.05"
decfsz Temporal,F ;Siguiente nmero
goto RA0_1
goto Dado

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 temporizacin
call Delay_var ;Temporiza 3"
movlw b'11111111'
movwf PORTB ;Apaga el display

goto Loop

end ;Fin del programa fuente

;
; PRACTICA 14
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Multiplexado de displays
;
;El ejemplo presenta un subrutina que realiza el multiplexado o barrido de 3 displays de
;nodo comn 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 dgito 0


DIG1 equ 0x0d ;Variable para el dgito 1
DIG2 equ 0x0e ;Variable para el dgito 2
Delay_Fijo equ 0x0f ;Variable para temporizacin fija
Delay_Cont equ 0x10 ;Variable para temporizacin variable

org 0x00 ;Vector de Reset


goto Inicio
org 0x05 ;Salva vector de interrupcin

;**********************************************************************************
;Tabla_7_seg: Esta rutina convierte el cdigo BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El cdigo 7 segmentos retorna tambin
;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' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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 dgitos 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 conversin a 7 segmentos

Display bsf PORTA,0 ;Activa dgito 0


movf DIG0,W ;Carga variable DIG0
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG0 sobre el dgito 0
call Delay ;Temporiza 1mS
bcf PORTA,0 ;Desactiva dgito 0
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,1 ;Activa dgito 1
movf DIG1,W ;Carga variable DIG1
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG1 sobre el dgito 1
call Delay ;Temporiza 1mS
bcf PORTA,1 ;Desactiva dgito 1
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,2 ;Activa dgito 2
movf DIG2,W ;Carga variable DIG2
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG2 sobre el dgito 2
call Delay ;Temporiza 1mS
bcf PORTA,2 ;Desactiva dgito 2
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
return ;Fin del multiplexado

;**********************************************************************************
;Delay: Rutina de temporizacin por software. Un bucle hace decermentar una variable hasta
;alcanzar 0. El tiempo que consume su ejecucin es del orden de 1mS, dado que la ejecucin 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 propsito general realiza una temporizacin 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
;tantes veces como indique la variable "Delay_cont", es por ello que el delay mnimo
;es de 5 mS ("Delay_cont=1) y el mxima 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 ;Todava 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 dgitos
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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Contador UP/DOWN de 3 dgitos
;
;Se trata de un contador UP/DOWN de 3 dgitos 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"

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Definiciones de registros internos

DIG0 equ 0x0c ;Variable para el dgito 0


DIG1 equ 0x0d ;Variable para el dgito 1
DIG2 equ 0x0e ;Variable para el dgito 2
Delay_Fijo equ 0x0f ;Variable para temporizacin fija

org 0x00 ;Vector de Reset


goto Inicio
org 0x05 ;Salva vector de interrupcin

;**********************************************************************************
;Tabla_7_seg: Esta rutina convierte el cdigo BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El cdigo 7 segmentos retorna tambin
;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' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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 dgitos 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 conversin a 7 segmentos

Display bsf PORTA,0 ;Activa dgito 0


movf DIG0,W ;Carga variable DIG0
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG0 sobre el dgito 0
call Delay ;Temporiza 1mS
bcf PORTA,0 ;Desactiva dgito 0
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,1 ;Activa dgito 1
movf DIG1,W ;Carga variable DIG1
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG1 sobre el dgito 1
call Delay ;Temporiza 1mS
bcf PORTA,1 ;Desactiva dgito 1
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,2 ;Activa dgito 2
movf DIG2,W ;Carga variable DIG2
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG2 sobre el dgito 2
call Delay ;Temporiza 1mS
bcf PORTA,2 ;Desactiva dgito 2
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
return ;Fin del multiplexado

;**********************************************************************************
;Delay: Rutina de temporizacin por software. Un bucle hace decermentar una variable hasta
;alcanzar 0. El tiempo que consume su ejecucin es del orden de 1mS, dado que la ejecucin 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
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 dgitos
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

;
; PRACTICA 16
;
; Autor: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;Cronmetro digital
;
;Se trata de un cronmetro capaz de medir lapsus de tiempo de hasta 99.9 segundos. El pulsador
;conectado a RA4 acta de START/STOP mientras que RA3 acta como puesta a 00.0

List p=16F84 ;Tipo de procesador


include "P16F84.INC" ;Definiciones de registros internos

DIG0 equ 0x0c ;Variable para el dgito 0


DIG1 equ 0x0d ;Variable para el dgito 1
DIG2 equ 0x0e ;Variable para el dgito 2
Delay_Fijo equ 0x0f ;Variable para temporizacin 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 temporizacin

org 0x00 ;Vector de Reset


goto Inicio
org 0x04
goto Interrupcion ;Vector de interrupcin
org 0x05 ;Salva vector de interrupcin

;**********************************************************************************
;Tabla_7_seg: Esta rutina convierte el cdigo BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El cdigo 7 segmentos retorna tambin
;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' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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 dgitos 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 conversin a 7 segmentos

Display bsf PORTA,0 ;Activa dgito 0


movf DIG0,W ;Carga variable DIG0
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG0 sobre el dgito 0
call Delay ;Temporiza 1mS
bcf PORTA,0 ;Desactiva dgito 0
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,1 ;Activa dgito 1
movf DIG1,W ;Carga variable DIG1
call Tabla_7_seg ;Convierte a 7 segmentos
andlw b'01111111' ;Activa el punto decimal en el dgito 1
movwf PORTB ;Visualiza DIG1 sobre el dgito 1
call Delay ;Temporiza 1mS
bcf PORTA,1 ;Desactiva dgito 1
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,2 ;Activa dgito 2
movf DIG2,W ;Carga variable DIG2
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG2 sobre el dgito 2
call Delay ;Temporiza 1mS
bcf PORTA,2 ;Desactiva dgito 2
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
return ;Fin del multiplexado

;**********************************************************************************
;Delay: Rutina de temporizacin por software. Un bucle hace decermentar una variable hasta
;alcanzar 0. El tiempo que consume su ejecucin es del orden de 1mS, dado que la ejecucin 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

;***************************************************************************************
;Interrupcin: 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 interrupcin 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 interrupcin
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 temporizacin
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 cronmetro
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 dgitos
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
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 (interrupcin cada 50mS)
movlw .2
movwf Delay_Cont ;Inicia variable de temporizacin
bsf INTCON,T0IE ;Habilita interrupcin del TMR0
bsf INTCON,GIE ;Permiso general de interrupciones

Crono_Fin clrwdt
btfsc PORTA,4 ;Flanco ascendente en RA4 ?
goto STOP ;Si, parada del cronmetro
call Display ;No, mantiene el refresco del display
goto Crono_Fin ;Sigue cronometrando

;Secuencia de parada del cronmetro y puesta a 000

STOP bcf INTCON,GIE ;Se detiene la interrupcin del TMR0


Fin_1 clrwdt
btfss PORTA,4 ;Flanco descendente de RA4 ??
goto Fin_2 ;Si
call Display ;An 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 cronmetro
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: Mikel Etxebarria
; (c) Microsystems Engineering (Bilbao)
;
;La memoria EEPROM de datos. La mquina "Su Turno"
;
;Sobre los display D0 y D1 se visualiza el nmero 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 seal
;acstica 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 alimentacin, 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 dgito 0


DIG1 equ 0x0d ;Variable para el dgito 1
Delay_Fijo equ 0x0e ;Variable para temporizacin fija
Delay_Cont equ 0x0f ;Variable de temporizacin
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 interrupcin

;****************************************************************************************
;EE_Write: Graba n bytes a partir de la primera posicin de la EEPROM de datos. El nmero
;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 ;Direccin 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, todava no ha finalizado la escritura
bcf EECON1,EEIF ;Reponer flag de fin de escritura
bcf STATUS,RP0 ;Seleccin banco 0
incf FSR,F ;Si, siguiente byte a escribir
incf EEADR,F ;Siguiente posicin 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.
;Se empieza a leer desde la posicin 0 de la EEPROM y los datos ledos se depositan a partir
;de la posicin indicada por FSR

EE_Read movlw .2
movwf N_Bytes ;N de bytes a leer
clrf EEADR ;1 direccin EEPROM a leer
movlw DIG0
movwf FSR ;1 direeccin a almacenar lo ledo
EE_Read_1 bsf STATUS,RP0 ;Seleccin de banco 1
bsf EECON1,RD ;Orden de lectura
bcf STATUS,RP0 ;Seleccin de banco 0
movf EEDATA,W
movwf INDF ;Almacena dato recien ledo
incf EEADR,F ;Siguiente direccin de EEPROM a leer
incf FSR,F ;Siguiente posicin de almacenamiento
decfsz N_Bytes,F ;Se han ledo todos los bytes deseados ??
goto EE_Read_1 ;No, nueva lectura
return ;Si

;**********************************************************************************
;Tabla_7_seg: Esta rutina convierte el cdigo BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El cdigo 7 segmentos retorna tambin
;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' ;Cdigo 7 seg. del dgito 0
retlw b'11111001' ;Cdigo 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 dgitos 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 conversin a 7 segmentos

Display bsf PORTA,0 ;Activa dgito 0


movf DIG0,W ;Carga variable DIG0
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG0 sobre el dgito 0
call Delay ;Temporiza 1mS
bcf PORTA,0 ;Desactiva dgito 0
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
bsf PORTA,1 ;Activa dgito 1
movf DIG1,W ;Carga variable DIG1
call Tabla_7_seg ;Convierte a 7 segmentos
movwf PORTB ;Visualiza DIG1 sobre el dgito 1
call Delay ;Temporiza 1mS
bcf PORTA,1 ;Desactiva dgito 1
movlw b'11111111'
movwf PORTB ;Desactiva segmentos
return ;Fin del multiplexado

;**********************************************************************************
;Delay: Rutina de temporizacin por software. Un bucle hace decermentar una variable hasta
;alcanzar 0. El tiempo que consume su ejecucin es del orden de 1mS, dado que la ejecucin 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 dgitos
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 correspondern 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


;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 estn 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 seal 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 temporizacin
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 seal 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

También podría gustarte