Está en la página 1de 48

ESCUELA UNIVERSITARIA

POLITCNICA

MICROPROCESADORES
EJERCICIOS Y PRCTICAS
2003 / 2004

Rubn Bartolom Henares

2003 / 04
EJERCICIOS DE PROGRAMACIN I

EJERCICIO 1: Cdigo fuente


list p=16F876,f=INHX8M
include "P16F876.INC"
RESULTADO

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ

0x20

;Asigna la etiqueta "RESULTADO" a la direccin 0x20.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

movlw d7
addlw d12
movwf RESULTADO
end

Rubn Bartolom Henares

;Carga 7 en el acumulador.
;Suma 12 al contenido del acumulador y lo guarda en l.
;Deposita el contenido del acumulador en "RESULTADO".
;Paro. Tambin se puede emplear "sleep" o un bucle.

EJERCICIOS DE PROGRAMACIN I

2003 / 04
EJERCICIOS DE PROGRAMACIN I

EJERCICIO 2: Cdigo fuente


;
;
;
;
;

Esta ALU solo sabe emplear como registro negativo el acumulador (W). De forma que para
realizar la operacin sumaremos primero A+B y lo guardaremos en una direccin de
memoria "RESULTADO" para, posteriormente, cargar C en el acumulador y restrselo a
RESULTADO mediante la instruccin "subwf": resta del registro F la cantidad contenida
en W.
list p=16F876,f=INHX8M
include "P16F876.INC"

DATOA
DATOB
DATOC
RESULTADO

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ
equ
equ
equ

0x20
0x21
0x22
0x23

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

movf
addwf
movwf
movf
subwf

DATOA,W
DATOB,W
RESULTADO
DATOC,W
RESULTADO,F

;Dato A al acumulador.
;Sumo al acumulador el dato B. La suma A+B est en W.
;Envo el contenido del acumulador a "RESULTADO".
;Envo el dato C al acumulador.
;Resta del registro RESULTADO el contenido del
;acumulador y gurdalo en RESULTADO.

end

; Si realizsemos el programa sin etiquetas:


inicio

movf
addwf
movwf
movf
subwf

0x20,0
0x21,0
0x23
0x22,0
0x23,1

;Dato A al acumulador
;Sumo al acumulador el dato B. La suma A+B est en W
;Envo el contenido del acumulador a "RESULTADO"
;Envo el dato C al acumulador
;Resta del registro RESULTADO el contenido del
;acumulador y gurdalo en RESULTADO

end
;
;
;
;
;

Cuando ponemos en una instruccin W F en realidad lo que estamos escribiendo es el


bit de direccin d, y habra que poner 0 (hacia el acumulador) 1 (hacia el registro)
como se ha visto en teora. El ensamblador no tendr problemas en compilar el cdigo
gracias a las definiciones de registros internos. En "p16f876.inc" hay definidas unas
etiquetas: w equ 0 y f equ 1 que facilitan al programador la escritura del cdigo.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN I

2003 / 04
EJERCICIOS DE PROGRAMACIN I

EJERCICIO 3: Cdigo fuente


; Deberemos tener en cuenta que las palabras de 16 bits ocupan dos posiciones de memoria
; y deberemos tener en cuenta tambin si existe acarreo. Para ello cuestionaremos el bit
; "carry" del registro STATUS.
list p=16F876,f=INHX8M
include "P16F876.INC"
A_H
A_L
B_H
B_L
SOL_H
SOL_L

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ
equ
equ
equ
equ
equ

0x20
0x21
0x22
0x23
0x24
0x25

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

movf
addwf
movwf
movf
btfsc
addlw

A_L,W
B_L,W
SOL_L
A_H,W
STATUS,0
d1

;Sumo las partes bajas de los


;nmeros A y B y guardo el
;resultado en SOL_L
;Llevo la parte alta de A al acumulador
;Cuestiono si se ha producido acarreo (carry=1)en la
;suma anterior. Si carry=0 salta una instruccin y
;sigue con el resto de la suma, sino suma 1 (acarreo)
;a A_H
;Sumo al acumulador la parte alta de B
;y lo guardo en SOL_H

addwf B_H,W
movwf SOL_H
end

; Caso con acarreo:


C (acarreo)

A_H

A_L

B_H

B_L

SOL_H

SOL_L

* Nota: Cuando escribimos "STATUS,0" o cualquier otro registro, nos estamos refiriendo
al bit 0 de ese registro (en este caso el bit de carry).

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN I

2003 / 04
EJERCICIOS DE PROGRAMACIN I

EJERCICIO 4: Cdigo fuente


;
;
;
;
;
;
;
;

Bsicamente el cdigo es el mismo, pero deberemos recordar de teora que el bit carry
se interpreta como:
1 = se ha producido acarreo en el 8 bit
0 = no se ha producido acarreo
Pero esto es para la suma. Si estamos restando, el bit carry se interpreta de forma
inversa, es decir:
1 = no hay acarreo
0 = se ha producido acarreo en el 8 bit
En este ejercicio deberemos emplear la instruccin "btfss" en vez de "btfsc".
Deberemos tener cuidado al utilizar el bit C e interpretarlo convenientemente.
list p=16F876,f=INHX8M
include "P16F876.INC"

A_H
A_L
B_H
B_L
SOL_H
SOL_L

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ
equ
equ
equ
equ
equ

0x20
0x21
0x22
0x23
0x24
0x25

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

movf
subwf
movwf
movf
btfss
addlw
subwf
movwf
end

B_L,W
A_L
SOL_L
B_H,W
STATUS,0
d1
A_H,W
SOL_H

;Resto las partes bajas de


;los registros A y B y guardo
;el resultado en SOL_L.
;Llevo la parte baja de B al acumulador.
;Cuestiono si se ha producido acarreo.
;Si se ha producido sumo 1 al acumulador (a B_H).
;Resto la parte alta de A del acumulador
;y lo guardo en SOL_H.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN I

2003 / 04
EJERCICIOS DE PROGRAMACIN I

EJERCICIO 5: Cdigo fuente


;
;
;
;
;
;
;
;

Se puede realizar de dos formas diferentes: direccionamiento directo e indirecto.


Con el direccionamiento directo cargaramos el valor 0x33 en el acumulador y mediante
la instruccin "movwf" lo llevaramos a las 15 posiciones de memoria, pero el
inconveniente es que deberamos escribir la instruccin 15 veces. Esto no es muy
econmico. En estos casos se emplea el direccionamiento indirecto:
Se emplearn los registros FSR e INDF. El registro FSR acta como puntero, de forma
que una instruccin que utilice el registro INDF accede al dato que se encuentra en
la direccin a la que apunta FSR.
list p=16F876,f=INHX8M
include "P16F876.INC"

CONT

inicio

uno

;Tipo de procesador.
;Definiciones de registros internos.

equ

0x70

;Asignamos a CONT una direccin que no coincida con las


;que tenemos que escribir. Por ejemplo, 0x70.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

movlw
movwf
movlw
movwf
movlw
movwf
incf
decfsz
goto
end

d15
CONT
0x20
FSR
0x33
INDF
FSR,F
CONT,F
uno

;Cargamos 15 en el acumulador.
;Asignamos el valor 15 a la variable CONT.
;Con esto conseguimos que el registro de
;direccionamiento indirecto apunte a la direccin 0x20.
;Cargamos en INDF el contenido 0x33, de forma que
;lo guardar en la direccin a la que apunte FSR.
;Apunto a la siguiente direccin a escribir.
;Decremento el contador y mientras no sea cero
;vuelvo a realizar la operacin.
;Si es cero, acabo el programa.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN I

2003 / 04
EJERCICIOS DE PROGRAMACIN I

EJERCICIO 9: Cdigo fuente


; Nos ayudaremos mediante una subrutina que llamar a una tabla donde se encontrarn
; contenidos los nmeros en cdigo gray.
list p=16F876,f=INHX8M
include "P16F876.INC"
BIN
GRAY

equ
equ

0x20
0x21

org
goto
org

0x00
inicio
0x05

;Tipo de procesador.
;Definiciones de registros internos.

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

inicio

movf
BIN,W
call
tabla
movwf GRAY

;Llevo el valor en binario al acumulador


;Llamo a la subrutina de conversin
;Aqu retorna la subrutina guardando el valor en cdigo
;gray en el registro GRAY

tabla

addwf PCL,F

;Suma al PCL el contenido del acumulador

; Al ejecutar esta ltima instruccin el contador de programa en vez de apuntar a la


; direccin siguiente (+1) apunta a la direccin +(1 + contenido del W)
retlw b00000000
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

b00000001
b00000011
b00000010
b00000110
b00000111
b00000101
b00000100
b00001100
b00001101

;retorna al programa principal con el nmero 0 en gray


;guardado en el acumulador
;nmero 1 en gray
;nmero 2 en gray
;nmero 3 en gray
;nmero 4 en gray
;nmero 5 en gray
;nmero 6 en gray
;nmero 7 en gray
;nmero 8 en gray
;nmero 9 en gray

;Como no nos especifican el tamao de la tabla, la podemos hacer todo lo grande que
;queramos, pero con cuidado de no sobrepasar las 256 posiciones, ya que sino nos
;pasaramos de pgina.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN I

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 1: Cdigo fuente


list p=16F876,f=INHX8M
include "P16F876.INC"

inicio

uno

dos

;Tipo de procesador.
;Definiciones de registros internos.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

clrf
bsf
movlw
movwf
movlw
movwf
clrf

PORTB
STATUS,RP0
b00000110
ADCON1
b00000001
TRISA
TRISB

bcf

STATUS,RP0

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar en el puerto A
;como entrada la patilla RA0.
;Configurar puerto B como salida. Solo necesitamos RB0
;y RB1 como salidas. Como estn las dems es da igual,
;pero borrando todas nos ahorramos una instruccin.
;Vuelvo al banco 0.

btfss
goto
bsf
bcf
goto
bcf
bsf
goto

PORTA,RA0
dos
PORTB,RB0
PORTB,RB1
uno
PORTB,RB0
PORTB,RB1
uno

;Cuestiono el valor de RA0.


;Si es cero voy a "dos", y
;si es uno enciendo el led de la patilla RB0
;y apago el led de la patilla RB1 (valor negado).
;Vuelvo a cuestionar
;Apago el led de la patilla RB0 y
;enciendo el led de RB1 (valor negado).
;Vuelvo a cuestionar el valor.

end

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 2: Otro posible diagrama:

Ejercicio 2

Borrar el puerto B

Inicializar el puerto
B como salida y el
A como entrada

Leer dato del


puerto A

SI

SI

NO

RA0=0?

00
Escribir en el
puerto B
10101010

Rubn Bartolom Henares

NO

RA1=0?

01
Escribir en el
puerto B
01010101

SI

10
Escribir en el
puerto B
00001111

NO

RA0=0?

11
Escribir en el
puerto B
11110000

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 2: Cdigo fuente


list p=16F876,f=INHX8M
include "P16F876.INC"

;Tipo de procesador.
;Definiciones de registros internos.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

inicio

clrf
bsf
movlw
movwf
movlw
movwf
clrf
bcf

PORTB
STATUS,RP0
b00000110
ADCON1
b00000011
TRISA
TRISB
STATUS,RP0

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar en el puerto A como
;entradas las patillas RA1 y RA0.
;Configurar puerto B como salida (todas las patillas).
;Vuelvo al banco 0.

uno

btfsc
goto
btfsc
goto
movlw
movwf
goto
movlw
movwf
goto
btfsc
goto
movlw
movwf
goto
movlw
movwf
goto

PORTA,RA1
tres
PORTA,RA0
dos
b10101010
PORTB
uno
b01010101
PORTB
uno
PORTA,RA0
cuatro
b00001111
PORTB
uno
b11110000
PORTB
uno

;
;Si RA1 es uno, voy a "tres".
;
;Si RA0 es uno, voy a "dos".
;Si RA0 es cero envo el
;valor al puerto B
;y vuelvo a "uno".
;Como RA0 es uno, envo el valor
;correspondiente al puerto B.
;Vuelvo a "uno".
;
;Si RA0 es uno voy a "cuatro".
;Si RA0 es cero envo el valor
;correspondiente al puerto B.
;Vuelvo a "uno".
;Si RA0 es uno envo el valor
;correspondiente al puerto B.
;Vuelvo a "uno".

dos
tres

cuatro

end

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 3: Cdigo fuente


RB1
RB2
RA3

;suponemos que RB0=1


;saca el cilindro (avance)
;y RB0=0 lo mete (retroceso).

Motor
M

RA2

RA1

a
RB0

cua

PIEZA
V

RA0
l

list p=16F876,f=INHX8M
include "P16F876.INC"

inicio

uno

dos
tres
cuatro

cinco

;Tipo de procesador.
;Definiciones de registros internos.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

clrf
bsf
movlw
movwf
movlw
movwf
clrf

PORTB
STATUS,RP0
b00000110
ADCON1
b00001111
TRISA
TRISB

bcf

STATUS,RP0

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar en el puerto A como entradas
;las patillas RA3, RA2, RA1 y RA0.
;Configurar puerto B como salida (solo usamos RB2, RB1
;y RB0). Borramos todas y ahorramos una instruccin
;Vuelvo al banco 0.

btfss
goto
bcf
bsf
btfss
goto
bsf
btfss
goto
bcf
btfss

PORTA,RA0
uno
PORTB,RB2
PORTB,RB0
PORTA,RA2
dos
PORTB,RB1
PORTA,RA3
tres
PORTB,RB0
PORTA,RA2

goto
bcf
btfss
goto
bsf
goto

cuatro
PORTB,RB1
PORTA,RA1
cinco
PORTB,RB2
uno

;Comprobar si se ha pulsado el pulsador de marcha.


;Zumbador est en off (apagado).
;El cilindro avanza e introduce la pieza.
;Comprobar si el sensor "b" est activado.
;Se activa el motor y comienza el torneado.
;Comprobar si la pieza ha llegado al final de carrera.
;El cilindro comienza el retroceso.
;Comprobar si la pieza pasa por el sensor
;de paro del motor.
;Se para el motor.
;Comprobar si la pieza ha vuelto a su posicin inicial.
;Se activa la seal acstica (zumbador on).
;Comenzar de nuevo.

end

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 4: Cdigo fuente

list p=16F876,f=INHX8M
include "P16F876.INC"

;Tipo de procesador.
;Definiciones de registros internos.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

inicio

clrf
bsf
movlw
movwf
movlw
movwf
clrf
bcf

PORTB
STATUS,RP0
b00000110
ADCON1
b00000011
TRISA
TRISB
STATUS,RP0

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar en el puerto A como
;entradas las patillas RA1 y RA0.
;Configurar puerto B como salida (todas las patillas)
;Vuelvo al banco 0.

leer0

btfss
goto
movlw
movwf
goto
movlw
movwf
btfss
goto
bsf
goto
bcf
goto

PORTA,RA0
cero
b00000110
PORTB
leer1
b00111111
PORTB
PORTA,RA1
puntooff
PORTB, RB7
leer0
PORTB,RB7
leer0

;Cuestiono el valor de RA0.


;Si es cero voy a "cero". Sino,
;envo la codificacin en binario del nmero 1 al
;puerto B para visualizarlo en el display.
;Paso a leer el bit RA1.
;Envo la codificacin del nmero 0
;al display conectado en el puerto B.
;Cuestiono el valor de RA1.

cero
leer1

puntooff

;Enciendo
;Vuelvo a
;Borro el
;Comienzo

el punto digital.
comenzar.
punto digital del display.
de nuevo.

end
; Se podra pensar que sera preciso desactivar las resistencias de pull-up del
; puerto B, pero esto no es necesario ya que stas resistencias se desactivan
; automticamente cuando las patillas del puerto B estn configuradas como salida.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 5: Cdigo fuente


list p=16F876,f=INHX8M
include "P16F876.INC"

;Tipo de procesador.
;Definiciones de registros internos.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

inicio

clrf
bsf
movlw
movwf
movlw
movwf
clrf
bcf

PORTB
STATUS,RP0
b00000110
ADCON1
b00001111
TRISA
TRISB
STATUS,RP0

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar en el puerto A como entradas
;las patillas RA3, RA2, RA1 y RA0.
;Configurar puerto B como salida (todas las patillas)
;Vuelvo al banco 0.

uno

movf
PORTA,W
andlw b00001111

;
;
;
;
;
;
;
;
;
;

;Cargamos en el acumulador el valor del puerto A.


;Realizamos un enmascaramiento AND.

Realizamos un enmascaramiento AND a las patillas RA3:RA0 de forma que, los bits no
empleados valdrn cero, y los que utilizamos mantendrn su valor. Nos aseguramos as
que, aunque halla algn valor en las patillas RA7:RA4 (no utilizadas), ste quedar
"enmascarado" y valdr cero
PORTA

RA7 RA6 RA5 RA4 RA3 RA2 RA1 RA0


-------------------------------0
0
0
0 RA3 RA2 RA1 RA0

enmascaramiento AND

Me quedo con el valor de los ltimos cuatro bits


call

tabla

tabla

;Llamo a la subrutina.

movwf PORTB
goto
uno

;Llevo el valor codificado en 7 segmentos al display.

addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

;Sumo el contenido del acumulador al PC.


;nmero 1 en hexadecimal.
;nmero 2 en hexadecimal.
;nmero 3 en hexadecimal.
;nmero 4 en hexadecimal.
;nmero 5 en hexadecimal.
;nmero 6 en hexadecimal.
;nmero 7 en hexadecimal.
;nmero 8 en hexadecimal.
;nmero 9 en hexadecimal.
;nmero A en hexadecimal.
;nmero B en hexadecimal.
;nmero C en hexadecimal.
;nmero D en hexadecimal.
;nmero E en hexadecimal.
;nmero F en hexadecimal.

PCL,F
b'00000110'
b'01011011'
b'01001111'
b'01100110'
b'01101101'
b'01111101'
b'00000111'
b'01111111'
b'01101111'
b'01110111'
b'01111100'
b'00111001'
b'01011110'
b'01111001'
b'01110001'

end

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 6: Cdigo fuente


; Para realizar la temporizacin vamos a crear una subrutina que temporice 10 mseg y la
; repetiremos 50 veces con la ayuda de un contador.
list p=16F876,f=INHX8M
include "P16F876.INC"
CONTADOR

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ

0x20

;Contador.

org
goto
org

0x00
inicio
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.
;El programa comienza despus del vector interrupcin.

bsf

STATUS,RP0

bcf
bcf

OPTION_REG,T0CS
OPTION_REG,PSA

;Paso al banco 1 para modificar el registro


;OPTION_REG.
;Selecciono el TMR0 como temporizador.
;Asignamos el pre-divisor de frecuencias al
;mdulo del temporizador TMR0.

;Comentario:
; stas dos instrucciones no se han realizado moviendo un literal ya que cuando se
; produce un reset el registro OPTION_REG posee todos sus bits a 1. Solo nos har falta
; borrar aquellos bits que deban estar a cero. Se podra hacer moviendo un literal.
bcf

uno

STATUS,RP0

movlw d50
movwf CONTADOR
bcf
INTCON,T0IF

;Vuelvo al banco 0.
;Cargo el valor 50 para la repeticin de la secuencia
;en el registro "CONTADOR".
;Borrar el bit T0IF.

; Importante!: Esta ltima operacin se debe realizar siempre por programa aunque en
; teora no hara falta, ya que al producirse un reset todos los bits de INTCON se
; ponen a cero. Es preferible incluirla siempre.
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Ahora hay que calcular el valor a cargar en el TMR0. Este calculo debe realizarse a
mano. Sabemos que la ecuacin que define la temporizacin para el TMR0 es:
T = 4Tosc(256 - carga)pre-escala
Si despejamos la carga:

T
carga = 256 - ------------------4Toscpre-escala

La temporizacin que deseamos es T=10mseg. La pre-escala viene definida por el estado


de los bits PS2, PS1 y PS0 del registro OPTION_REG. Los tres poseern el valor 1 ya
que, como se ha comentado, despus de un reset todos los bits de OPTION_REG se ponen a
uno. Se estar cargando, por tanto, y segn el rango de funcionamiento del
pre-divisor, el valor 256; luego pre-escala = 256 (Si se deseara otra pre-escala,
bastara con modificar los bits PS por programa). El periodo del oscilador ser la
inversa de la frecuencia, que en nuestro caso es de 20MHz. Por tanto, Tosc = 200nseg.
Sustituyendo todos los datos en la ecuacin se obtiene:
carga = 60.6875
Debemos tomar un valor entero para cargarle en el TMR0. Cul es el correcto, 60 o 61?
Calculamos a continuacin cul sera la temporizacin para ambos valores de la carga:

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

;
;
carga = 60 T = 10.0352 mseg
;
carga = 61 T = 9.9840 mseg
;
; El segundo valor es el correcto, 61, ya que con el primero nos pasamos. Siempre ser
; ms sencillo ajustar la temporizacin deseada incluyendo en el programa instrucciones
; "nop". Continuamos con el programa.
movlw
movwf

d61
TMR0

;Realizamos la carga
;en el temporizador 0.

; Tardar dos ciclos en comenzar el proceso del temporizador. En el 3 se incrementa


dos

btfss
goto

INTCON,T0IF ;Compruebo si ha habido un desbordamiento (T0IF=1).


dos
;Aqu, y hasta 256 ciclos despus, TMR0 no se
;incrementa.
decfsz CONTADOR,F ;Con este bucle realizo la
goto
uno
;temporizacin de 10mseg 50 veces.
end

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 9: Cdigo fuente


;
;
;
;
;

Como nos piden que cuente hasta 6, cargaremos en TMR0 un valor de forma que solo le
falten 6 incrementos para desbordar, as desbordar despus de 6 pulsos. Emplear
TMR0 para contar los 6 eventos y despus lo emplear como temporizador para
temporizar el segundo de visualizacin del display. Esto no es incompatible, ya que
las dos tareas no las realiza a la vez.
list p=16F876,f=INHX8M
include "P16F876.INC"

CONT
W_TEMP
STATUS_TEMP
OPTION_REG_TEMP

inicio

equ
equ
equ
equ

0x20
0x21
0x22
0x23

;Tipo de procesador.
;Definiciones de registros internos.

;Para el tiempo 1seg su valor ser 100.


; \ Para guardar los registros importantes
; > que vayan a ser modificados
; / durante la interrupcin

org
goto
org
goto
org

0x00
inicio
0x04
inter
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

clrf
bsf
movlw
movwf
bsf
clrf

PORTB
STATUS,RP0
.6
ADCON1
TRISA,RA4
TRISB

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales (.6 es lo mismo que d6).
;Configurar en el puerto A como entrada la patilla RA4.
;Configurar puerto B como salida (todas las patillas).

movlw b10101000
movwf OPTION_REG

;Configuramos el registro OPTION_REG


;de acuerdo a nuestras necesidades.

;OPTION_REG = 10101000

; bit 7 RBPU =1
;
;
; bit 6 INTEDG=0
;
;
;
;

bit 5
bit 4
bit 3
bits 2:0

Da igual su estado. Las resistencias de pull-up se desconectan


automticamente al configurar el puerto B como salida. Las
desactivamos por precaucin.
Interrupcin activa con flanco descendente en RB0/INT. Tambin lo
podramos hacer con flanco ascendente, el enunciado no dice nada.
T0CS=1
1 seleccionamos la entrada de pulsos por RA4, 0 para reloj interno.
T0SE=0
El incremento de TMR0 se produce por flanco ascendente en RA4.
PSA=1
Asigna el divisor de frecuencias al perro guardin(WDT).
PS2:PS0=0
Da igual el valor, no estamos utilizando el reloj interno.
bcf

STATUS,RP0

;Vuelvo al banco 0.

; Debo cargar ahora el temporizador con el complemento a 1 de seis para que ste
; desborde tras seis eventos (en el sptimo, ya que 6 se decrementa hasta 0):
;
;
TMR0
W
Display
;
F9 ----- 6 ----- 0
;
FA ----- 5 ----- 1
;
FB ----- 4 ----- 2
;
FC ----- 3 ----- 3
;
FD ----- 2 ----- 4
;
FE ----- 1 ----- 5
;
FF ----- 0 ----- 6
;
Interrupcin 00

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

movlw ~.6
movwf TMR0

;INTCON
; bit 7
; bit 5
; bit 2
;
; Todas
uno

movlw b00111111
movwf PORTB

;Esto carga el complemento a 1 de 6 en el acumulador.


;Tengo el nmero de pulsos a contar para que desborde.
;Dos ciclos despus se podr incrementar el TMR0.
;Esto para que nada ms conectar el
;display aparezca el nmero cero.

movlw b10100000
movwf INTCON

;Configuro el registro
;INTCON como necesite.

= 10100000
GIE=1
Activamos el bit general de interrupciones.
T0IE=1
Habilita la interrupcin del TMR0.
T0IF=0
ste bit no se escribe. Yo leo de l cuando hay desbordamiento del
temporizador TMR0. Deber borrase por software (un cero).
las dems interrupciones deshabilitadas (ceros)
comf
TMR0
andlw b00001111

;Complemento el valor de TMR0 y lo mando al acumulador


;Enmascaramiento AND. *

; * sta ltima instruccin es optativa ya que los valores que va a tomar el TMR0 sern
; del tipo Fx. Al complementar, F es 0. ej: F9=11111001 00000110 (ya hay
; enmascaramiento)
call
tabla
movwf PORTB
goto
uno

;Llamo a la subrutina tabla


;Envo el nmero en cdigo 7 segmentos al display

; El microprocesador estar en este bucle hasta que el bit T0IF sea uno, momento en el
; que se producir una interrupcin y el programa saltar a la subrutina de interrupcin
; "inter"
tabla

;
;
;
;
;

addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw

PCL,F
b'01111101'
b'01101101'
b'01100110'
b'01001111'
b'01011011'
b'00000110'
b'00111111'

;Sumo el
;Retorno
;Retorno
;Retorno
;Retorno
;Retorno
;Retorno
;Retorno

contenido del acumulador al PC


con el valor de 6 en 7 segmentos
con el valor de 5 en 7 segmentos
con el valor de 4 en 7 segmentos
con el valor de 3 en 7 segmentos
con el valor de 2 en 7 segmentos
con el valor de 1 en 7 segmentos
con el valor de 0 en 7 segmentos

en
en
en
en
en
en
en

W
W
W
W
W
W
W

Definimos la subrutina de interrupcin que mostrar todos los segmentos del display
iluminados durante 1 segundo. Para ello, como se ha comentado al principio, se
emplear tambin el TMR0, ya que su primera funcin de contador ya ha terminado.
Para temporizar 1 segundo, se emplear la temporizacin del ejercicio 6 que era de
10 mseg y la multiplicaremos por 100 (por eso definimos CONT)

; / *** interrupcin *** /


;Lo primero es guardar todos los registros importantes para no perderlos
inter
movwf W_TEMP
;Guardar el W en un registro temporal.
swapf STATUS,W
;Intercambia los nibbles de STATUS
movwf STATUS_TEMP
;y lo guarda en un registro temporal.
clrf
STATUS
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0.
movf
OPTION_REG,W
;Guarda el registro OPTION_REG
movwf OPTION_REG_TEMP
;en un registro temporal.
clrf
OPTION_REG
;Borrar el registro.
;Los registros ya estn guardados
bsf
STATUS,RP0
movlw b10000111
movwf OPTION_REG

Rubn Bartolom Henares

;Banco 1.
;Configuramos el registro OPTION_REG para
;que el TMR0 funcione como temporizador.

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

;OPTION_REG = 10000111

;
;
;
;
;
;

bit 7
bit 6
bit 5
bit 4
bit 3
bits 2:0

RBPU =1
Desactivamos las resistencias de pull-up por precaucin.
INTEDG=0 Con un 0, interrupcin activa con flanco descendente en RB0/INT.
T0CS=0
Con 0 seleccionamos los pulsos del reloj interno.
T0SE=0
El incremento de TMR0 se produce por flanco ascendente del reloj.
PSA=0
Asigna el divisor de frecuencias al mdulo del TMR0.
PS2:PS0=1
Selecciona el rango del divisor de frecuencia del TMR0 (256).
bcf

STATUS,RP0

;Vuelvo al banco 0

bcf

INTCON,T0IF

;Borrar T0IF. *

; * Hay que borrar el bit de sealizacin de desbordamiento T0IF, ya que si no lo borro


; cuando acabe la interrupcin, el programa vuelve a entrar en ella (bucle infinito).
movlw
movwf
call
clrf

0xFF
PORTB
retardo
PORTB

;El display se
;enciende completamente.
;Subrutina para iluminar durante 1 segundo.
;Borro el display.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


movf
OPTION_REG_TEMP,W
;Recupero el valor de
movwf OPTION_REG
;OPTION_REG a travs de W.
swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg. temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
stop

goto

stop

;Fin de subrutina de interrupcin *

; * Todas las subrutinas deben acabar con un retorno, pero creo un bucle infinito porque
; el enunciado dice que para repetir el proceso ser necesario pulsar RESET
; / *** subrutina de retardo *** /
retardo
otravez
dos

;
;
;
;
;

movlw
movwf
bcf
movlw
movwf
btfss
goto
decfsz
goto
return

.100
CONT
INTCON,T0IF
.61
TMR0
INTCON,T0IF
dos
CONT,F
otravez

;Cargo el registro CONT


;con el valor 100
;Borrar el bit de sealizacin de interrupciones *
;Cargo con el valor 61 el TMR0. Ya se vi en el ej 6
;que con este valor se temporizan 10 mseg
;Comprobar si hay desbordamiento
;Si es as, decrementar CONT y comprobar si CONT=0
;Si CONT no es cero, realizar el proceso de nuevo
;Si es cero, regresar.

* Observar que en esta ltima subrutina se


desbordamiento T0IF. En el programa, en la
posee el valor 1 (desbordamiento activado,
"otravez", si no lo borro, el temporizador
interpretar una interrupcin.

vuelve a borrar el bit de sealizacin de


instruccin "goto otra vez", el bit T0IF
no se ha borrado), por lo que, al saltar a
dejar de contar, ya que el microprocesador

;Empleo de "swapf" al guardar registros en la rutina de interrupcin:


; Al guardar y recuperar STATUS y W se emplea la instruccin "swapf" en vez de "movwf" o
; "movf" ya que stas dos ltimas pueden afectar a los bits C, DC y Z y modificar as el
; STATUS con la consiguiente perturbacin en el programa. "swapf" no afecta a ningn bit
; de estado.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

EJERCICIO 12: Cdigo fuente

F
N=1
FFFF

FFFF

FFFF

FFFF

FFFF

FFFF

FFFF

0000

0000

0000

0000

0000

0000

RB0
FFFE

N=2
FFFE

FFFF

0000

FFFF

0000

FFFE
FFFF

FFFD

N=3
FFFD

;
;
;
;
;
;
;
;
;
;
;
;
;
;

FFFE

FFFE

FFFF

0000

0000
FFFD

FFFE

FFFF

0000

Sabemos que el temporizador 1 puede trabajar con eventos externos a travs de la


patilla RC0/T1OSC/T1CKL. Mi objetivo es que cuente los pulsos de la seal cuadrada que
voy a introducir por RC0, por lo que deber configurar el TMR1 como contador. Los
incrementos los realizar con los flancos ascendentes pero es preciso que primero
detecte un flanco descendente antes de empezar a contar los impulsos. Es decir, antes
de que interprete los flancos ascendentes y se incremente deber haber detectado un
flanco descendente.
Cada N flancos ascendentes deber desbordarse y producir una interrupcin, como puede
observarse en el cronograma. En la propia subrutina de interrupcin deber cambiar por
programa el valor del TMR1 de FFFFh a 0000h y conmutar la seal en RB0.
El nmero ms grande al que puedo asignar N es 65535 (FFFFh), es decir, como mucho
podr dividir la frecuencia F por 65535.

; Hacemos el programa, por ejemplo, para N=6. Para ello, en realidad, deberemos guardar
; el complemento a 2 de 6 para que despus de contar 6 llegue a 0xFFFF y en el siguiente
; pulso se desborde y provoque la interrupcin.
list p=16F876,f=INHX8M
include "P16F876.INC"
N
W_TEMP
STATUS_TEMP

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ
equ
equ

0xFFF9 ;Cargamos el complemento a 2 del nmero 6 (0xFFF9).


0x21
; \ Para guardar los registros
0x22
; / durante la interrupcin

org
goto
org
goto
org

0x00
inicio
0x04
inter
0x10

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

clrf
bsf
clrf
bsf

PORTB
STATUS,RP0
TRISB
TRISC,RC0

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto B como salida (todas las patillas).
;Patilla RC0 como entrada.

Rubn Bartolom Henares

;(Se puede poner 0x05 o cualquier otra direccin).

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

;
;
;
;

En realidad, esta ltima instruccin no es necesaria, ya que como los impulsos van a
proceder de un oscilador externo (por RC0), deberemos activar el bit T1OSCEN del
registro T1CON. Al activar este bit, las patillas RC0 y RC1 actan como entradas,
independientemente del registro TRISC.
bsf
bcf

PIE1,TMR1IE
STAUS,RP0

movlw b00000111
movwf T1CON

;Habilito las posibles interrupciones del TMR1.


;Banco 0.
;Configuracin del
;registro T1CON.

;T1CON = 00000111
; bits 7:6 (no implementados) Preferiblemente se escribirn ceros.
; bits 5:4 T1CKPS1:T1CKPS0=00 Rango del pre-divisor. No seleccionaremos pre-divisor,
;
ya que el temporizador podra saltarse flancos.
; bit 3 T1OSCEN=0 Deshabilitamos el oscilador externo.
; bit 2 T1SYNC=1
No sincroniza la entrada del reloj externo con el interno.
; bit 1 TMR1CS=1
Reloj externo procedente de la patilla RC0/T1OSO/T1CKL.
; bit 0 TMR1ON=1
Habilitacin del TMR1.
clrf

TMR1L

movlw
movwf
movlw
movwf

low-N
TMR1L
high-N
TMR1H

;Borro la parte baja


;desborda durante la
;Envo la parte baja
;es decir, 0xF9 a la
;Envo la parte alta
;es decir, 0xFF a la

del TMR1 para asegurar que no se


operacin de escritura.
de N en complemento a 2,
parte baja del TMR1.
de N en complemento a 2,
parte alta del TMR1.

; Los comandos "low" y "high" se emplean para referirse a palabras que ocupan dos
; posiciones de memoria (16 bits). Si el valor de N solo ocupase 8 bits estos comando no
; haran falta.
movlw b11000000
movwf INTCON
;INTCON
; bit 7
; bit 6
; Todas
uno

;Activo los bits de habilitacin global de


;interrupciones y de los perifricos (GIE y PEIE).

= 11000000
GIE=1
Activamos el bit general de interrupciones.
PEIE=1
Habilita la interrupcin de los perifricos.
las dems interrupciones deshabilitadas (ceros)
sleep
nop
goto
uno

; / *** interrupcin *** /


;Guardamos los registros importantes:
inter
movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP
clrf
STATUS
;Los registros ya estn guardados

;Guardar el W en un registro temporal


;Intercambia los nibbles de STATUS
;y lo guarda en un registro temporal
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0

; Vuelvo a recargar el TMR1 con el complemento a 2 de


clrf
TMR1L
;Borro la parte baja
;desborda durante la
movlw low-N
;Envo la parte baja
movwf TMR1L
;es decir, 0xF9 a la
movlw high-N
;Envo la parte alta
movwf TMR1H
;es decir, 0xFF a la

Rubn Bartolom Henares

6:
del TMR1 para asegurar que no se
operacin de escritura.
de N en complemento a 2,
parte baja del TMR1.
de N en complemento a 2,
parte alta del TMR1.

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN II

bcf

PIR1,TMR1IF

movlw b00000001
xorwf PORTB,F
;
;
;
;
;
;
;
;
;
;
;
;

;Deshabilito la posible interrupcin por desbordamiento


;del TMR1.
;Realiza la operacin
;OR exclusiva entre W y PORTB.

Con esta operacin se consigue que el valor de la patilla RB0 cambie. Al colocar un 1
en el bit cero de W conseguimos que el bit cero del PORTB (RB0) cambie su valor
actual. Las posiciones de W donde hay ceros no alteran el valor de los dems bits de
PORTB. Lo vemos en la tabla de la verdad de la operacin OR-exclusiva:
W | RB0 | Nuevo valor
-----|-----|------------0 | 0 |
0
0 | 1 |
1

1 | 0 |
1

1 | 1 |
0
-----|-----|-------------

;Recuperamos ahora los registros guardados antes.


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg. temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
retfie

;Fin de la subrutina de interrupcin.

end

;Fin del programa.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN II

2003 / 04
EJERCICIOS DE PROGRAMACIN III

EJERCICIO 1: Cdigo fuente

Flanco 0

Flanco 1

Periodo

1 captura

;
;
;
;
;
;
;
;

2 captura

La diferencia entre dos flancos ascendentes nos dar el periodo. La primera captura se
almacenar en un registro temporal de 16 bit, ya que el mdulo de captura solo
memoriza la captura actual. Tambin necesito establecer en que instante debo realizar
la resta de valores. Definir una variable llamada "N_FLANCO" de forma que cuando se
produzca el primer flanco, N_FLANCO=0 y cuando se produzca el segundo N_FLANCO=1,
momento en el que realizar la resta.
Como nos dice el enunciado, la velocidad de evolucin del TMR1 oscila entre 1.6seg y
100mseg, por lo que solo podr medir periodos que oscilen entre los 62KHz y los 10 Hz.
list p=16F876,f=INHX8M
include "P16F876.INC"

PERIODO_H
PERIODO_L
CAP_TEMP_H
CAP_TEMP_L
N_FLANCO
W_TEMP
STATUS_TEMP

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ
equ
equ
equ
equ
equ
equ

0x20
0x21
0x22
0x23
0x24
0x25
0x26

org
goto
org
goto
org

0x00
inicio
0x04
inter
0x15

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

clrf
clrf
clrf
clrf
clrf

PERIODO_H
PERIODO_L
CAP_TEMP_H
CAP_TEMP_L
N_FLANCO

;
;
;
;
;

clrf
clrf
bsf
clrf
clrf
bsf
bsf
bcf

PORTB
PORTD
STATUS,RP0
TRISB
TRISD
TRISC,RC2
PIE1,CCP1IE
STATUS,RP0

;Borro el valor de
;los puertos B y D.
;Banco 1.
;Puerto B configurado como salida.
;Puerto D configurado como salida.
;Bit RC2 configurado como entrada.
;Habilito las posibles interrupciones del comparador 1.
;Vuelvo al banco 0.

Rubn Bartolom Henares

;(Se puede poner 0x05 o cualquier otra direccin).


\
|
> Borrar los registros de la memoria RAM.
|
/

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

clrf
clrf
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

TMR1L
TMR1H

;Despus de un reset el valor de estos registros es


;desconocido. Antes de poner en marcha el temporizador
;los borro para garantizar que comienzan a cero.

Calculamos el rango del pre-divisor:


20MHz 50ns = Tosc
1
-------- = 4Tosc = 450ns = 200ns
fosc/4
Debemos llegar al valor mnimo impuesto en el enunciado. Para ello emplearemos el
pre-escaler:
1.6s/200ns = 1600ns/200ns = 8
Con el pre-escaler x8 conseguimos este valor. El periodo mximo que conseguiremos
ser:
(FFFF)
655351.6s = 104587ms = 104.587s = Tmx

;T1CON = 00110001
; bits 7:6 (no implementados) Preferiblemente se escribirn ceros.
; bits 5:4 T1CKPS1:T1CKPS0=11 Rango del pre-divisor, x8.
; bit 3 T1OSCEN=0 Deshabilitamos el oscilador externo.
; bit 2 T1SYNC=0
Sincroniza la entrada del reloj externo con el interno.
; bit 1 TMR1CS=0
Reloj interno (fosc/4).
; bit 0 TMR1ON=1
Habilitacin del TMR1.
movlw b00110001
movwf T1CON

;Configuramos el registro T1CON en


;funcin de nuestras necesidades

; Segn el valor asignado al pre-escaler, despus de 1600ns se producir el primer


; flanco
200ns
400ns
;INTCON
; bit 7
; bit 6
; Todas

movlw b11000000
movwf INTCON

;Habilito las interrupciones


;globales y las de los perifricos

= 11000000
GIE=1
Activamos el bit general de interrupciones.
PEIE=1
Habilita la interrupcin de los perifricos.
las dems interrupciones deshabilitadas (ceros).

; Ya estamos preparados para que se produzcan interrupciones cada vez que el mdulo CCP
; detecte un flanco. Programamos ahora el mdulo CCP.
600ns
800ns
;CCP1CON =
; bits 7:6
; bits 5:4
; bits 3:0

movlw b00000101
movwf CCP1CON
00000101
(no implementados)
CCP1X:CCP1Y=00
CCP1M3:CCP1M0=0101

loop 1000ns
1200ns
1400ns
1600ns

movf
movwf
movf
movwf
goto

PERIODO_H,W
PORTB
PERIODO_L,W
PORTD
loop

Rubn Bartolom Henares

Preferiblemente se escribirn ceros.


En modo captura, ceros.(Solo se emplean en modo PWM).
En cada flanco ascendente.
;
; La deteccin se producir en este bucle. Cada vez que
; cuente 1600ns se detecta un flanco y se produce una
; interrupcin.
;

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

; *Nota: El que interrumpe al bucle anterior es el mdulo CCP1 no el TMR1 (no lo he


; configurado as):
;
;
(1) habilitado CCP1IE
;
Interrupcin
;
1 con flanco ascendente en RC2 CCP1IF
(solo si los dos a 1)
;
; / *** interrupcin *** /
;Lo primero es guardar todos los registros importantes para no perderlos
inter
movwf W_TEMP
;Guardar el W en un registro temporal.
swapf STATUS,W
;Intercambia los nibbles de STATUS
movwf STATUS_TEMP
;y lo guarda en un registro temporal.
clrf
STATUS
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0.
;Los registros ya estn guardados
btfss PIR1,CCP1IF
retfie
;
;
;
;
;

;Deteccin de una posible falsa interrupcin.

Con estas dos instrucciones conseguimos detectar posibles falsas interrupciones que no
son debidas al mdulo CCP1. Si CCP1IF=1 la interrupcin es debida al mdulo CCP1,
saltar una instruccin y continuar con la subrutina de interrupcin. Si este bit es
cero significa que el programa ha entrado en la subrutina de interrupcin pero no por
que CCP1 halla detectado un flanco ascendente. En este caso cancelamos la interrupcin
btfsc N_FLANCO,0
goto medir
movf
movwf
movf
movwf
incf

CCPR1L,W
CAP_TEMP_L
CCPR1H,W
CAP_TEMP_H
N_FLANCO,F

;Si es cero es el primer flanco, con lo cual lo


;guardar en los registros para restarlo despus. Si es
;uno voy a "medir".
;Guardo la parte baja
;del valor de CCPR1.
;Guardo la parte alta
;del valor de CCPR1.
;Incremento N_FLANCO para que la prxima vez valga uno
;y sea la segunda medida.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg. temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
bcf

PIR1,CCP1IF

;Borro el sealizador de interrupcin del CCP1 antes de


;salir para que el programa no vuelva a la interrupcin

CAP_TEMP_L,W
CCPR1L,W
PERIODO_L
STATUS,C
CAP_TEMP_H
CAP_TEMP_H,W
CCPR1H,W
PERIODO_H
PIR1,CCP1IF

;Resto las partes bajas


;de las dos medidas.
;Guardo la parte baja del resultado.
;Compruebo si ha habido acarreo (resta: C=0 acarreo)
;y si es as sumo uno al sustraendo.
;Resto las partes altas
;de las dos medidas
;y lo guardo en la parte alta del resultado.
;Borro el sealizador de interrupcin del CCP1.

retfie
medir

movf
subwf
movwf
btfss
incf
movf
subwf
movwf
bcf

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

swapf W_TEMP,F
swapf W_TEMP,W
;Los registros ya estn recuperados

;Intercambia el contenido del reg. temporal de W


;lo vuelve a intercambiar y lo transfiere al W.

retfie
end
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Ejemplo:
Si realizado el proceso, el valor que obtenemos es, por ejemplo:
PERIODO_H | PERIODO_L_
0 0
0 A
Este resultado quiere decir que tenemos 10 eventos de la base de tiempos del TMR1, es
decir:
101.6s = 16s
*Nota: 16s es el valor de nuestro periodo. Como se puede comprobar, los registros
PERIODO_H y PERIODO_L no reflejan el valor real de nuestro periodo, reflejan el valor
en funcin de la base de tiempos (dividido entre 1.6). Para que reflejasen el valor
real hara falta codificar una subrutina de multiplicacin para multiplicar el
resultado por la base de tiempos.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

EJERCICIO 4: Cdigo fuente


; *Nota: Como solo tengo 6 patillas en el puerto A solo emplear 6 bits; no me harn
; falta los registros altos del TMR1 ni del CCP1.
list p=16F876,f=INHX8M
include "P16F876.INC"
W_TEMP
STATUS_TEMP

inicio

;Tipo de procesador.
;Definiciones de registros internos.

equ
equ

0x20
0x21

org
goto
org
goto
org

0x00
inicio
0x04
inter
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

clrf
bsf
movlw
movwf
movlw
movwf
bcf
bsf
bcf

PORTB
STATUS,RP0
.6
ADCON1
b00111111
TRISA
TRISB,RB0
PIE1,CCP1IE
STATUS,RP0

;Borro el valor del puerto B.


;Banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar todas las patillas
;del puerto A como entradas.
;Configurar la patilla RB0 como salida.
;Habilito las posibles interrupciones del comparador 1.
;Vuelvo al banco 0.

movlw b00000010
movwf T1CON

;(Se puede poner 0x05 o cualquier otra direccin).

;Configuro el
;temporizador 1.

;T1CON = 00000010
; bits 7:6 (no implementados) Preferiblemente se escribirn ceros.
; bits 5:4 T1CKPS1:T1CKPS0=00 Rango del pre-divisor, 1:1
; bit 3 T1OSCEN=0 Deshabilitamos el oscilador externo.
; bit 2 T1SYNC=0
Sincroniza la entrada del reloj externo con el interno.
; bit 1 TMR1CS=1
Reloj externo procedente de la patilla RC0/T1OSO/T1CKL (flancos
;
ascendentes).
; bit 0 TMR1ON=0
Detiene el temporizador. (Lo habilitar ms tarde).
movlw b00001010
movwf CCP1CON
;CCP1CON =
; bits 7:6
; bits 5:4
; bits 3:0
;

00001010
(no implementados)
CCP1X:CCP1Y=00
CCP1M3:CCP1M0=1010

Preferiblemente se escribirn ceros.


En modo captura, ceros.(Solo se emplean en modo PWM).
Modo comparador. Genera una interrupcin por software
activando CCP1IF. La patilla CCP1 no se ve afectada.

clrf
clrf
clrf

TMR1L
TMR1H
CCPR1H

bsf

T1CON,TMR1ON ;Habilito el TMR1. Lo pongo en marcha ahora.

movlw b11000000
movwf INTCON
;INTCON
; bit 7
; bit 6
; Todas

;Configuro el
;mdulo CCP1.

;Despus de un reset no conocemos su valor. Antes de


;activar el TMR1 los borro para que comiencen a cero.
;Como no lo voy a utilizar lo borro.

;Configuro las
;interrupciones.

= 11000000
GIE=1
Activamos el bit general de interrupciones.
T0IE=1
Habilita la interrupcin de los perifricos.
las dems interrupciones deshabilitadas (ceros).

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

uno
;
;
;
;

sleep
goto
uno

;Duermo al
;microprocesador.

Entrar en la subrutina de interrupcin cuando se active CCP1IF. Cuando coincidan la


parte baja del comparador (no la he manipulado) y la del temporizador 1 (se ir
aumentando en uno con cada flanco ascendente) se producir la interrupcin (se
activar CCP1IF).

; / *** interrupcin *** /


;Lo primero es guardar todos los registros importantes para no perderlos
inter
movwf W_TEMP
;Guardar el W en un registro temporal.
swapf STATUS,W
;Intercambia los nibbles de STATUS
movwf STATUS_TEMP
;y lo guarda en un registro temporal.
clrf
STATUS
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0.
;Los registros ya estn guardados
btfss PIR1,CCP1IF
retfie

;Deteccin de una posible


;falsa interrupcin.

bcf
clrf
clrf
movlw
xorwf
clrf

;Paro el temporizador.
;Borro el posible valor que
;puedan tener los registros.
;Con esto consigo cambiar el valor
;del bit RB0 del puerto B.
;Lo borro por precaucin ya que no lo voy a usar.

T1CON,TMR1ON
TMR1L
TMR1H
b00000001
PORTB,F
CCPR1H

; Ahora hay que fijar cual ser el nmero de flancos a contar, que vendr dado por el
; valor de las patillas RA5:RA0.
movf
PORTA,W
andlw b00111111
movwf CCPR1L
;
;
;
;

;Enmascaramiento de
;bits no empleados.*
;Mando el valor a contar al registro bajo del CCP1.
;(Como se ha comentado antes, el alto no se emplea).

* En teora esta operacin no hace falta ya que el registro PORTA solo utiliza 6 bits
(tantos como patillas tiene el puerto), pero si hay problemas con los buses o
cualquier otro inconveniente se pueden modificar los bits 6 y 7. Los borro y ahorro
posibles problemas.
bsf
bcf

T1CON,TMR1CON
PIR1,CCP1IF

;Reanudo el funcionamiento del temporizador.


;Borro el sealizador de interrupcin del CCP1.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin.


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg. temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
retfie
; Problemas:
;
; La parte baja del comparador presentar un valor desconocido (entre 00 y FF) si se
;
produce un reset.
; No se si exactamente voy a entrar al momento o despus de 256 flancos.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

EJERCICIO 6: Cdigo fuente


;
;
;
;

Como vamos a tener que temporizar 1seg nos har falta la subrutina de temporizacin de
10mseg que hemos venido empleando en algunos de los ejercicios. Adems, nuestro
formato de transmisin ser de 8 bits, que es el tamao de los caracteres del cdigo
ASCII extendido (el que emplean los PCs).
list p=16F876,f=INHX8M
include "P16F876.INC"

CONT
W_TEMP
STATUS_TEMP

inicio

;
;
;
;
;
;

;Tipo de procesador
;Definiciones de registros internos

equ
equ
equ

0x20
0x21
0x22

org
goto
org
goto
org

0x00
inicio
0x04
inter
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

clrf
bsf
movlw
movwf

PORTC
STATUS,RP0
b10111111
TRISC

;Esto no hara falta.


;Banco 1.
;Configurar RC6/TX como salida (transmisor)
;y RC7/RX como entrada (receptor).

;(Se puede poner 0x05 o cualquier otra direccin).

En realidad no hara falta configurar estas patillas como entrada y salida. El


fabricante, Microchip, nos dice que para transmisin mediante la USART estos dos bits
de TRISC deberan estar a 1. ste es el estado que adquieren despus de un reset, es
decir, al iniciar el programa ya estn a uno y no hara falta configurarlos. Pero en
la prctica, asignando TX como salida y RX como entrada se obtiene el mismo resultado.
La configuracin escrita en el programa parece la ms lgica y evita confusiones.
movlw b11000111
movwf OPTION_REG

;Configuramos el
;temporizador 0.

;OPTION_REG = 11000111

;
;
;
;
;
;
;
;
;
;

bit 7 RBPU =1
bit 6
bit 5
bit 4
bit 3
bits 2:0

Da igual su estado. Las resistencias de pull-up se desconectan


automticamente al configurar el puerto B como salida. Activamos el
bit por precaucin.
INTEDG=1 Interrupcin externa activa con flanco ascendente en RB0/INT.
T0CS=0
Pulsos del reloj interno de frecuencia igual al ciclo de instruccin
T0SE=0
El incremento de TMR0 se produce por flanco ascendente del reloj.
PSA=0
Asigna el divisor de frecuencias al mdulo del TMR0
PS2:PS0=1
Selecciona el rango del divisor de frecuencia del TMR0 (256)
El porqu de cargar este valor fue explicado en el primer
ejercicio en el que se realiz la temporizacin de 10mseg.
movlw b00100100
movwf TXSTA

;Configuro el registro de control


;y estado de transmisin TXSTA.

;TXSTA = 00100100

;
;
;
;
;
;
;
;

bit 7 CSRC=0
bit 6
bit 5
bit 4
bit 3
bit 2

Bit de seleccin de procedencia de la seal. En modo asncrono no


afecta (da igual su valor).
TX9=0
Seleccionamos un formato de transmisin de 8 bits.
TXEN=1
Transmisin activada. (a partir de ya se puede transmitir si la
USART est activada)
SYNC=0
Modo asncrono.
No implementado (se lee como cero).
BRGH=1
Transmisin de alta velocidad. (en modo sncrono no afecta).

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

; bit 1 TRMT=0
;
; bit 0 TX9D=0
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Bit de estado del registro de desplazamiento de transmisin. Lo


iniciamos como vaco (cero).
Bit de dato del 9 bit del formato de transmisin. Es un bit de
salida, no de entrada. Nosotros no lo empleamos.

Debemos cargar ahora el registro SPBRG adecuadamente para poder trabajar a la


velocidad (en baudios) a la que vamos a transmitir.
Sabemos que la ecuacin que determina la velocidad en baudios viene definida por:
fosc
Velocidad = --------------( K(X + 1) )
La velocidad son 9600 baudios, K=16 ya que hemos seleccionado modo de alta velocidad
(BRGH=1), fosc es la que venimos empleando hasta ahora, 20MHz y X es el valor a cargar
en el registro SPRG. Despejamos X:
(fosc / velocidad) - K
X = -----------------------K
Sustituyendo los valores obtenemos X=129,2. Cargando el valor 129 en el registro
obtenemos una velocidad de aproximadamente 9615 baudios, muy acorde con la que
necesitamos.
movlw .129
movwf SPBRG

; Todo est preparado para que el programa comience a funcionar, solo falta habilitar la
; USART e inicializar el temporizador 0:
bcf

STATUS,RP0

bsf

RCSTATUS,SPEN ;USART en ON.

movlw
movwf
movlw
movwf

~.195
TMR0
.100
CONT

movlw b10100000
movwf INTCON
;INTCON
; bit 7
; bit 5
; Todas
uno

;Vuelvo al banco 0.

;Para poder
;temporizar 10mseg.
;Para temporizar
;1 segundo.
;Habilitamos la interrupcin
;del temporizador 0.

= 10100000
GIE=1
Activamos el bit general de interrupciones.
T0IE=1
Habilita la interrupcin del TMR0.
las dems interrupciones deshabilitadas (ceros).
goto

uno

;Colgamos al procesador.

; / *** interrupcin *** /


;Lo primero es guardar todos los registros importantes para no perderlos
inter
movwf W_TEMP
;Guardar el W en un registro temporal
swapf STATUS,W
;Intercambia los nibbles de STATUS
movwf STATUS_TEMP
;y lo guarda en un registro temporal.
clrf
STATUS
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0
;Los registros ya estn guardados

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

bcf
movlw
movwf
decfsz
retfie

INTCON,T0IF
~.195
TMR0
CONT,F

movlw A
call
tx_dato

;Borramos el sealizador de desbordamiento del TMR0.


;Recargamos
;otros 10 mseg.
;Decrementamos CONT.
;Si no vale cero, todava no pasado 1 segundo. Vuelvo
;a temporizar otros 10mseg hasta que llegue a 1 seg.
;Si es cero, ya ha pasado 1seg. Cargo el dato
;y lo envo.

movlw .100
movwf CONT

;Recargo el contador
;antes de regresar al bucle uno.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg. temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
retfie
; / *** Subrutina de transmisin de dato *** /
tx_dato

movwf TXREG

;Transmito el dato que previamente tena cargado en W.

; Ahora tendr que estar muestreando el bit de transmisin TRMT continuamente hasta que
; me indique que la transmisin ha finalizado:
dos

bsf
STATUS,RP0
btfss TXSTA,TRMT
goto
dos
return

;Voy al banco 1.
;Cuando el bit sea uno, habr finalizado la transmisin
;Mientras no sea as estar a cero, espero.

end
; *Nota: En el ensamblador MPLAB, no se pueden meter impulsos a TX y RX. No se puede
; simular la transmisin serie. Habra que poner manualmente a uno el bit TRMT para
; simular el fin de transmisin.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

EJERCICIO 7: Cdigo fuente


list p=16F876,f=INHX8M
include "P16F876.INC"
W_TEMP
STATUS_TEMP

inicio

;Tipo de procesador
;Definiciones de registros internos

equ
equ

0x20
0x21

org
goto
org
goto
org

0x00
inicio
0x04
inter
0x05

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

clrf
Clrf
bsf
movlw
movwf

PORTC
PORTB
STATUS,RP0
b10111111
TRISC

;Esto no hara falta.


;Borramos el valor que pueda tener el puerto B.
;Banco 1.
;Configurar RC6/TX como salida (transmisor)
;y RC7/RX como entrada (receptor).

movlw b00100100
movwf TXSTA

;(Se puede poner 0x05 o cualquier otra direccin).

;Configuro el registro de control


;y estado de transmisin TXSTA.

;TXSTA = 00100100

;
;
;
;
;
;
;
;
;
;
;
;

bit 7 CSRC=0
bit 6
bit 5
bit
bit
bit
bit

4
3
2
1

bit 0

Bit de seleccin de procedencia de la seal. En modo asncrono no


afecta (da igual su valor).
TX9=0
Seleccionamos un formato de transmisin de 8 bits.
TXEN=1
Transmisin activada. (a partir de ya se puede transmitir si la
USART est activada).
SYNC=0
Modo asncrono.
No implementado (se lee como cero).
BRGH=1
Transmisin de alta velocidad. (en modo sncrono no afecta).
TRMT=0
Bit de estado del registro de desplazamiento de transmisin. Lo
iniciamos como vaco (cero).
TX9D=0
bit de dato del 9 bit del formato de transmisin. Es un bit de
salida, no de entrada. Nosotros no lo empleamos.
bsf

PIE1,RCIE

;Habilitamos la recepcin de la posible interrupcin


;del USART.

bcf

STATUS,RP0

;Volvemos al banco 0.

movlw b10010000
movwf RCSTA
;RCSTA = 10010000

;
;
;
;
;
;
;
;
;
;

bit 7 SPEN=1
bit 6 RX9=0
bit
bit
bit
bit
bit
bit

5
4
3
2
1
0

SREN=0
CREN=1
ADDEN=0
FERR=0
OERR=0
RX9D=0

;Configuramos el registro de control


;y estado de recepcin RCSTA.

Habilitacin del puerto serie. Con un 1 se habilita el puerto serie


(se configuran las patillas RC7 y RC6 como RX y TX).
Recepcin del 9 bit. Como hemos elegido un formato de 8 bits,
lo deshabilitamos (cero).
Recepcin simple. En modo asncrono no afecta (cero).
Recepcin continua (un bit detrs de otro).
Deteccin de direccin. Solo si tenemos formato de 9 bits (cero).
Error de trama (no hay).
Error de sobrepaso (no hay).
Bit de dato del 9 bit del formato de recepcin. No nos interesa.

; A partir de aqu funciona el USART, pero no produce interrupciones. Las habilitamos:

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

2003 / 04
EJERCICIOS DE PROGRAMACIN III

uno

bsf
bsf

INTCON,PEIE
INTCON,GIE

goto

uno

;Habilitamos las interrupciones de los perifricos.


;(Es una buena tcnica habilitar siempre en ltimo
;lugar las interrupciones globales).

; / *** interrupcin *** /


;Lo primero es guardar todos los registros importantes para no perderlos
inter
movwf W_TEMP
;Guardar el W en un registro temporal.
swapf STATUS,W
;Intercambia los nibbles de STATUS
movwf STATUS_TEMP
;y lo guarda en un registro temporal.
clrf
STATUS
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0.
;Los registros ya estn guardados
btfss PIR1,RCIF
retfie

;Garantizamos que la interrupcin


;es producida por el USART.

movf
RCREG,W
movwf PORTB
call
tx_dato

;Reflejamos el dato recibido va serie


;asincrona en los leds del Puerto B.
;Transmito el dato.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg. temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
retfie
; / *** Subrutina de transmisin de dato *** /
tx_dato
dos

movwf TXREG
bsf
STATUS,RP0
btfss TXSTA,TRMT
goto
dos
return

;Transmito el dato que previamente tena cargado en W


;(lo ltimo cargado en W era el dato recibido en RCREG)
;Voy al banco 1.
;Cuando el bit sea uno, habr finalizado la transmisin
;Mientras no sea as estar a cero, espero.

end
; Observaciones:
; Los bits RCIF y TXIF, indicadores de interrupcin, se borran automticamente. No hay
;
que borrarlos por software como ocurra por ejemplo con T0IF.
; Mientras se transmite un dato (el programa est en tx_dato) puede estar recibindose
;
otro dato en RC6. Es una configuracin full-duplex.

Rubn Bartolom Henares

EJERCICIOS DE PROGRAMACIN III

PRCTICAS 2003 / 2004

PRCTICA 2: Diagrama de flujo

Prctica 2

Borrar
puerto B
y N_FLANCOS

NO

SI

Inicializar
puerto B salida
puerto A entrada

Incrementa
CONT

Leer puerto A y
guardar en
N_FLANCOS

SI

N_FLANCOS
=0?

Visualizar CONT
en el puerto B

N_FLANCOS
=0?
(STOP)

NO

RA4=0?

NO

SI
Retardo

RA4=1?

NO

SI
Retardo

Decrementar
N_FLANCOS

Rubn Bartolom Henares

PRCTICA 2 - 2

PRCTICAS 2003 / 2004

PRCTICA 2: Cdigo fuente


;
;
;
;
;

PRCTICA 2: ENTRADAS Y SALIDAS BSICAS (I)


GRUPO: 2L
MESA: 3
Alumnos:
BARTOLOM HENARES, RUBN
REVILLA GUTIRREZ, JESS
list
include

N_FLANCOS
CONT
DELAY1
DELAY2

p=16F876, f=INHX8M
"P16F876.INC"

;Tipo de procesador
;Definiciones de registros internos

equ
equ
equ
equ

0x51
0x52
0x53
0x54

;
;
;
;

org
goto

0x00
inicio

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

org

0x05

;El programa comienza despus del vector interrupcin.

inicio

clrf
clrf
clrf
bsf
movlw
movwf
movlw
movwf
clrf
bcf

N_FLANCOS
CONT
PORTB
STATUS,RP0
b'00000110'
ADCON1
b'00011111'
TRISA
TRISB
STATUS,RP0

;Borra N_FLANCOS.
;Borra CONT.
;Borra los latch de salida.
;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar las patillas RA4:RA0
;del puerto A como entrada.
;Configurar puerto B como salida.
;Vuelvo al banco 0.

leer_A

movf
andlw
btfsc
goto

PORTA,W
b'00001111'
STATUS,Z
leer_A

;Leer entradas RA3:RA0 y enviarlas al acumulador.


;Enmascaramiento de los bits no utilizados.
;Comprueba si RA3:RA0 valen cero (STOP) y si es as,
;vuelve a comprobarlos hasta que cambie su valor.
;Para cualquier otro valor comienza la ejecucin.
;Almacenamos el nmero de flancos a contar para
;incrementar CONT.

movwf N_FLANCOS
loop0

btfsc PORTA,4
goto
loop0
call
retardo

loop1

btfss
goto
call
decfsz
goto
incf
movf
movwf
goto

PORTA,4
loop1
retardo
N_FLANCOS,F
loop0
CONT,F
CONT,W
PORTB
leer_A

\
| Asignar a las distintas variables
| sus registros correspondientes.
/

;Deteccin de
;flanco de bajada.
;Llamada a subrutina para evitar rebotes mecnicos
;del interruptor.
;Deteccin de
;flanco de subida.
;Si N_FLANCOS no es cero
;vuelve a loop0.
;Si N_FLANCOS es cero incrementa el contador.
;Refleja el valor de CONT a
;la salida del puerto B.
;Vuelve a realizar todo el proceso.

; / *** Subrutina de retardo para evitar rebotes mecnicos en el interruptor *** /


retardo

movlw d'66'
movwf DELAY2

Rubn Bartolom Henares

PRCTICA 2 - 3

PRCTICAS 2003 / 2004

uno
dos

movlw
movwf
nop
decfsz
goto
decfsz
goto
return

0xFB
DELAY1
DELAY1,F
dos
DELAY2,F
uno

end

Rubn Bartolom Henares

PRCTICA 2 - 4

PRCTICAS 2003 / 2004

PRCTICA 3: Diagrama de flujo

Prctica 3

Borrar
puerto B
y N_FLANCOS

NO

N_FLANCOS
=0?

SI
Inicializar
puerto B salida
puerto A entrada

Incrementa
CONT

Leer puerto A y
guardar en
N_FLANCOS

SI

SI

NO

N_FLANCOS
=0?
(STOP)

Tabla

NO

RA4=0?

CONT=20?
(mximo)

NO

Enviar el valor de
CONT convertido al
puerto B (display)

SI
Fin

Retardo

RA4=1?

SI

NO

Tabla

Sumar
desplazamiento al PC
(digito hex.)

Retardo
Localizar valor en
cdigo 7 segmentos

Decrementar
N_FLANCOS

Visualizar en el
puerto B
(display)

Retorna

Rubn Bartolom Henares

PRCTICA 3 - 2

PRCTICAS 2003 / 2004

PRCTICA 3: Cdigo fuente


;
;
;
;
;

PRCTICA 3: ENTRADAS Y SALIDAS BSICAS (II)


GRUPO: 2L
MESA: 3
Alumnos:
BARTOLOM HENARES, RUBN
REVILLA GUTIRREZ, JESS
list
include

N_FLANCOS
CONT
DELAY1
DELAY2

p=16F876, f=INHX8M
"P16F876.INC"

;Tipo de procesador
;Definiciones de registros internos

equ
equ
equ
equ

0x51
0x52
0x53
0x54

;
;
;
;

org
goto

0x00
inicio

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

org

0x05

;El programa comienza despus del vector interrupcin.

inicio

clrf
clrf
clrf
bsf
movlw
movwf
movlw
movwf
clrf
bcf
movlw
movwf

N_FLANCOS
CONT
PORTB
STATUS,RP0
b'00000110'
ADCON1
b'00011111'
TRISA
TRISB
STATUS,RP0
b'00111111'
PORTB

;Borra N_FLANCOS.
;Borra CONT
;Borra los latch de salida.
;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar las patillas RA4:RA0
;del puerto A como entrada.
;Configurar puerto B como salida.
;Vuelvo al banco 0.
;Inicializo el display
;con el nmero cero.

leer_A

movf
andlw
btfsc
goto

PORTA,W
b'00001111'
STATUS,Z
leer_A

;Leer entradas RA3:RA0 y enviarlas al acumulador.


;Enmascaramiento de los bits no utilizados.
;Comprueba si RA3:RA0 valen cero (STOP) y si es as,
;vuelve a comprobarlos hasta que cambie su valor.
;Para cualquier otro valor comienza la ejecucin.
;Almacenamos el nmero de flancos a contar para
;incrementar CONT.
;Deteccin de
;flanco de bajada.
;Llamada a subrutina para evitar rebotes mecnicos
;del interruptor.
;Deteccin de
;flanco de subida.

movwf N_FLANCOS
loop0

btfsc PORTA,4
goto
loop0
call
retardo

loop1

btfss
goto
call
decfsz
goto
incf

PORTA,4
loop1
retardo
N_FLANCOS,F
loop0
CONT,F

movlw
subwf
btfss
goto
goto

d'20'
CONT,W
STATUS,Z
visualizar
inicio

Rubn Bartolom Henares

\
| Asignar a las distintas variables
| sus registros correspondientes.
/

;Si N_FLANCOS no es cero


;vuelve a loop0.
;Si N_FLANCOS es cero incrementa el contador.
;Cargamos el valor mximo que queremos que cuente en W
;y se lo restamos a CONT, guardando el resultado en W.
;Si CONT an no ha llegado a 19, la resta no
;ser cero (Z=0) y pasa a visualizar el resultado.
;Si se ha llegado al tope, CONT=20, la resta ser cero
;(Z=1) y en este caso reiniciamos el programa.

PRCTICA 3 - 3

PRCTICAS 2003 / 2004

visualizar

movf
andlw
call
movwf
clrf
goto

CONT,W
b'00011111'
tabla
PORTB
PCLATH
leer_A

;Llevo CONT a W
;Enmascaramiento de bits no utilizados.
;Llamo a la subrutina para visualizar en el display.
;Enviar la codificacin de los segmentos al puerto B
;Borro el PCLATH.
;Voy a por el siguiente nmero.

; / *** Subrutina de retardo para evitar los rebotes mecnicos del interruptor *** /
retardo
uno
dos

movlw
movwf
movlw
movwf
nop
decfsz
goto
decfsz
goto
return

d'66'
DELAY2
0xFB
DELAY1
DELAY1,F
dos
DELAY2,F
uno

; / *** Subrutina para visualizar en el display el valor de CONT *** /


tabla

addwf
nop
;segmentos
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw

PCL,F
.gfedcba
b'00000110'
b'01011011'
b'01001111'
b'01100110'
b'01101101'
b'01111101'
b'00000111'
b'01111111'
b'01101111'
b'10111111'
b'10000110'
b'11011011'
b'11001111'
b'11100110'
b'11101101'
b'11111101'
b'10000111'
b'11111111'
b'11101111'

;Esta lnea corresponde al 0, que ya est visualizado.


; 1
; 2
; 3
; 4
; 5
; 6
; 7
; 8
; 9
;10
;11
;12
;13
;14
;15
;16
;17
;18
;19

end

Rubn Bartolom Henares

PRCTICA 3 - 4

PRCTICAS 2003 / 2004

PRCTICA 4: Diagrama de flujo

NO

Prctica 4

temporizar

Borrar
puerto B

CONT=50

Inicializar
puerto B salida
puerto A entrada

Borrar T0IF y
cargar el valor para
temporizar 10mseg
TMR0=61

RA4=1?

NO

T0IF=1?
(desbordamiento)

SI

SI
Encender el
led conectado
a RB0

temporizar

Decrementar el
contador
CONT = CONT-1

NO
CONT=0?

SI
Apagar el
led conectado
a RB0

Retorna

temporizar

Fin

Rubn Bartolom Henares

PRCTICA 4 - 2

PRCTICAS 2003 / 2004

PRCTICA 4: Cdigo fuente


;
;
;
;
;

PRCTICA 4: TEMPORIZADORES E INTERRUPCIONES


GRUPO: 2L
MESA: 3
Alumnos:
BARTOLOM HENARES, RUBN
REVILLA GUTIRREZ, JESS
list
include

CONT

inicio

p=16F876, f=INHX8M
"P16F876.INC"

;Tipo de procesador
;Definiciones de registros internos

equ

0x50

;Asignar a la variable su registro correspondiente.

org
goto

0x00
inicio

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

org

0x05

;El programa comienza despus del vector interrupcin.

clrf
bsf
movlw
movwf
bsf
bcf
movlw
movwf

PORTB
STATUS,RP0
b'00000110'
ADCON1
TRISA,0
TRISB,0
b'10000111'
OPTION_REG

;Borra los latch de salida.


;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar RA0 de puerto A como entrada.
;Configurar RB0 de puerto B como salida.
;Configuramos el registro OPTION_REG
;de acuerdo a nuestras necesidades.

;OPTION_REG = 10000111

;
;
;
;
;
;
;
;
;
;
;
;

bit 7 RBPU =1
bit 6
bit 5
bit 4
bit 3
bits 2:0

uno
dos

Da igual su estado. Las resistencias de pull-up se desconectan


automticamente al configurar el puerto B como salida. Activamos el
bit por precaucin.
INTEDG=0 Selecciona el flanco en el que se activa la interrupcin si entrase
una seal por RB0/INT, peor como nosotros estamos empleando esta
patilla como salida, el estado de este bit no influye.
T0CS=0
Reloj interno, de frecuencia igual al ciclo de instruccin (CLKOUT)
T0SE=0
Selecciona en que flanco, ascendente o descendente en RA4, se va a
incrementar el TMR0. Aqu da igual, el TMR0 se va a incrementar
con los flancos del reloj interno. Da igual el valor.
PSA=0
Asigna el divisor de frecuencias al temporizador 0, TMR0
PS2:PS0=1
Selecciona el rango del divisor de frecuencias del TMR0 (256)
bcf

STATUS,RP0

;Vuelvo al banco 0.

btfss
goto
bsf
call
bcf
call
goto

PORTA,0
uno
PORTB,0
temporizar
PORTB,0
temporizar
uno

;Cuestiono el valor de RA0


;hasta que valga uno, momento
;en el que pongo a uno RB0.
;y lo mantengo 0.5 seg a uno.
;Despus borro RB0,
;y lo mantengo otros 0.5 seg borrado.
;Realiza el proceso de nuevo.

/ *** Subrutina de temporizacin de 0.5 segundos *** /

temporizar
otravez

movlw
movwf
bcf
movlw
movwf

d'50'
CONT
INTCON,2
d'61'
TMR0

Rubn Bartolom Henares

;Borro el bit T0IF de desbordamiento del TMR0

PRCTICA 4 - 3

PRCTICAS 2003 / 2004

preguntar

btfss
goto
decfsz
goto
bcf
return

INTCON,2
preguntar
CONT,F
otravez
INTCON,2

;Cuestiono T0IF hasta que se produzca


;la interrupcin, momento en el que
;decrementar el contador y volver a
;realizar el proceso de nuevo, hasta que
;el CONT valga cero, momento en el que
;habr finalizado la temporizacin de 0.5seg.

end
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Explicacin del valor cargado en el TMR0:


Este calculo lo debe realizar el propio programador. Sabemos que la ecuacin que
define la temporizacin para el TMR0 es:
T = 4Tosc(256 - carga)preescala
Si despejamos la carga:
T
carga = 256 - -----------------4Toscpreescala
La temporizacin que deseamos es T = 10mseg. La preescala viene definida por el
estado de los bits PS2, PS1 y PS0 del registro OPTION_REG. Los tres poseern el valor
1 ya que, como se ha comentado, despus de un reset todos los bits de OPTION_REG se
ponen a uno. Se estar cargando, por tanto, y segn el rango de funcionamiento del
predivisor, el valor 256; luego preescala = 256. (Si se deseara otra preescala,
bastara con modificar los bits PS por programa). El periodo del oscilador ser la
inversa de la frecuencia, que en nuestro caso es de 20MHz. Por tanto, Tosc = 200nseg.
Sustituyendo todos los datos en la ecuacin se obtiene:
carga = 60.6875
Debemos tomar un valor entero para cargarle en el TMR0. Cul es el correcto, 60 o
61? Calculamos a continuacin cul sera la temporizacin para ambos valores de la
carga:
carga = 60 T = 10.0352 mseg
carga = 61 T = 9.9840 mseg
El segundo valor es el correcto, 61, ya que con el primero nos pasamos. Si queremos
ajustar nuestro valor siempre ser ms sencillo ajustar la temporizacin deseada
incluyendo en el programa instrucciones "nop".

Rubn Bartolom Henares

PRCTICA 4 - 4

PRCTICAS 2003 / 2004

PRCTICA 5: Diagrama de flujo

Prctica 5

RA5:RA0 del
puerto A como
entradas

RC2/CCP1 como
salida del modo
PWM

Cargar en PR2 el
valor para obtener
2KHz de ciclo PWM

Configurar el
mdulo CCP1 en
modo PWM

Configurar el TMR2
con el valor del
pre-escaler
calculado

Asignar el valor en
puerto A al ciclo de
servicio del PWM

Rubn Bartolom Henares

PRCTICA 5 - 2

PRCTICAS 2003 / 2004

PRCTICA 5: Cdigo fuente


;
;
;
;
;

PRCTICA 5: MDULO CAPTURA, COMPARACIN Y PWM.


GRUPO: 2L
MESA: 3
Alumnos:
BARTOLOM HENARES, RUBN
REVILLA GUTIRREZ, JESS
list
include

inicio

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

p=16F876, f=INHX8M
"P16F876.INC"

;Tipo de procesador
;Definiciones de registros internos

org
goto

0x00
inicio

;Vector de reset. Estas dos lneas sirven


;para cargar el programa en el mdulo.

org

0x05

;El programa comienza despus del vector interrupcin.

bsf
movlw
movwf
movlw
movwf
clrf

STATUS,RP0
b'00000110'
ADCON1
b'00111111'
TRISA
TRISC

;Selecciona el banco 1.
;Configurar puerto A
;como E/S digitales.
;Configurar RA5:RA0
;como entradas.
;Configurar la patilla RC2/CCP1 como salida
;del modo PWM.

Calculamos el valor a cargar en el temporizador 2 para obtener 2KHz de periodo. La


ecuacin que determina el periodo es:
Periodo_PWM = (PR2 + 1)4ToscPre-divisor_TMR2
Despejamos PR2 que es el valor que deberemos cargar:
Periodo_PWM
PR2 = -------------------------- - 1
4ToscPre-divisor_TMR2
El periodo son 1/2KHz = 0.5mseg, 4Tosc son 200nseg y para el pre-divisor le daremos
primeramente el valor 1. Con todo esto obtenemos:
PR2 = 2499
Evidentemente, este valor no se puede cargar en un registro de 8 bits. Para reducir
el valor a cargar asignaremos al pre-divisor el valor 16. Con este valor, el
resultado es:
PR2 = 155.25
El valor a cargar es, por tanto, PR2 = 156
movlw
movwf
bcf
clrf

d'156'
PR2
STATUS,RP0
TMR2

movlw b'00001100'
movwf CCP1CON
;CCP1CON =
; bits 7:6
; bits 5:4
; bits 3:0

00001100
(no implementados)
CCP1X:CCP1Y=00
CCP1M3:CCP1M0=11xx

Rubn Bartolom Henares

;Cargamos en el registro PR2 el valor calculado


;para el periodo de la seal del mdulo PWM.
;Vuelvo al banco 0.
;Borramos el TMR2 antes de configurarlo
;para asegurarnos de que comienza en cero.
;Configuramos el mdulo CCP1 en modo PWM. Los 2 bits
;menos significativos del PWM los iniciaremos como 0s
Preferiblemente se escribirn ceros.
Los iniciamos como ceros (no hay ajuste fino).
Modo PWM.

PRCTICA 5 - 3

PRCTICAS 2003 / 2004

movlw b'00000110'
movwf T2CON

;Configuramos el TMR2 acorde con nuestras necesidades.


;(Ya habamos calculado que el pre-escaler valdra 16
;para poder llegar al periodo deseado).

;T2CON = 00000110
; bit
7 (no implementados)
; bits 6:3 TOUTPS3:TOUTPS0=0000
; bit
2 TMR2ON=1
; bits 1:0 T2CKPS1:T2CKPS0=1x
leer_ciclo

movf
andlw
movwf
goto

PORTA,W
b'00111111'
CCPR1L
leer_ciclo

Preferiblemente se escribirn ceros.


Rango del post-divisor, 1:1.
El TMR2 est en servicio.
Rango del pre-divisor, 1:16.

;Llevo el valor del ciclo de servicio introducido en


;PORTA, realizando un enmascaramiento previo,
;al registro CCPR1L. El ciclo ya est asignado.

end

Rubn Bartolom Henares

PRCTICA 5 - 4

PRCTICAS 2003 / 2004

PRCTICA 6: Diagrama de flujo

Prctica 6

interrupcin

RC7/RX entrada
RC6/TX salida

Borrar el flag de
indicacin de
interrupcin por
recepcin RCIF

Configurar los
registros RCSTA y
TXSTA

Guardar el dato
recibido

Configurar la
velocidad de trabajo
del procesador

DATO<A ?
(en la codificacin
ASCII)

NO

Habilitar
interrupciones de
recepcin,
perifricos y global

nop

SI

NO

DATO>Z ?

SI

(en la codificacin
ASCII)

Sumar 32 a
DATO (letra
minscula) y
enviar

Fin de
transmisin?

Enviar el mensaje
Error

NO

Fin de
transmisin?

SI

NO

SI

Retorno

AR

Rubn Bartolom Henares

B
RO
PRCTICA 6 M
-P
2
CO
SIN

PRCTICAS 2003 / 2004

PRCTICA 6: Cdigo fuente


;
;
;
;
;

PRCTICA 6: EL MDULO USART


GRUPO: 2L
MESA: 3
Alumnos:
BARTOLOM HENARES, RUBN
REVILLA GUTIRREZ, JESS
list
include

DATO
STATUS_TEMP
W_TEMP

inicio

p=16F876, f=INHX8M
"P16F876.INC"

equ
equ
equ

0x20
0x21
0x22

org
goto
org
goto

0x00
inicio
0x04
inter

clrf
bsf
movlw
movwf

PORTC
STATUS,RP0
b'10111111'
TRISC

movlw b'00100100'
movwf TXSTA

;Tipo de procesador.
;Definiciones de registros internos.

;Registro para almacenar el dato recibido.


;Registros para almacenar STATUS y W
;durante la rutina de interrupcin.

;Esto no hara falta (es costumbre).


;Banco 1.
;Configurar RC7/RX como entrada (receptor)
;y RC6/TX como salida (transmisor).
;Configurar el registro de control
;y estado de transmisin TXSTA.

;TXSTA = 00100100

;
;
;
;
;
;
;
;
;
;
;
;

bit 7 CSRC=0

;
;
;
;
;
;
;
;
;
;
;
;

Debemos cargar ahora el registro SPBRG adecuadamente para poder trabajar a la


velocidad (en baudios) a la que vamos a transmitir.

bit 6
bit 5
bit
bit
bit
bit

4
3
2
1

bit 0

Bit de seleccin de procedencia de la seal. En modo asncrono no


afecta (da igual su valor).
TX9=0
Seleccionamos un formato de transmisin de 8 bits.
TXEN=1
Transmisin activada. (a partir de ya se puede transmitir si la
USART est activada)
SYNC=0
Modo asncrono.
No implementado (se lee como cero).
BRGH=1
Transmisin de alta velocidad. (en modo sncrono no afecta).
TRMT=0
Bit de estado del registro de desplazamiento de transmisin. Lo
iniciamos como vaco (cero).
TX9D=0
Bit de dato del 9 bit del formato de transmisin. Es un bit de
salida, no de entrada. Nosotros no lo empleamos.

La velocidad son 9600 baudios, K=16 ya que hemos seleccionado modo de alta velocidad
(BRGH=1), fosc son 20MHz y X es el valor a cargar en el registro SPRG, que vendr
determinado por:
(fosc / velocidad) - K
X = -----------------------K
Sustituyendo los valores obtenemos X=129,2. Cargando el valor 129 en el registro
obtenemos una velocidad de aproximadamente 9615 baudios.
movlw .129
movwf SPBRG

;La velocidad de transmisin


;ser de 9600 baudios.

bsf
bcf

;Habilitar la recepcin de interrupciones.


;Banco 0.

PIE1,RCIE
STATUS,RP0

AR

Rubn Bartolom Henares

B
RO
PRCTICA 6 M
-P
3
CO
SIN

PRCTICAS 2003 / 2004

movlw b'10010000'
movwf RCSTA
;RCSTA = 10010000

;
;
;
;
;
;
;
;
;
;

bit 7 SPEN=1
bit 6 RX9=0
bit
bit
bit
bit
bit
bit

5
4
3
2
1
0

SREN=0
CREN=1
ADDEN=0
FERR=0
OERR=0
RX9D=0

;Configurar el registro de control


;y estado de recepcin RCSTA.

Habilitacin del puerto serie. Con un 1 se habilita el puerto serie


(se configuran las patillas RC7 y RC6 como RX y TX).
Recepcin del 9 bit. Como hemos elegido un formato de 8 bits,
lo deshabilitamos (cero).
Recepcin simple. En modo asncrono no afecta (cero).
Recepcin continua (un bit detrs de otro).
Deteccin de direccin. Solo si tenemos formato de 9 bits (cero).
Error de trama (no hay).
Error de sobrepaso (no hay).
Bit de dato del 9 bit del formato de recepcin. No nos interesa.

; A partir de aqu funciona el USART, pero no produce interrupciones. Las habilitamos:

uno

bsf
bsf

INTCON,PEIE
INTCON,GIE

;Habilitacin de interrupcin de perifricos.


;Habilitacin global de interrupciones.

goto

uno

;Colgamos al procesador.

; / *** Rutina de interrupcin *** /


;Lo primero es guardar todos los registros importantes para no perderlos
inter
movwf W_TEMP
;Guardar el W en un registro temporal.
swapf STATUS,W
;Intercambia los nibbles de STATUS
movwf STATUS_TEMP
;y lo guarda en un registro temporal.
clrf
STATUS
;Banco 0, sin importar el banco actual, borra
;los bits IRP,RP1,RP0.
;Los registros ya estn guardados

error_

bcf
INTCON,T0IF
btfss PIR1,RCIF
retfie

;Comprobar si la interrupcin ha
;sido provocada por el USART.
;Si no es as, retorna.

movf
movwf
movfw
subwf
btfss
goto
movlw
subwf
btfsc
goto
goto

RCREG,W
DATO
'A'
DATO,W
STATUS,C
error_
'Z'
DATO,W
STATUS,C
error_
responder

;Guardar el valor recibido


;desde el PC a un registro.
;Comprobar si el dato recibido est, en la
;codificacin ASCII, por debajo de la letra "A".
;Si es as, el bit carry valdr cero
;y se enviar el mensaje "Error".
;Sino, comprobamos ahora si el dato recibido
;est por debajo de la letra "Z" restando Z-DATO.
;Si el dato no es vlido, carry valdr
;uno y enviaremos el mensaje de "Error".
;Si es vlido, enviaremos la respuesta.

movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf
movlw
movwf

'E'
TXREG
'r'
TXREG
'r'
TXREG
'o'
TXREG
'r'
TXREG

bsf

STATUS,RP0

;Banco 0 (Ya estoy en el banco 0, pero por si acaso).

AR

Rubn Bartolom Henares

B
RO
PRCTICA 6 M
-P
4
CO
SIN

PRCTICAS 2003 / 2004

dos

btfss TXSTA,TRMT
goto
dos

;Ha terminado de enviar datos hacia el PC?.


;No. Vuelve a preguntar.
;Si. Recupera los registros y retorna.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
retfie
responder

tres

movlw
addwf
movwf
bsf
btfss
goto

.32
DATO,W
TXREG
STATUS,RP0
TXSTA,TRMT
tres

;Sumar al DATO almacenado el valor 32 para obtener


;el equivalente en minscula de la letra recibida
;y enviarlo hacia el PC.
;Banco 0.
;Ha terminado de enviar datos hacia el PC?.
;No. Vuelve a preguntar.
;Si. Recupera los registros y retorna.

;Recupero los registros guardados antes de finalizar la rutina de interrupcin


swapf STATUS_TEMP,W
;Vuelve a intercambiar STATUS_TEMP y lo
movwf STATUS
;devuelve a STATUS en su estado original.
swapf W_TEMP,F
;Intercambia el contenido del reg temporal de W
swapf W_TEMP,W
;lo vuelve a intercambiar y lo transfiere al W.
;Los registros ya estn recuperados
retfie
end

AR

Rubn Bartolom Henares

B
RO
PRCTICA 6 M
-P
5
CO
SIN

También podría gustarte