codigo para el 16f84

; ; PRACTICA 1 ; ; Autor: Mikel Etxebarria ; (c) Microsystems Engineering (Bilbao) ; ; ;Leer el estado de los 5 interrup

Views 80 Downloads 0 File size 85KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

; ; 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 lógico de ;los mismos sobre los leds S0-S4 conectados en RB0-RB4 List p=16F84 include "P16F84.INC" con los nombres

Inicio

Loop

;Tipo de procesador ;Incluye el fichero P16F84.INC que contiene la definición ;de los registros internos

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

clrf bsf clrf movlw movwf bcf

PORTB STATUS,RP0 TRISB b'00011111' TRISA STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1 de la memoria de datos ;Puerta B se configura como salida

movf movwf goto

PORTA,W PORTB Loop

;Leer las entradas RA0-RA4 ;Reflejar en las salidas ;Bucle sin fin

end

;Puerta A se configura como entrada ;Selecciona banco 0 de la memoria de datos

;Fin del programa fuente

; ; PRACTICA 2 ; ; Autor: Mikel Etxebarria ; (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 include "P16F84.INC" Temp

Inicio

Loop de RA0 y RA1

Apagar

Encender

;Tipo de procesador ;Incluye el fichero P16F84.INC que contiene la definición ;con los nombres de los registros internos ;Variable temporal que se almacena en la posición 0x0c

equ

0x0c

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

clrf bsf clrf movlw movwf bcf

PORTB STATUS,RP0 TRISB b'00000011' TRISA STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1 de la memoria de datos ;Puerta B se configura como salida

clrf

Temp

;Pone a 0 el registo o variable temporal

movf andlw

PORTA,W b'00000011'

;Leer el estado de la puerta A ;Filtra la información leída y nos quedamos con el estado

movwf btfsc goto movlw subwf btfsc goto movlw subwf btfsc goto

Temp STATUS,Z Apagar b'00000001' Temp,W STATUS,Z Encender b'00000010' Temp,W STATUS,Z Encender

;Almacena temporalmente ;RA0=0 y RA1=0 ?? ;Si, la lámpara se apaga

bcf

PORTB,0

;No, la lámpara se apaga

goto

Loop

bsf

PORTB,0

goto

Loop

end

;RA0 y RA1 se configuran como entrada ;Selecciona banco 0 de la memoria de datos

;RA0=1 y RA1=0 ?? ;Si, la lámpara se enciende ;RA0=0 y RA1=1 ?? ;Si, la lámpara se enciende

;La lámpara se enciende

;Fin del programa fuente

; ; PRACTICA 3 ; ; Autor: Mikel Etxebarria ; (c) Microsystems Engineering (Bilbao) ; ;Programa combinacional ; ;Según el estado de los interruptores RA0 y RA1, activar los ;puerta B, conforme a la siguiente tabla de la verdad: ; ; RA1 RA0 RB7 RB6 RB5 RB4 ; ------; 0 0 1 0 1 0 ; 0 1 0 1 0 1 ; 1 0 0 0 0 0 ; 1 1 1 1 1 1

Temp

Inicio

Loop:

leds RB0-RB7 conectados a la RB3 -1 0 1 0

RB2 -0 1 1 0

RB1 -1 0 1 0

RB0 -0 1 1 0

List p=16F84 include "P16F84.INC" equ 0x0c

;Tipo de procesador ;Incluir la definición de los registros internos ;Variable temporal

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

clrf bsf clrf movlw movwf movlw movwf bcf

PORTB STATUS,RP0 TRISB b'00001001' OPTION_REG b'00000011' TRISA STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida

clrwdt movf andlw movwf btfsc goto movlw

PORTA,W b'00000011' Temp STATUS,Z Secuencia_00 b'00000001'

;Preescaler de 1:2 asociado al WDT ;RA0 y RA1 se configuran como entrada ;Selecciona banco 0 ;Refrescar el WDT ;Carga el valor de la PUERTA A ;Filtra el estado de RA0 y RA1 ;Almacena temporalmente ;Están a 00 ? ;Si

subwf btfsc goto movlw subwf btfsc goto

Temp,W STATUS,Z Secuencia_01 b'00000010' Temp,W STATUS,Z Secuencia_10

Secuencia_11

movlw movwf goto

b'11110000' PORTB Loop

;Salida de la secuencia 11

Secuencia_00

movlw movwf goto

b'10101010' PORTB Loop

;Salida de la secuencia 00

Secuencia_01

movlw movwf goto

b'01010101' PORTB Loop

;Salida de la secuencia 01

Secuencia_10

movlw movwf goto

b'00001111' PORTB Loop

;Salida de la secuencia 10

end

;Están a 01 ? ;Si ;Están a 10 ? ;Si

;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 transición a "1" en RA0 provoca su activación, una transición en RA0 ;su desactivación.

Inicio

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Incluir la definición de los registros internos

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

clrf bsf clrf movlw movwf

PORTB STATUS,RP0 TRISB b'00001001' OPTION_REG

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Preescaler de 1:2 asociado al WDT

movlw movwf bcf

b'00000011' TRISA STATUS,RP0

;RA0 y RA1 se configuran como entrada ;Selecciona banco 0

Loop:

clrwdt btfsc goto btfss goto

PORTA,0 Alarma_On PORTA,1 Loop

;Refrescar el WDT ;RA0=1 ?? ;Si ;RA1=1 ?? ;No

Alarma_Off

bcf goto

PORTB,0 Loop

;Si, conecta la alarma

Alarma_On

btfsc goto bsf goto

PORTA,1 Alarma_Off PORTB,0 Loop

;RA1 también en ON ?? ;Si, desconectar alarma ;No, activar alarma

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

Temp Delay

Inicio

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Incluir la definición de los registros internos

equ equ

0x0c 0x0d

;Variable temporal ;Variable para temporización

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

clrf bsf clrf movlw movwf bcf

PORTB STATUS,RP0 TRISB b'00000111' OPTION_REG STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Preescaler de 1:256 asociado al TMR0 ;Selecciona banco 0

Loop Loop_0 Loop_1

movlw movwf bcf

b'00000001' Temp STATUS,C

movwf movlw movwf movlw movwf bcf clrwdt btfss goto decfsz goto rlf movf goto

PORTB .2 Delay ~.195 TMR0 INTCON,T0IF INTCON,T0IF Loop_1 Delay,F Loop_0 Temp,F Temp,W Loop

end

;1er. valor a sacar ;Salida del valor correspondiente ;Una temporización de 50 mS se repetirá 2 veces ;Carga el TMR0 con el complemento del valor 195 ;Restaura el flag de desbordamiento del TMR0 ;Refrescar el WDT ;Se ha desbordado el TMR0 ?? ;No, todavía no han transcurrido los 50 mS ;Se ha repetido 2 veces la temporización de 50 mS (0.1") ;No ;Si, Desplaza a la izquierda para obtener el siguiente ;valor a sacar por la puerta B ;Fin del programa fuente

; ; PRACTICA 6 ; ; Autor: Mikel Etxebarria ; (c) Microsystems Engineering (Bilbao) ; ;Usando el preescaler, más 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 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

Temp Delay

Inicio

Loop

Loop_0 Loop_1

include "P16F84.INC"

;Incluir la definición de los registros internos

equ equ

0x0c 0x0d

;Variable temporal ;Variable para temporización

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

clrf bsf movlw movwf clrf bcf

PORTB STATUS,RP0 b'00000111' TRISA TRISB STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1

movlw movwf bcf

b'00000001' Temp STATUS,C

movf andlw bsf movwf bcf movf movwf movlw movwf movlw movwf bcf clrwdt btfss goto decfsz goto rlf goto

PORTA,W b'00000111' STATUS,RP0 OPTION_REG STATUS,RP0 Temp,W PORTB .200 Delay ~.50 TMR0 INTCON,T0IF

end ; ; ; ; ; ;

INTCON,T0IF Loop_1 Delay,F Loop_0 Temp,F Loop

;RA0-RA2 actúan como entradas ;Puerta B se configura como salida ;Selecciona banco 0 ;1er. valor a sacar ;Lee las entradas RA0-RA2 ;Selecciona banco 1 ;Ajusta valor del preescaler según las entradas ;Selecciona el banco 0 ;Salida del valor correspondiente ;Una temporización de 50 eventos se repetirá 200 veces ;Carga el TMR0 con el complemento del valor 50 ;Restaura el flag de desbordamiento del TMR0 ;Refrescar el WDT ;Se ha desbordado el TMR0 ?? ;No, todavía no han transcurrido los 50 mS ;Se ha repetido 200 veces la temporización de 50 eventos ? ;No ;Si, Desplaza a la izquierda para obtener el siguiente ;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 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.

Inicio

Loop

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

org goto org

0x00 Inicio 0x05

;Vector de Reset

clrf bsf clrf movlw movwf movlw movwf bcf

PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00001000' OPTION_REG STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida

sleep incf movf andlw iorlw bsf movwf bcf goto end

;Salva vector de interrupción

;RA0-RA4 entradas ;Preescaler de 1 para el WDT ;Selecciona banco 0 ;Modo Standby

PORTB,F PORTA,W b'00000111' b'00001000' STATUS,RP0 OPTION_REG STATUS,RP0 Loop

;Incrementa el contador binario sobre la puerta B ;Lee el estado de los interruptores RA0-RA2 ;Selecciona el banco 1 ;Ajusta valor del preescaler ;Selecciona el banco 1 ;Volver al modo Standby ;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 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

Inicio

Loop

Espera

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

org goto org

0x00 Inicio 0x05

;Vector de Reset

clrf bsf clrf movlw movwf movlw movwf

PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00111111' OPTION_REG

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida

bcf

STATUS,RP0

movf andlw xorlw addlw movwf bsf bcf

PORTA,W b'00001111' b'11111111' .1 TMR0 PORTB,1 INTCON,T0IF

;RA0-RA4 entradas ;Preescaler de 256 para el WDT. El TMR0 evoluciona a ;cada flanco descendente aplicado por RA4 ;Selecciona banco 0 ;Lee las entradas RA0-RA3 ;Complementa el valor leído (el TMR0 es ascendente) ;Carga el TMR0 con el valor leído ;Activa la entrada de pulsos a contar ;Repone el flag del TMR0

clrwdt btfss INTCON,T0IF goto Espera

;Refresca el WDT ;Ha finalizado la cuenta ?? ;No

bcf PORTB,1 bsf PORTB,0 clrwdt sleep

;Desconecta la entrada de pulsos a contar ;Activa la salida a relé, led, etc. ;El WDT se refresca y comienza la temporización ;El modo standby se mantiene hasta que el WDT desborde ;transcurridos aprox. 2" (18mS*256 de preescaler)

bcf goto

;Desactiva la salida a relé, led, etc.

end

; ; ; ;

;Salva vector de interrupción

PORTB,0 Loop

;Fin del programa fuente

PRACTICA 9 Autor: Mikel Etxebarria

; (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.

Temp Temp_2

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ equ

0x0c 0x0d

;Variable para la temporización ;Registro temporal

org goto

0x00 Inicio

;Vector de Reset

org

0x04

;Vector de interrupción

;Programa de tratamiento de la interrupción Tratamiento

btfss goto bcf decfsz goto Con_si_0 movlw movwf movlw xorwf Seguir movlw movwf Fin_Tratamiento retfie

INTCON,T0IF ;Ha sido el TMR0 ?? Fin_Tratamiento ;No INTCON,T0IF ;Si, repone flag del TMR0 Temp,F ;Se ha repetido la interrupción 5 veces ?? Seguir ;No 5 Temp ;Repone el contador nuevamente con 5 b'10000000' PORTB,F ;RB7 cambia de estado ~.195 TMR0 ;Repone el TMR0 con el complemento de 195 ;Retorno de interrupción

Inicio

PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000111' OPTION_REG STATUS,RP0

clrf bsf clrf movlw movwf movlw movwf bcf

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 256 asignado al TMR0 ;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 ;complemento de 195 movlw movwf movlw movwf movlw

~.195 TMR0 0x05 Temp b'10100000'

;Carga el TMR0 con el complemeto de 195 ;Nº de veces a repetir la interrupción

Loop

movwf

INTCON

clrwdt movf andlw movwf movf andlw iorwf movwf goto

PORTA,W b'00000011' Temp_2 PORTB,W b'10000000' Temp_2,W PORTB Loop

end

;Activa la interrupción del TMR0 ;Refresca el WDT ;Lee el estado de RA0 y RA1 ;Lo salva temporalmente

;Salida por RB0 y RB1 respentando valor actual de RB7

;Fin del programa fuente

; ; PRACTICA 10 ; ; Autor: Mikel Etxebarria ; (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".

Temp

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ

0x0c

;Variable para la temporización

org goto

0x00 Inicio

;Vector de Reset

org

0x04

;Vector de interrupción

;Programa de tratamiento de la interrupción Tratamiento

btfsc goto btfss goto

Cambio_RB4_RB7 bsf

INTCON,INTF ;Ha sido el RB0/INT ?? Tratar_INTF ;Si INTCON,RBIF ;No, ha sido cambio en RB4-RB7 ? Fin_Tratamiento ;No, falsa interrupción PORTA,1

;Activa salida RB1

Tratar_INTF

goto

Fin

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 Seguir Delay_50mS

movlw movwf bcf movlw movwf clrwdt btfss goto nop decfsz goto

Fin_Tratamiento clrf movf bcf

Inicio

Loop

;Comienza una temporización de 1" ;Inicia una variable temporal ;Repone el flag del TMR0

INTCON,T0IF Delay_50mS

;Repone el TMR0 con el complemento de 195 ;Comienza un bucle de temporización de 50mS ;Fin de los 50 mS ?? ;Todavía no

Temp,F Seguir

;Se ha repetido 20 veces los 50mS ?? ;No

PORTA PORTB,W INTCON,RBIF

;Si, ha pasado 1". Desconecta las salidas ;Lee estado actual de las entradas RA4-RA7 para reponer ;el flag de interrupción por cambio en RB4-RB7. Hay que ;hacerlo en este órden

bcf INTCON,INTF retfie

;Repone el flag de interrupción por RBO/INT ;Retorno de interrupción

clrf bsf clrf movlw movwf movlw movwf bcf

PORTA STATUS,RP0 TRISA b'11111111' TRISB b'01000111' OPTION_REG STATUS,RP0

;Borra los latch de salida ;Selecciona banco 1 ;Puerta A se configura como salidas

movf movlw movwf

PORTB,W b'10011000' INTCON

;Lee el estado inicial de las entradas RB4-RB7

sleep goto

Loop

end

; ; ; ;

.20 Temp INTCON,T0IF ~.195 TMR0

;Puerta B se configura como entrada ;Preescaler de 256 asignado al TMR0 y ;RB0/INT sensible al flanco ascendente ;Selecciona banco 0

;Activa la interrupcines INTF y RBIF ;El dispositivo queda en standby

;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 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"

Temp

Tabla_7_seg

Inicio

Loop:

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Incluir la definición de los registros internos

equ

0x0c

;Variable temporal

org goto

0x00 Inicio

;Vector de Reset

org

0x05

;Salva el vector de interrupción

addwf

PCL,F

retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000' b'10011000'

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;8 ;9

clrf bsf clrf movlw movwf movlw movwf bcf

PORTB STATUS,RP0 TRISB b'00001001' OPTION_REG b'00001111' TRISA STATUS,RP0

clrwdt movf andlw movwf movlw subwf btfsc goto btfsc goto

PORTA,W b'00001111' Temp 0x0a Temp,W STATUS,Z NULO STATUS,C NULO

movf call movwf goto

Temp,W Tabla_7_seg PORTB Loop

;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Preescaler de 1:2 asociado al WDT ;RA0-RA3 se configuran como entrada ;Selecciona banco 0 ;Refrescar el WDT ;Lee las entradas RA0-RA3 ;Almacena valor leído ;El valor es igual a 0x0A ?? ;Si ;No, el valor es mayor a 0x0A ?? ;Si ;Convierte el valor a código de 7 segmentos ;Lo deposita en la puerta de salida para visualizarlo

NULO

movlw movwf goto

b'11111111' PORTB Loop

end

;El valor de entrada no estaba comprendido entre 0 y 9 ;El display permanece apagado ;Fin del programa fuente

; ; PRACTICA 12 ; ; Autor: Mikel Etxebarria ; (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

Contador

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ

0x0c

;Variable del contador

org goto

0x00 Inicio

;Vector de Reset

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

Inicio

addwf

PCL,F

retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000' b'10011000'

clrf bsf clrf movlw movwf

PORTB STATUS,RP0 TRISB b'00011111' TRISA

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;8 ;9 ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada

Loop

movlw movwf bcf clrf

b'00000110' OPTION_REG STATUS,RP0 Contador

;Preescaler de 128 para el TMR0 ;Selecciona banco 0 ;Puesta a 0 del contador

movf call movwf

Contador,W Tabla_7_seg PORTB

;Convierte BCD a 7 segmentos ;Visualiza el valor del contador

Wait_0

clrwdt btfss PORTA,0 goto Wait_0 sleep

;Refrescar el WDT ;Subida de la señal RA0 ? ;No ;Modo standby en espara de 18mS. Elimina rebotes

Wait_1

clrwdt btfsc PORTA,0 goto Wait_1 sleep

;Refrescar el WDT ;Bajada de RA0 (pulso) ?? ;No ;Modo standby en espara de 18mS. Elimina rebotes

btfss goto

PORTA,1 Down

;RA1 = 1 ?? ;No, cuenta descendente

incf movlw subwf btfss goto clrf goto

Contador,F .10 Contador,W STATUS,Z Loop Contador Loop

;Incrementa contador

decf movlw subwf btfss goto movlw movwf goto

Contador,F 0xff Contador,W STATUS,Z Loop .9 Contador Loop

;Decrementa el contador

Up

Down

end

;Es mayor de 9 ?? ;No ;Si, puesta a 0 del contador

;Es menor de 0 ?? ;No ;Si, puesta a 9 del contador ;Fin del programa fuente

; ; PRACTICA 13 ; ; Autor: Mikel Etxebarria ; (c) Microsystems Engineering (Bilbao) ; ; ;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

Numero Delay_Cont Temporal

include "P16F84.INC"

;Definiciones de registros internos

equ equ equ

0x0c 0x0d 0x0e

;Número aleatorio ;Contador de intervalos ;Variable temporal

org goto org

0x00 Inicio 0x05

;Vector de Reset ;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

retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000' b'10011000'

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;8 ;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: Intervalo

Inicio

bcf movlw movwf clrwdt btfss goto decfsz goto return

INTCON,T0IF ~.195 TMR0

movlw movwf bsf clrf movlw movwf movlw movwf bcf

b'11111111' PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000111' OPTION_REG STATUS,RP0

INTCON,T0IF Intervalo Delay_Cont,F Delay_var

;Desconecta el flag de rebosamiento ;carga el TMR0 con el complemento de 195 ;Refrescar el WDT ;Rebasamiento del TMR0 al de 50mS ?? ;Todavía no ;Decrementa contador de intervalos ;Repite el intervalo de 50 mS

;Pone a "1" los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 256 para el TMR0 ;Selecciona banco 0

Loop

clrwdt btfss goto movf movwf

;Refrescar el WDT ;Activado RA0 ?? ;Todavía No ;Ahora si. ;Captura el valor del TMR0 (Nº aleatorio)

PORTA,0 Loop TMR0,W Numero

;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 subwf movwf sublw btfss goto incf

.6 Numero,W Numero .5 STATUS,C Divide Numero,F

;Resta 6 al número aleatorio ;lo guarda ;Mira si es menor de 5 ;No ;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: RA0_1

Salida:

movlw movwf clrwdt btfss goto movf call movwf movlw movwf call decfsz goto goto

PORTA,0 Salida Temporal,W Tabla_7_seg PORTB .1 Delay_Cont Delay_var Temporal,F RA0_1 Dado

sleep movf call movwf movlw movwf call movlw movwf

Numero,W Tabla_7_seg PORTB d'60' Delay_Cont Delay_var b'11111111' PORTB

goto

Loop

end ; ; ; ;

.6 Temporal

;Inicia el contador del dado ;Refresco del WDT ;Mira si RA0 está a 1 ;No, visualiza el aleatorio ;Número a visualizar ;Conversión a BCD ;Visualiza sobre el display ;Variable de temporización ;temporiza 0.05" ;Siguiente número

;Elimina rebotes ;Recoge el aleatorio ;Lo convierte en 7 segmentos ;Salida a Display ;Inicia variable de temporización ;Temporiza 3" ;Apaga el display

;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 común y que visualiza el valor actual de las variables D0, D1 y D2 a las que se ;supone previamente cargadas.

DIG0 DIG1 DIG2 Delay_Fijo Delay_Cont

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ equ equ equ equ

0x0c 0x0d 0x0e 0x0f 0x10

;Variable ;Variable ;Variable ;Variable ;Variable

org goto org

0x00 Inicio 0x05

;Vector de Reset

para para para para para

el dígito 0 el dígito 1 el dígito 2 temporización fija temporización variable

;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

retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000' b'10011000'

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;8 ;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 movf call movwf call bcf movlw movwf bsf movf call movwf call

PORTA,0 DIG0,W Tabla_7_seg PORTB Delay PORTA,0 b'11111111' PORTB PORTA,1 DIG1,W Tabla_7_seg PORTB Delay

;Activa dígito 0 ;Carga variable DIG0 ;Convierte a 7 segmentos ;Visualiza DIG0 sobre el dígito 0 ;Temporiza 1mS ;Desactiva dígito 0 ;Desactiva segmentos ;Activa dígito 1 ;Carga variable DIG1 ;Convierte a 7 segmentos ;Visualiza DIG1 sobre el dígito 1 ;Temporiza 1mS

bcf movlw movwf bsf movf call movwf call bcf movlw movwf return

PORTA,1 b'11111111' PORTB PORTA,2 DIG2,W Tabla_7_seg PORTB Delay PORTA,2 b'11111111' PORTB

;Desactiva dígito 1 ;Desactiva segmentos ;Activa dígito 2 ;Carga variable DIG2 ;Convierte a 7 segmentos ;Visualiza DIG2 sobre el dígito 2 ;Temporiza 1mS ;Desactiva dígito 2 ;Desactiva segmentos ;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 ;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: Intervalo

Inicio

bcf movlw movwf clrwdt btfss goto decfsz goto return

INTCON,T0IF ~.19 TMR0

movlw movwf clrf bsf clrf movlw movwf movlw movwf bcf

b'11111111' PORTB PORTA STATUS,RP0 TRISB b'00011000' TRISA b'00000111' OPTION_REG STATUS,RP0

movlw movwf

1 DIG2

INTCON,T0IF Intervalo Delay_Cont,F Delay_var

;Desconecta el flag de rebosamiento ;carga el TMR0 con el complemento de 195 ;Refrescar el WDT ;Rebasamiento del TMR0 al de 50mS ?? ;Todavía no ;Decrementa contador de intervalos ;Repite el intervalo de 50 mS

;Pone a "1" los latch de salida ;Desconecta los dígitos ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 se configuran como salidas ;Preescaler de 256 para el TMR0 ;Selecciona banco 0

Loop

movlw movwf movlw movwf

2 DIG1 3 DIG0

clrwdt call movlw movwf call goto

Display .1 Delay_Cont Delay_var Loop

end

;Carga en las variables el valor a visualizar (123) ;Refrescar el WDT ;

;Fin del programa fuente

; ; PRACTICA 15 ; ; Autor: Mikel Etxebarria ; (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"

DIG0 DIG1 DIG2 Delay_Fijo

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ equ equ equ

0x0c 0x0d 0x0e 0x0f

;Variable ;Variable ;Variable ;Variable

org goto org

0x00 Inicio 0x05

;Vector de Reset

para para para para

el dígito 0 el dígito 1 el dígito 2 temporización fija

;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

retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000' b'10011000'

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;8 ;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 movf call movwf call bcf movlw movwf bsf movf call movwf call bcf movlw movwf bsf movf call movwf call bcf movlw movwf return

PORTA,0 DIG0,W Tabla_7_seg PORTB Delay PORTA,0 b'11111111' PORTB PORTA,1 DIG1,W Tabla_7_seg PORTB Delay PORTA,1 b'11111111' PORTB PORTA,2 DIG2,W Tabla_7_seg PORTB Delay PORTA,2 b'11111111' PORTB

;Activa dígito 0 ;Carga variable DIG0 ;Convierte a 7 segmentos ;Visualiza DIG0 sobre el dígito 0 ;Temporiza 1mS ;Desactiva dígito 0 ;Desactiva segmentos ;Activa dígito 1 ;Carga variable DIG1 ;Convierte a 7 segmentos ;Visualiza DIG1 sobre el dígito 1 ;Temporiza 1mS ;Desactiva dígito 1 ;Desactiva segmentos ;Activa dígito 2 ;Carga variable DIG2 ;Convierte a 7 segmentos ;Visualiza DIG2 sobre el dígito 2 ;Temporiza 1mS ;Desactiva dígito 2 ;Desactiva segmentos ;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 subwf btfss return clrf return

0x0a DIG2,W STATUS,Z DIG2

;Es mayor de 9 ?? ;No ;Si, agista a 0 variable DIG2

;******************************************************************************************* ;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

Loop

Descendente

movlw movwf clrf bsf clrf movlw movwf movlw movwf bcf

b'11111111' PORTB PORTA STATUS,RP0 TRISB b'00011000' TRISA b'00000111' OPTION_REG STATUS,RP0

clrf clrf clrf

DIG0 DIG1 DIG2

;Carga las variables con valor inicial 000

clrwdt btfsc goto call goto

PORTA,4 Descendente Display Loop

;Refrescar el WDT ;Flanco ascendente en RA4 ?? ;Si ;No, mantiene el refresco del display ;Esperar

clrwdt btfss PORTA,4

;Pone a "1" los latch de salida ;Desconecta los dígitos ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 se configuran como salidas ;Preescaler de 256 para el TMR0 ;Selecciona banco 0

;Refrescar el WDT ;Flanco descendente en RA4

Pulso

Dec_Cont

goto call goto

Pulso Display Descendente

;Si, ha habido un pulso en RA4 ;No, mantiene el refresco del display ;Esperar

btfss goto call goto call goto

PORTA,3 Dec_Cont Incrementa Loop Decrementa Loop

;RA3 está a "1" ?? ;No ;Si, incrementa el contador ;Esperar al siguiente pulso ;Decrementar el contador ;Esperar el siguiente pulso

end

;Fin del programa fuente

; ; PRACTICA 16 ; ; Autor: Mikel Etxebarria ; (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

DIG0 DIG1 DIG2 Delay_Fijo W_Temp STATUS_Temp Delay_Cont

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ equ equ equ equ equ equ

0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12

;Variable ;Variable ;Variable ;Variable ;Registro ;Registro ;Variable

org goto org goto org

0x00 Inicio 0x04 Interrupcion 0x05

;Vector de Reset

para el dígito 0 para el dígito 1 para el dígito 2 para temporización fija temporal para el W temporal para el registro de estado de temporización

;Vector de interrupción ;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

retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000'

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;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 movf call movwf call bcf movlw movwf bsf movf call andlw movwf call bcf movlw movwf bsf movf call movwf call bcf movlw movwf return

PORTA,0 DIG0,W Tabla_7_seg PORTB Delay PORTA,0 b'11111111' PORTB PORTA,1 DIG1,W Tabla_7_seg b'01111111' PORTB Delay PORTA,1 b'11111111' PORTB PORTA,2 DIG2,W Tabla_7_seg PORTB Delay PORTA,2 b'11111111' PORTB

;Activa dígito 0 ;Carga variable DIG0 ;Convierte a 7 segmentos ;Visualiza DIG0 sobre el dígito 0 ;Temporiza 1mS ;Desactiva dígito 0 ;Desactiva segmentos ;Activa dígito 1 ;Carga variable DIG1 ;Convierte a 7 segmentos ;Activa el punto decimal en el dígito 1 ;Visualiza DIG1 sobre el dígito 1 ;Temporiza 1mS ;Desactiva dígito 1 ;Desactiva segmentos ;Activa dígito 2 ;Carga variable DIG2 ;Convierte a 7 segmentos ;Visualiza DIG2 sobre el dígito 2 ;Temporiza 1mS ;Desactiva dígito 2 ;Desactiva segmentos ;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 return clrf incf movlw subwf btfss return clrf return

STATUS,Z DIG1 DIG2,F 0x0a DIG2,W STATUS,Z DIG2

;Es mayor de 9 ?? ;No ;Si, ajusta a 0 variable DIG1 ;Incrementa DIG2 ;Es mayor de 9 ?? ;No ;Si, agista a 0 variable DIG2

;*************************************************************************************** ;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

Inter_Fin

Inicio

Loop

Loop_1

btfss retfie bcf movwf swapf movwf movlw movwf decfsz goto movlw movwf call swapf movwf swapf swapf retfie

INTCON,T0IF

movlw movwf clrf bsf clrf movlw movwf movlw movwf bcf

b'11111111' PORTB PORTA STATUS,RP0 TRISB b'00011000' TRISA b'00000111' OPTION_REG STATUS,RP0

clrf clrf clrf bcf

DIG0 DIG1 DIG2 INTCON,T0IF

;Puesta a 000 del contador ;Repone flag del TMR0

clrwdt btfsc goto call goto

PORTA,4 Descendente Display Loop_1

;Refrescar el WDT ;Flanco ascendente en RA4 ?? ;Si ;No, mantiene el refresco del display ;Esperar

INTCON,T0IF W_Temp STATUS,W STATUS_Temp ~.195 TMR0 Delay_Cont,F Inter_Fin .2 Delay_Cont Incrementa STATUS_Temp,W STATUS W_Temp,F W_Temp,W

;Ha sido el TMR0 ?? ;No, falsa interrupción ;Si, reponer flag del TMR0 ;Salva el registro W ;Salva el registro de estado ;Recarga el TMR0 para la siguiente temporización ;Ha habido dos interrupciones ?? ;No ;Si, repone el contador de interrupciones con 2 ;Actualiza el contador del cronómetro ;Recupera el registro de estado ;Recupera el registro W

;Pone a "1" los latch de salida ;Desconecta los dígitos ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 se configuran como salidas ;Preescaler de 256 para el TMR0 ;Selecciona banco 0

Descendente

clrwdt btfss goto call goto

PORTA,4 START Display Descendente

;Refrescar el WDT ;Flanco descendente en RA4 ;Si, ha habido un pulso en RA4 ;No, mantiene el refresco del display ;Esperar

;Se comienza a cronometrar START

Crono_Fin

movlw movwf movlw movwf bsf bsf

~.195 TMR0 .2 Delay_Cont INTCON,T0IE INTCON,GIE

clrwdt btfsc goto call goto

PORTA,4 STOP Display Crono_Fin

;Carga el TMR0 con 195 (interrupción cada 50mS) ;Inicia variable de temporización ;Habilita interrupción del TMR0 ;Permiso general de interrupciones ;Flanco ascendente en RA4 ? ;Si, parada del cronómetro ;No, mantiene el refresco del display ;Sigue cronometrando

;Secuencia de parada del cronómetro y puesta a 000 STOP Fin_1

Fin_2

Fin_3

bcf clrwdt btfss goto call goto clrwdt btfsc goto call goto clrwdt btfss goto call goto end

INTCON,GIE

;Se detiene la interrupción del TMR0

PORTA,4 Fin_2 Display Fin_1

;Flanco descendente de RA4 ?? ;Si ;Aún no se ha soltado RA4, refrescar el display ;Esperar a que se suelte RA4

PORTA,3 Fin_3 Display Fin_2

;Flanco ascendente en RA3 ? ;Si ;No, mantiene el refresco del display ;Esperar a que se active RA3

PORTA,3 Loop Display Fin_3

;Flanco descendente en RA3 ? ;Si, ha habido pulso para puesta a 0 del cronómetro ;No, mantiene el refresco del display ;Esperar a que se suelte RA3 ;Fin del programa fuente

; ; PRACTICA 17 ; ; Autor: Mikel Etxebarria ; (c) Microsystems Engineering (Bilbao) ; ;La memoria EEPROM de datos. La máquina "Su Turno" ; ;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.

DIG0 DIG1 Delay_Fijo Delay_Cont N_Bytes

List p=16F84 include "P16F84.INC"

;Tipo de procesador ;Definiciones de registros internos

equ equ equ equ equ

0x0c 0x0d 0x0e 0x0f 0x10

;Variable para el dígito 0 ;Variable para el dígito 1 ;Variable para temporización fija ;Variable de temporización ;Nº de bytes a grabar/leer en la EEPROM

org goto

0x00 Inicio

;Vector de Reset

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

EE_Write_1

Wait

movlw movwf clrf movlw movwf movf movwf bsf bsf movlw movwf movlw movwf bsf bcf btfss goto bcf bcf incf incf decfsz goto return

.2 N_Bytes EEADR DIG0 FSR INDF,W EEDATA STATUS,RP0 EECON1,WREN b'01010101' EECON2 b'10101010' EECON2 EECON1,WR EECON1,WREN EECON1,EEIF Wait EECON1,EEIF STATUS,RP0 FSR,F EEADR,F N_Bytes,F EE_Write_1

;Inicia Nº de bytes a leer ;Dirección 0 de EEPROM ;Inicia índice con el 1er. byte a grabar ;Carga dato a grabar ;Selecciona banco 1 ;Permiso de escritura

;Secuencia establecida por Microchip ;Orden de escritura ;Desconecta permiso de escritura ;Fin de escritura ?? ;No, todavía no ha finalizado la escritura ;Reponer flag de fin de escritura ;Selección banco 0 ;Si, siguiente byte a escribir ;Siguiente posición de EEPROM ;Decrementa el contador de bytes. Es 0 ?? ;No, faltan bytes por grabar ;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 posición 0 de la EEPROM y los datos leídos se depositan a partir ;de la posición indicada por FSR EE_Read

EE_Read_1

movlw movwf clrf movlw movwf bsf

.2 N_Bytes EEADR DIG0 FSR STATUS,RP0

;Nº de bytes a leer ;1ª dirección EEPROM a leer ;1ª direección a almacenar lo leído ;Selección de banco 1

bsf bcf movf movwf incf incf decfsz goto return

EECON1,RD STATUS,RP0 EEDATA,W INDF EEADR,F FSR,F N_Bytes,F EE_Read_1

;Orden de lectura ;Selección de banco 0 ;Almacena dato recien leído ;Siguiente dirección de EEPROM a leer ;Siguiente posición de almacenamiento ;Se han leído todos los bytes deseados ?? ;No, nueva lectura ;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

retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw

b'11000000' b'11111001' b'10100100' b'10110000' b'10011001' b'10010010' b'10000010' b'11111000' b'10000000' b'10011000'

;Desplaza al PC tantas posiciones como indique el valor ;del registro W ;Código 7 seg. del dígito 0 ;Código del 1 ;2 ;3 ;4 ;5 ;6 ;7 ;8 ;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 movf call movwf call bcf movlw movwf bsf movf call movwf call bcf movlw movwf return

PORTA,0 DIG0,W Tabla_7_seg PORTB Delay PORTA,0 b'11111111' PORTB PORTA,1 DIG1,W Tabla_7_seg PORTB Delay PORTA,1 b'11111111' PORTB

;Activa dígito 0 ;Carga variable DIG0 ;Convierte a 7 segmentos ;Visualiza DIG0 sobre el dígito 0 ;Temporiza 1mS ;Desactiva dígito 0 ;Desactiva segmentos ;Activa dígito 1 ;Carga variable DIG1 ;Convierte a 7 segmentos ;Visualiza DIG1 sobre el dígito 1 ;Temporiza 1mS ;Desactiva dígito 1 ;Desactiva segmentos ;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 decfsz Delay_Fijo,F goto Delay_1 return

;Consume 1 uS ;Consume 1 uS ;Consume 2 uS

;**************************************************************************************** ;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 movwf clrf bsf clrf movlw movwf movlw movwf bcf

b'11111111' PORTB PORTA STATUS,RP0 TRISB b'00011000' TRISA b'00000111' OPTION_REG STATUS,RP0

;Pone a "1" los latch de salida ;Desconecta los dígitos ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 se configuran como salidas ;Preescaler de 256 para el TMR0 ;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.

Clear

Loop

call

EE_Read

movlw subwf btfsc goto movlw subwf btfss goto

0x09 DIG0,W STATUS,C Clear 0x09 DIG1,W STATUS,C Loop

clrf clrf call

DIG0 DIG1 EE_Write

clrwdt btfsc PORTA,4 goto Descendente

;Lee los dos primeros bytes y los deposita en ;las variable DIG0 y DIG1 ;DIG0 > 09 ?? ;Si, el contador a de ponerse a 00 ;DIG1 > 09 ?? ;No, DIG0 y DIG1 están entre los valores correctos

;Pone le contador a 00 ;Refresca el WDT ;Flanco ascendente en RA4 ?? ;Si, esperar el descendente para incrementar contador

Descendente

Inc_Cont

Inc_Cont_1

Borrar

btfsc goto call goto

PORTA,3 Borrar Display Loop

;Flanco ascendente en RA3 (borrado) ?? ;Si, puesta a 00 del contador ;No, mantiene el refresco del display ;Esperar

bsf clrwdt btfss goto call goto

PORTA,2

;Activa señal sonora ;Refrescar el WDT ;Flanco descendente en RA4 ;Si, ha habido un pulso en RA4 ;No, mantiene el refresco del display ;Esperar

call call movlw movwf clrwdt call decfsz goto bcf goto

Incrementa EE_Write .250 Delay_Cont

;Incrementa el contador ;Actualiza el contador en la EEPROM

Display Delay_Cont,F Inc_Cont_1 PORTA,2 Loop

;Refresca el display (el refresco tarda 2 mS) ;Repite el refresco 250 veces (500 mS)

Display PORTA,3 Borrar DIG0 DIG1 EE_Write Loop

;Refresca el display ;Flanco descendente en RA3 ? ;No

clrwdt call btfsc goto clrf clrf call goto end

PORTA,4 Inc_Cont Display Descendente

;Inicia variable de temporización

;Desconecta la señal sonora

;Si, borrar el contador

;Fin del programa fuente