; ; PRACTICA 1 ; ; Autor: Mikel Etxebarria ; (c) Microsystems Engineering (Bilbao) ; ; ;Leer el estado de los 5 interrup
Views 80 Downloads 0 File size 85KB
; ; 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