Professional Documents
Culture Documents
Microcontrolador PIC16F84
Programa:
;------------------------------------------------------
;PROGRAMA PORTB.ASM
;Apagar y encender el puerto B cada segundo
;-------------------------------------------------------
;-------------------------------------------
; Configurar el puerto B como salida
;--------------------------------------------
; Registro TRISB=00h para salidas.
bsf STATUS,5 ; pongo a uno el bit 5 del registro STATUS para entrar en el banco1.
movlw 00h ; cargo w con el dato 00h.
movwf TRISB ; cargo el registro TRISB con el w para hacer el puerto B como salida.
Bcf STATUS,5 ; pongo a cero el bit 5 del registro STATUS para entrar en el banco 0.
;----------------------------------
;PROGRAMA PRINCIPAL
;-----------------------------------
programa ; etiqueta de programa principal.
movlw 00h ; cargo w con el dato 00h
movwf PORTB ; cargo el registro PORTB con w apagando los leds.
call sg1 ; subrutina de retardo de 1 seg.
movlw 0ffh ; cargo w con el dato ffh.
movwf PORTB ; cargo el registro PORTB con w encendiendo los leds.
call sg1 ; subrutina del retardo de 1 seg.
goto programa ; salta al comienzo del programa.
;------------------------------------------------
;RETARDOS
;------------------------------------------------
;ffh=255 goto=2 useg. decfsz=1 useg.
;(255 x 2) + 255= 765 useg
;(765 x 765) + 255= 585480 useg.
;(585480 x 2) + 1= 1170961 useg.
sg1 ; etiqueta = subrutina del retardo de 1 seg.
movlw 0ffh ; cargo w con el dato ffh.
movwf 0ch ; cargo el registro 0ch con el w.
movwf 0dh ; cargo el registro 0dh con el w.
movlw 01h ; cargo w con el dato 01h.
movwf 0eh ; cargo el registro 0eh con w.
Objetivo: Hacer juegos de encendidos y apagados de leds conectados al puerto B. A la vez practicaremos con
las instrucciones: swapf f,d Rlf f,d Rrf f,d
La instrucción swapf f,d intercambia los 4 bits de mayor peso por los cuatros de menor peso y viceversa del
dato contenido en el registro usado. Ejemplo: swapf 0ch,1
Si tuviéramos en el registro 0ch el dato 0fh, al aplicar la instrucción el contenido se transformaría en f0h y lo
guardaríamos en 0ch por ser d= 1. Si fuese d= 0 lo guardaríamos en el acumulador w.
La instrucción rlf f,d desplaza el contenido del registro usado hacia la izquierda, introduciendo por el lugar del
bit de menor peso el valor del acarreo. El acarreo es a su vez cargado con el contenido del bit de más peso del
dato contenido en el registro usado. El contenido es almacenado en el registro si d= 1 y si no será guardado en
el acumulador w por ser d= 0. Ejemplo: rlf 0ch,1
Si el valor contenido en el registro 0ch es 01h y el acarreo es cero, al desplazarse hacia la izquierda el contenido
será 02h. El valor 02h se guardará en 0ch por ser d= 1.
La instrucción rrf f, d desplaza el contenido del registro usado hacia la derecha introduciendo el valor del
acarreo por el bit de más peso y cargándose el acarreo con el valor del bit de menor peso del registro. El valor
del dato se guardará en el registro si d= 1 o en el acumulador w, si d= 0.
;-----------------------------------
;PROGRAMA PRINCIPAL
;-----------------------------------
programa
movlw 00h ; cargo w con el dato 00h.
movwf PORTB ; cargo el registro PORTB con el w.
call sg1 ; subrutina de retardo de 1 seg.
call sg1
movlw 0fh ; cargo w con el dato 0fh.
movwf PORTB ; cargo el registro PORTB con el w.
call sg1
call sg1
swapf PORTB,1 ; aplico la instrucción al contenido del registro PORTB y lo
; deposito en el mismo ya que d= 1
call sg1
call sg1
movlw 0ffh ; cargo el w con el dato ffh.
movwf PORTB ; cargo PORTB con el w.
call sg1
call sg1
call rotacion ; subrutina de rotar un solo led de derecha a izquierda y
; viceversa ,una sola vez.
goto programa ; salto al comienzo del programa principal.
;-------------------------------------------------------------
;PROGRAMA DE ROTACION.
;-------------------------------------------------------------
rotacion
movlw 00h ; cargo w con el dato 00h.
movwf 10h ; cargo registro 10h con el w.
movlw 09h ; cargo w con el dato 09h.
movwf 11h ; cargo el registro 11h con w.
bsf STATUS,0 ; pongo a uno el bit 0 del STATUS ( bit 0 = C = acarreo )
der
decfsz 11h,1 ; decremento el registro 11h y salto si es cero y deposito el
; contenido en 11h ya que d=1
goto derecha ; salto a la etiqueta ( dirección ) llamada derecha.
movlw 08h ; cargo w con el dato 08h.
movwf 11h ; cargo el registro 11h con w.
bcf STATUS,0 ; pongo a cero el bit 0 de STATUS ( bit 0 = C = acarreo ).
izq
decfsz 11h,1 ; decremento el registro 11h y salto si vale cero depositando el
; contenido en el mismo ya d= 1.
goto izquierda ; salto a la etiqueta ( dirección ) llamada izquierda.
return; regreso de subrutina.
derecha
rrf 10h,0 ; roto a la derecha el contenido del registro 10h y lo almaceno en
; w ya que d=0
movwf 10h ; cargo el registro 10h con el w.
movwf PORTB ; cargo el registro PORTB con el w.
call sg1
goto der ; salto a etiqueta der.
izquierda
rlf 10h,0 ; roto a la izq. el contenido del registro 10h y lo almaceno en w
; ya que d=0
movwf 10h ; cargo 10h con el w.
movwf PORTB ; cargo PORTB con w.
call sg1
goto izq ; salto a etiqueta izq.
; RETARDOS
sg1
movlw 0ffh
movwf 0ch
movwf 0dh
movlw 01h
movwf 0eh
salto1
decfsz 0ch,1
goto salto1
decfsz 0dh,1
goto salto1
decfsz 0eh,1
goto salto1
return
end
PRACTICA Nº 3
Microcontrolador PIC16F84A.
Objetivo: Comprobar como funciona la interrupción externa, RB0/INT. Al actuar sobre el pin RB0/INT mediante
un pulsador provocaremos que el puerto A, al cual, hemos conectados unos leds, se apaguen y enciendan en un
bucle repetitivo.
Esquema eléctrico:
Programa:
;---------------------------------------------------------
;PROGRAMA inter.ASM
;Cómo funciona la interrupción externa /Int.
;---------------------------------------------------------
list p=16f84A
include "p16F84A.inc"
;---------------------------------------------------
;RESET
;---------------------------------------------------
org 0h
reset
goto inicio
;------------------------------
;INTERRUPCION
;------------------------------
org 04h
goto int
;--------------------------------
;PUNTERO DE INICIO
;--------------------------------
org 10h
inicio
;-----------------------------------------------------------
;Configurar el puerto A como salida.
;-----------------------------------------------------------
;Registro TRISB=00h para salidas.
bsf STATUS,RP0 ; banco1
movlw 00h
movwf TRISA ; puertoA como salida
bcf STATUS,RP0 ; banco0
;-----------------------
;PuertoA apagado.
;-----------------------
movlw 00h
movwf PORTA
;------------------------------------------------
;Configurar el registro OPTION_REG. Flanco de bajada.
;------------------------------------------------
;Registro OPTION_REG bit6=INTEDG= 0= flanco descendente
bsf STATUS,RP0 ; banco1
bcf OPTION_REG,INTEDG ; flanco descendente
bcf STATUS,RP0 ; banco0
;--------------------------------------------------------------------------------
;Configurar el registro INTCON. Habilitar permisos de interrupciones general y particular de
; /Int. Habilitar permiso de interrupción global.
bsf INTCON,GIE ; 1= activación permiso general.
;Habilitar permiso int.
bsf INTCON,INTE ; 1= activación permiso /int.
;---------------------------------------------------------------------
;Esperando la interrupción.
; Cuando pulse el botón provoco un flanco de bajada y salgo del bucle de espera. La bandera
; pasa a 1 y salto al programa de la interrupción y luego al programa principal, haciendo
;infinitos bucles. La /Int la uso como autorización (pulsar el botón) para ejecutar el
;programa principal.
;---------------------------------------------------------------------
espera
btfss INTCON,INTF ; salta si es uno
goto espera ; salto a "espera" hasta que la bandera sea 1.Cuando pulse el botón
int
bcf INTCON,GIE ; 0 para no más interrupciones de ningún tipo.
bcf INTCON,INTE ; 0 para no más interrupción /Int.
; Poner a cero el flag de la /Int., necesario si hubiera más interrupciones de /Int. Este
; programa solo va haber una "unica" llamada a la /Int. y se ejecutará el programa principal
;indefinidamente deshabilitando para siempre la /Int.
;-------------------------------------------------------------------------
;Retardos.
;--------------------------------------------------------------------------
;0ch, 0dh y 0eh registros RAM del GPR
;----------------------------------------
sg1 ; 1005723 useg.
movlw 0c1h
movwf 0ch
movwf 0dh
movlw 01h
movwf 0eh
salto1
decfsz 0ch,1
goto salto1
decfsz 0dh,1
goto salto1
decfsz 0eh,1
goto salto1
return
Objetivo: Hacer funcionar el contador y ver como al desbordarse el contador provoca una interrupción. El pin
nº6 es la entrada de un contador que cuenta de 00h a ffh. Al pasar de ffh a 00h provoca una interrupción y la
subida de una bandera o flag.
Esquema eléctrico:
Programa:
;----------------------------------------------
;PROGRAMA CONTADOR.ASM
;Probar el contador y su interrupción.
;----------------------------------------------
list p=16f84A
include "p16F84A.inc"
;------------------------------
;RESET
;------------------------------
org 00h
reset
goto inicio
;------------------------------
;INTERRUPCION
;------------------------------
org 04h
goto int
;------------------------------
;PUNTERO DE INICIO
;------------------------------
org 10h
inicio
;-----------------------------------------------------
;Configurar el puerto A como salida
;-----------------------------------------------------
;Registro TRISA= 00h para salidas.
bsf STATUS,RP0; banco1
movlw 00h;
movwf TRISA; puertoA como salida
bcf STATUS,RP0; banco0
;PuertoA apagado
movlw 00h
movwf PORTA
;------------------------------------------------------
;Configurar el contador TMR0
;------------------------------------------------------
;TMR0 = contador descendente cargado con el dato ffh.
;Registro OPTION_REG
;Contador= bit5=T0CS= 1= pulsos exteriores.
;Descentente= bit4=T0SE= 1
bsf STATUS,RP0; banco1
bsf OPTION_REG,T0SE
bsf OPTION_REG,T0CS
bcf STATUS,RP0; banco0
;Cargar el TMR0 con ffh.
movlw 0ffh
movwf TMR0; cargo TMR0 con el dato ffh
; para que desborde con un pulso del pulsador conectado a la
; entrada T0cki.
;---------------------------------------------
;Preparar interrupciones.
;---------------------------------------------
;Habilitar permiso de interrupción global.
bsf INTCON,GIE
;Habilitar permiso int. particular del TMR0.
bsf INTCON,T0IE
;Espera hasta rebosar el TMR0.
espera
btfss INTCON,T0IF; salta si es 1. Al pulsar hago
; que el contador se desborde al pasar de ffh a 00h. La bandera se
; pone a 1 y salto a la interrupción y luego al programa principal.
; El puerto A se encenderá y apagará en un bucle indefinido.
goto espera
;-----------------------------------
;PROGRAMA PRINCIPAL
;-----------------------------------
programa
movlw 00h
movwf PORTA; apago el puertoA
call sg1
movlw 0ffh; enciendo el puertoA
movwf PORTA
call sg1
goto programa
;-------------------------------------------
;INTERRUPCION DEL TMR0
;-------------------------------------------
int
;Deshabiltar permiso de int. global
bcf INTCON,GIE
;Deshabilitar permiso de int. del contador
bcf INTCON,T0IE
;Poner a cero el flag
bcf INTCON,T0IF
retfie; retorno subrutina de interrupción.
;------------------------------------------------------------------
;Retardos.
;------------------------------------------------------------------
;c1h=193 goto=2 useg. decfsz=1 useg.( skip if 0 ).
;(193 x 2) + 193 = 579 useg
;(579 x 579) = 335241 useg.
;(335241 x 3) = 1005723 useg.
;0ch, 0dh y 0eh registros RAM del GPR
;----------------------------------------------------
sg1; 1005723 useg.
movlw 0c1h
movwf 0ch
movwf 0dh
movlw 01h
movwf 0eh
salto1
decfsz 0ch,1
goto salto1
decfsz 0dh,1
goto salto1
decfsz 0eh,1
goto salto1
return
;-------------------------
sg500; 497025 useg.
movlw 0e6h; e6h= 235
movwf 0ch
movwf 0dh
salto2
decfsz 0ch,1
goto salto2
decfsz 0dh,1
goto salto2
return
;--------------------------
sg250; 251001 useg.
movlw 0a7h; a7h= 167
movwf 0ch
movwf 0dh
salto3
decfsz 0ch,1
goto salto3
decfsz 0dh,1
goto salto3
return
;------------------------------------------------
sg125; 125316 useg.
movlw 76h; 76h= 118
movwf 0ch
movwf 0dh
salto4
decfsz 0ch,1
goto salto4
decfsz 0dh,1
goto salto4
return
end
PRÁCTICA Nº 5
Microcontrolador PIC16F84A
Objetivo: Encender y apagar cada segundo un led conectado al puerto RA2. Se usará el timer0 para hacer la
temporización.
Esquema eléctrico:
Programa:
;-----------------------------------------------
;PROGRAMA TIMER0.ASM
;Temporizador con el timer0
;haciendo on-off un led seg. alternos.
;-----------------------------------------------
list p=16F84A
include "p16F84A.inc"
;------------------
;RESET
;------------------
org 00h
reset
goto inicio
;---------------------------
INTERRUPCIONES
;---------------------------
org 04h
goto int
;-------------------------------
;Comienzo del programa
;-------------------------------
org 10h
inicio
;-----------------------------------------------
;Configurar el puertoA como entrada
;excepto el PA2 que será salida.
;-----------------------------------------------
;1= entradas, 0= salidas
;PA3,4= 1; PA2= 0; PA1,0= 1
;Registro TRISA= ---1 1011b= 1bh
;apagar led
;------------------------------------------
;Configurar el TMR0 (contador).
;------------------------------------------
;--------------------------------------
;Configurar las interrupciones
;--------------------------------------
;--------------------------------------
;Configurar registros generales.
;--------------------------------------
;--------------------------------------
;Programa principal
;--------------------------------------
programa
;---------------------------------------------
;Subrutina de temporizar 1 segundo.
;---------------------------------------------
;Frecuencia del cristal es 4Mhz.
;La señal de entrada al TMR0 es fosc./4, o sea, 1Mhz (T= 1 useg.).
;El divisor de frecuencia divide por 256, con lo que la señal de 1 Mhz se
;transforma en una de 3906,25 Hz (T= 0,256 mseg.)
;1seg= 1000 mseg.
;0,256 mseg x 3900= 998,4 mseg
;El TMR0 va a contar desde 216 a 255 que son 39 impulsos de 0,256 mseg.
;y esto lo va hacer 100 veces, o sea, las 3900 veces que necesito.
cuenta1
bsf INTCON,T0IE; activo int. timer0.
bcf INTCON,T0IF; poner a cero el flag del timer0.
movlw 0d8h; d8h= 216 decimal
movwf TMR0; 255 - 216 = 39.
cuenta
;---------------------------------------
;Tratamiento de la interrupción.
;---------------------------------------
int
bcf INTCON,T0IE; desactivación de la int. del timer0.
bcf INTCON,T0IF; borro el flag
retfie; retorno subrutina interrupción.
end
PRACTICA Nº6
Construcción de una alarma compuesta de dos sensores y un elemento sonoro, un buzzer
Objetivo de la práctica:
1º: Usar las instrucciones de manejo de bits:
1º: Dos sensores de detección, que serán simulados con los pulsadores.
2º: El PIC que ejecutará el programa de funcionamiento de la alarma con las siguientes directrices:
a: Una vez conectada la alimentación nos debe dar tiempo suficiente a abandonar el local, 1 minuto de retardo.
b: Comprobar cuatro veces que los detectores están activos a intervalos de un cuarto de minuto.
c: Una vez activada totalmente hacer sonar una señal sonora durante dos minutos.
3º: Esta señal sonora será producida por una chicharra (buzzer).
Descripción de las funciones de los pines del puerto B para configurarlo para la alarma.
Consiste en descargar una red RC a través del pulsador y la resistencia de 47 ohmios. Al conectar la
alimentación el condensador de 100 nF se carga a través de la resistencia de 10K ohmios.
En las entradas de los circuitos disparadores (pines 1-2 o 8-9) atendremos +5voltios con lo que a las salidas
(pines 3 y 10) del circuito disparador habrá cero voltios.
Si le conectásemos otro circuito (entradas pines 5-6 y 12-13) disparador a las salidas anteriores invertiríamos
esos cero voltios a cinco voltios en las salidas, pines 4 y 11.
El diodo conectado en paralelo con la resistencia de 10k sirve para descargar el condensador cuando se
desconecte la fuente de alimentación y así no dañar al PIC.
Usamos como inversores las puertas NAND de dos entradas aunque valdría cualquier otro inversor, pero eso sí,
con entradas de disparador ya que sino ante cualquier rebote de los pulsadores, ruido o interferencia que
llegase a las entradas no conseguiríamos un solo pulso sino varios pulsos al activar el pulsador.
Descripción de los pasos a seguir para hacer el programa:
1º. Pondremos a uno los bit 0 y 1 del TRISB para hacer dos entradas en el puerto B. Pondremos a cero los bit 7
del TRISB para hacer una salida en el puerto B.
2º. Con las instrucciones de salto condicional de bits detectaremos como están las entradas y se actuará sobre
la alarma sonora.
Programa :
;-----------------------------------------------------------------------
;SEXTO PROGRAMA:
;Alarma con dos sensores y señal sonora.
;-----------------------------------------------------------------------
;PIC 16F84A/ 4 MHz/
;Bits de configuración para el programador:
;CP(protección de la memoria de código):....................No
;PWRTE(activación del temporizador "Power-up"):....No
;WDTE(activación del "perro guardián"):.....................No
;FOSC1-FOSC0(tipo de oscilador):...............................Xtal
;-------------------------------------------------------------------------
;PROGRAMA
LIST p=16f84A
INCLUDE "p16f84A.inc"
ORG 00h
goto inicio
inicio
ORG 10h
call banco1
bsf TRISB,0
bsf TRISB,1
bcf TRISB,7
call banco0
programa
call buzzer2 ; Subrutina para hacer sonar dos veces el buzzer
call sg60 ; retardo de 60 segundos.
programa1
movlw 04h ; muevo el nº 04h al W.
movwf 11h ; muevo W al registro 11h
call buzzer1 ; subrutina de hacer sonar el buzzer una vez
comprueba1
btfsc PORTB,0 ; compruebo si el sensor 0 está activo o no
goto cuatro1 ; salto incondicional a la etiqueta “cuatro1” para
;comprobar 4 veces si está activado el sensor 0 conectado a RB0
cuatro1
call buzzer1 ;suena una vez el buzzer
call sg15 ; retardo de 15 segundos
decfsz 11h,1 ; decrementa el registro 11h y si vale cero salta
goto comprueba1 ; salto incondicional
call buzzer120 ; suena el buzzer durante 120 segundos
goto programa1 ; salto incondicional
cuatro2
call buzzer1
call sg15
decfsz 11h,1
goto comprueba2
call buzzer120
goto programa1
;----------------------------------------------
;Subrutinas de cambios de bancos.
;----------------------------------------------
banco0
bcf STATUS,RP0
return
banco1
bsf STATUS,RP0
return
;---------------------------------------------
;Subrutinas de el buzzer (buzzer)
;---------------------------------------------
buzzer1
bsf PORTB,7
call sg1
bcf PORTB,7
return
buzzer2
bsf PORTB,7
call sg1
bcf PORTB,7
call sg1
bsf PORTB,7
call sg1
bcf PORTB,7
return
buzzer120
bsf PORTB,7
call sg60
call sg60
bcf PORTB,7
return
;---------------------------------
;Subrutinas de retardos.
;---------------------------------
sg1
call banco0
movlw 0ffh
movwf 0ch
movlw 0ffh
movwf 0dh
movlw 05h
movwf 0eh
repite
decfsz 0ch,1
goto repite
decfsz 0dh,1
goto repite
decfsz 0eh,1
goto repite
return
;Retardo de 15 segundos.
;Decrementaremos un registro, 0fh, cargado
;con el nº 0fh (15) hasta llegar a cero.
sg15
movlw 0fh
movwf 0fh
otra
call sg1
decfsz 0fh,1
goto otra
return
sg60
movlw 0c3h
movwf 10h
otravez
call sg1
incfsz 10h,1
goto otravez
return
END
PRÁCTICA Nº 7
Proyecto: Regulador lumínico mediante el control de la fase.
Al pasar esta corriente eléctrica por la lámpara haremos que se ilumine al 100 %. Si nos las ingeniamos para
que la señal aplicada a la lámpara se recorte como se ve en la figura siguiente, obtendremos valores de
iluminación entre un 0% y un 100%.
ORG 00h
goto inicio
inicio
ORG 10h
;Configurar la INT.
call banco1
bcf OPTION_REG,INTEDG ;flanco de bajada de la INT
call banco0
programa
movlw 00h
movwf 20h
progra1
btfss INTCON,INTF
goto progra1
bcf INTCON,INTF
call varia
call disparo
call up
call down
goto progra1
;--------------------------------------------------
;Subrutinas de los botones UP-DOWN.
;---------------------------------------------------
up
btfss PORTB,2 ;testeo el puerto RB2 y si vale uno salto
goto saltu1
incf 20h,1 ;incremento el registro 20h
bcf STATUS,C ;corrección para no llegar a FFh, solo llego hasta F1h
movlw 0fh
addwf 20h,0
btfss STATUS,C
goto saltu1
movlw 0f1h
movwf 20h
saltu1
return
down
btfss PORTB,3 ;testeo el puerto RB3 y si vale uno salto
goto saltu3
decf 20h,1 ;decremento el registro 20h
bcf STATUS,C ;corrección para no llegar a 00h, sólo llego hasta 0Fh
movlw 0f1h
addwf 20h,0
btfss STATUS,C
goto saltu2
return
saltu2
movlw 0fh
movwf 20h
saltu3
return
;------------------------------------
;Disparo del triac: 225 useg.
;------------------------------------
;Pulso de disparo de 225 microsegundos necesarios para activar el triac
disparo
bsf PORTB,4
call usg225
bcf PORTB,4
return
usg225
movlw 4bh
movwf 30h
sal4
decfsz 30h,1
goto sal4
return
;-----------------------------------------------
;Retardo variable después de la INT.
;-----------------------------------------------
;El tiempo entre que se activa la bandera INTF es de 10mseg (10.000 microsegundos)
;Si un registro (21h) lo cargo con un valor comprendido entre 01h y FFh y lo voy
;decrementando hasta llegar a cero con un retardo fijo de unos 25 microsegundos entre medias
;puedo conseguir unos pocos microsegundos o los 10.000 microsegundos.
varia
movf 20h,0
movwf 21h
salte
call usg25
decfsz 21h,1
goto salte
return
usg25
movlw 08h
movwf 31h
sal5
decfsz 31h,1
goto sal5
return
;------------------------------------------
;Subrutinas de cambios de bancos.
;------------------------------------------
banco0
bcf STATUS,RP0
return
banco1
bsf STATUS,RP0
return
END
PRÁCTICA Nº 8
La instrucción RETLW.
ORG 00h
goto inicio
ORG 10h
tabla
movf TMR0,0
andlw 0fh
addwf PCL,1
retlw 3fh
retlw 06h
retlw 5bh
retlw 4fh
retlw 66h
retlw 6dh
retlw 7dh
retlw 07h
retlw 7fh
retlw 67h
retlw 77h
retlw 7ch
retlw 39h
retlw 5eh
retlw 79h
retlw 71h
inicio
;Configurar el TMR0.
call banco1
bsf OPTION_REG,T0SE
bsf OPTION_REG,T0CS
call banco0
clrf TMR0
programa
call tabla
movwf PORTB
goto programa
;------------------------------------------
;Subrutinas de cambios de bancos.
;------------------------------------------
banco0
bcf STATUS,RP0
return
banco1
bsf STATUS,RP0
return
END
PRÁCTICA Nº 9
Conexión de una pantalla LCD de 1 línea y 16 caracteres.
Descripción del lugar que ocupa cada carácter en la pantalla y la dirección de la posición de memoria en la LCD.
Descripción del carácter colocado y la dirección que ocupa en la memoria de la LCD.
CODIGO Tiempo
Instrucción. Descripción de
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 ejecución
Borra la
pantalla y
retorna el
Borrar Pantalla 0 0 0 0 0 0 0 0 0 1 1.64 mS.
cursor a la
dirección 0 (
Home )
Retorna el
cursor al
Cursor Home 0 0 0 0 0 0 0 0 1 * 1.64 mS.
inicio (
Dirección o)
Donde
I/D=0
Decremente
la posición
del cursor,
I/D=1
incrementa
Modo de
la posición
entrada de 0 0 0 0 0 0 0 1 I/D S 40 uS.
del cursor,.
caracteres
S=0 El texto
de la
pantalla no
se desplaza,
S=1 El texto
de la
pantalla se
desplaza en
el momento
que se
escribe un
carácter
Donde D=0
Pantalla
apagada,
D=1 Pantalla
encendida,
C=0 Cursor
apagado,
Apagado y C=1 Cursor
encendido de 0 0 0 0 0 0 1 D C B encendido, 40 uS..
la pantalla. B=0
Intermitencia
del cursor
apagado,
B=1
Intermitencia
del cursor
encendido.
Desplazamiento
0 0 0 0 0 1 S/C R/L * * 40 uS.
cursor y display
Funtion Set 0 0 0 0 1 DL N F * * 40 uS.
Dirección
0 0 0 1 ACG 40 uS.
CG RAM
Dirección
0 0 1 ADD 40 uS.
DD RAM
Leer busy flag
y 0 1 BF AC 1 uS.
dirección
Escribir dato en
1 0 Escribir el Dato 40 uS.
CG o DD RAM
Leer dato en
1 1 Leer el Dato 40 uS.
CG or DD RAM
NOMENCLATURAS
Nomenclatura Valor = 1 Valor = 0
I/D=1 Incrementa el Cursor I/D=0 Decrementa el Cursor en
I/D
en una posición una posición.
D D=1 Pantalla Encendida D=0 Pantalla Apagada.
C C=1 Cursor Encendido. C=0 Cursor Apagado.
B=1 Intermitencia del cursor B=0 Intermitencia del cursor
B
encendida. apagado
S/C S/C=1 Mover todo el texto. S/C=0 Mover el cursor.
R/L=1 Mover todo el texto a R/L=1 Mover todo el texto a la
R/L
la izquierda. derecha.
DL DL=1 Bus de datos de 8 Bits. DL=0 Bus de datos de 4 Bits.
S=1 Desplazamiento del S=0 No desplazamiento del
S
texto. texto
BF=1 Operación Interna en BF=0 No puede aceptar
BF
progreso. instrucción
F=1 Matriz para el carácter F=0 Matriz del carácter de 5 x 7
F
de 5 X 10 dots Dost
N N=1 Activación de dos lineas. N=0 Activación de 1 linea
INSTRUCCIÓN Hexadecimal
Función set (DL=1, 8-bit interface; N=0, 1 line; F=0, 5*7 Pixels) 30
Modo entrada (I/D=1; S=0) 06
Display ON-OFF (Control: D=0; C=0; B=0) Display apagado 08
Cursor Home 02
Desplazamiento cursor y display ( S/C=0; R/L=1,derecha) 14
Borrar pantalla 01
;------------------------------------------------------------------------------
;PROGRAMA COMPROBADO:
;Manejo de una LCD.
;Escribir el mensaje: PIC 16F84A, v.00
;------------------------------------------------------------------------------
;PIC 16F84A/ 4 MHz/
;Bits de configuración para el programador:
;CP(protección de la memoria de código):..............................No
;PWRTE(activación del temporizador "Power-up"):..............No
;WDTE(activación del "perro guardián"):...............................No
;FOSC1-FOSC0(tipo de oscilador):........................................Xtal
;------------------------------------------------------------------------------
;PROGRAMA
LIST p=16f84A
INCLUDE "p16f84A.inc"
ORG 00h
goto inicio
ORG 10h
inicio
;Configurar los puertos A y B.
call pabconfig
;Configuración inicial de la LCD.
call lconfigI
;Configuración de trabajo de la LCD.
call lconfigW
programa
call lcdPIC
progra
goto progra
;----------------------------------------
;Subrutina para poner un texto.
;---------------------------------------
;P I C _ 1 6 F 8 4 A , _ v . 0 0
lcdPIC
call pabconfig; subrutina de configurar Puerto A y B para la LCD.
call lclear; borrar pantalla
call lhome; dirección 00h de la pantalla
;-------------------------------------------
;-------------------------------------------
;Subrutinas de la pantalla LCD.
;-------------------------------------------
;--------------------------------------
;Subrutina de configuración del puerto A y B.
;-------------------------------------
pabconfig
call pacontrol
call pbbusO
return
;---------------------------------------------
;Subrutina de configuración inicial de la pantalla LCD.
;---------------------------------------------
lconfigI
call mseg20
call l8xx
call mseg6
call l8xx
call useg150
call l8xx
call l817
call ldisplay0xx
call lclear
call lmode10
return
;-------------------------------------------
;Subrutina de configuración de la
;LCD para comenzar a trabajar.
;-------------------------------------------
lconfigW
call ldisplay10x
call lcursorder
return
;-----------------------------------------------------
;Puerto A 3,4= entradas, 0,1 y 2 = salidas
;y las pongo a cero.
;-----------------------------------------------------
pacontrol
call banco1
bcf TRISA,0
bcf TRISA,1
bcf TRISA,2
call banco0
bcf PORTA,0
bcf PORTA,1
bcf PORTA,2
return
;------------------------------
;Puerto B= salidas y las pongo a cero.
;------------------------------
pbbusO
call banco1
movlw 00h
movwf TRISB
call banco0
movlw 00h
movwf PORTB
return
;----------------------------------------------------
;Puerto B y RA2,1 = entradas y la RA0 se queda como salida a cero para inhabilitar la LCD.
;---------------------------------------------------
pabI0O
call banco1
movlw 0ffh
movwf TRISB
bsf TRISA,1
bsf TRISA,2
call banco0
return
;----------------------------------------
;Pulso de habilitación del LCD.
;----------------------------------------
;Flanco de subida
lE1
nop
bcf PORTA,0
nop
bsf PORTA,0
return
;Flanco de bajada
lE2
nop
bcf PORTA,0
nop
return
;------------------
;Escribir dato.
;------------------
lwd
bsf PORTA,2
bcf PORTA,1
call lE1
return
;---------------------------
;Escribir instrucción.
;--------------------------
lwi
bcf PORTA,2
bcf PORTA,1
call lE1
return
;-----------------------------
;Escribir instrucciones.
;-----------------------------
;De 20h a puerto B.
;----------------------------
w20pb
movf 20h,0
movwf PORTB
return
;--------------------------------------------------
;Escribir instrucción de "No operación".
;--------------------------------------------------
lnop
movlw 00h
call winst
return
winst
movwf 20h
call lwi
call w20pb
call lE2
call useg45
return
;----------------------------------------------------
;Escribir inst. de limpiar display y
;poner a cero el contador de direcciones.
;----------------------------------------------------
lclear
movlw 01h
call winstt
return
winstt
movwf 20h
call lwi
call w20pb
call lE2
call mseg2
return
;---------------------------------------
;Escribir inst. de cursor a casa.
;--------------------------------------
lhome
movlw 02h
call winstt
return
;------------------------------------------
;Escribir inst. de modo de entrada.
;------------------------------------------
;-----------------------------------------------------------------
;El cursor se mueve incremental (I/D= 1)
;y el display no se desplaza automáticamente (S= 0).
;-----------------------------------------------------------------
lmode10
movlw 06h
call winst
return
;------------------------------------------------
;Escribir inst. del control del display.
;------------------------------------------------
;------------------------------------------------------
;Display on, D= 1; Cursor off, C= 0; B= x.
;------------------------------------------------------
ldisplay10x
movlw 0ch
call winst
return
;-----------------------------------------
;Display off, D= 0; C= x; B= x.
;-----------------------------------------
ldisplay0xx
movlw 08h
call winst
return
;----------------------------------------------------
;Desplazar display o mover cursor (S/C) y
;especificar dirección (R/L).
;----------------------------------------------------
;---------------------------------------------------
;Desplazar display y no cursor (S/C=1) a
;la derecha (R/L=1).
;---------------------------------------------------
ldisplayder
movlw 1ch
call winst
return
;------------------------------------------------
;Mover cursor y no display (S/C=0) a
;la derecha (R/L=1).
;------------------------------------------------
lcursorder
movlw 14h
call winst
return
;---------------------------------------------------------------
;Función Set.
;Configurar la pantalla: bus de 4 o 8 bits (DL),
;1 o 2 líneas (N) y nº de puntos (5x10 o 5x7) (F).
;---------------------------------------------------------------
l8xx
call lwi
movlw 30h
movwf 20h
call w20pb
call lE2
call useg45
return
l817
movlw 30h
call winst
return
;--------------------------------------------------
;Subrutina para colocar datos seguidos
;-------------------------------------------------
wdato
movwf 20h
call lwd
call w20pb
call lE2
call useg45
return
;----------------------------------------------------
;Subrutina para colocar datos en cualquier
;posición de la pantalla: DDRAM dirección.
;----------------------------------------------------
wdir
addlw 80h
movwf 20h
call lwi
call w20pb
call lE2
call useg45
return
;------------------------------
;Retardos para la LCD.
;------------------------------
;---------------------------
;Retardo de 2 mseg.
;--------------------------
mseg2
call banco0
movlw 0ffh
movwf 30h
movlw 03h
movwf 31h
salto5s
decfsz 30h,1
goto salto5s
decfsz 31h,1
goto salto5s
return
;--------------------------
;Retardo de 6 mseg.
;--------------------------
mseg6
call banco0
movlw 0ffh
movwf 30h
movlw 08h
movwf 31h
salto41s
decfsz 30h,1
goto salto41s
decfsz 31h,1
goto salto41s
return
;---------------------------
;Retardo de 20 mseg.
;---------------------------
mseg20
call banco0
movlw 0ffh
movwf 30h
movlw 1ah
movwf 31h
salto4s
decfsz 30h,1
goto salto4s
decfsz 31h,1
goto salto4s
return
;---------------------------
;Retardo de 45 useg.
;---------------------------
useg45
call banco0
movlw 0fh
movwf 30h
salto6s
decfsz 30h,1
goto salto6s
return
;------------------------------
;Retardo de 150 useg.
;------------------------------
useg150
call banco0
movlw 32h
movwf 30h
salto61s
decfsz 30h,1
goto salto61s
return
;------------------------------------------
;Subrutinas de cambios de bancos.
;------------------------------------------
banco0
bcf STATUS,RP0
return
banco1
bsf STATUS,RP0
return
END
PRÁCTICA nº 10
Conexión de un teclado.
Teclado estático: formado por dos decodificadores decimales. Al unir los dos decodificadores con unas puertas
OR y añadirles un buffer tres estados obtenemos un dispositivo capacitado para ser conectado al puerto B y que
no tendrá problemas de choque de buses al ser controlado por un pin específico del PIC, habilitar del teclado sin
cortocircuitarse con el bus de una LCD conectada al puerto B, por ejemplo.
Buffer tres estados, 74HC245. El terminal RA3 controlará la salida de datos al bus de datos que también es
usado por la LCD.
Poniendo RA3 a cero los datos saldrán hacia el puerto B del PIC. Hemos construido un teclado hexadecimal ( 00
a 0fh). Hemos necesitado cuatro integrados CMOS, unas cuantas resistencias y pulsadores sueltos; si queremos
disminuir el número de integrados, de conexiones de pulsadores y de componentes, etc, hay un integrado
llamado 74C922 que nos facilita las conexiones. También podemos usar un teclado ya encapsulado.
El teclado encapsulado usado tiene las siguientes conexiones y dibujado los números así:
Si observamos los números de las teclas en el dibujo del integrado y los números del teclado, vemos que no
coinciden, por lo tanto en el software habrá que hacer corresponder los números de las teclas del 74C922 con
las del teclado.
Vamos haber que transformaciones hay que hacer para poder ver en la pantalla LCD la tecla que pulses.
Usaremos la instrucción RETLW para hacer una correspondencia entre esas combinaciones y las necesarias para
ser visualizadas en la pantalla LCD y correspondan a las dibujadas en el teclado encapsulado. Las combinaciones
de correspondencia son:
En ASCII el 30h es nuestro 0 decimal, el 39h es el 9, 3ch es < y 3eh es >. En la práctica anterior visualizamos
un mensaje:
TECLA PULSADA
;------------------------------------------------------------------------------
;PROGRAMA COMPROBADO:
;Manejo de un teclado (74C922) y una LCD.
;Escribir un mensaje y ver la tecla que pulso en el teclado.
;------------------------------------------------------------------------------
;PIC 16F84A/ 4 MHz/
;Bits de configuración para el programador:
;CP(protección de la memoria de código):..............................No
;PWRTE(activación del temporizador "Power-up"):..............No
;WDTE(activación del "perro guardián"):...............................No
;FOSC1-FOSC0(tipo de oscilador):........................................Xtal
;------------------------------------------------------------------------------
;PROGRAMA
LIST p=16f84A
INCLUDE "p16f84A.inc"
ORG 00h
goto inicio
ORG 10h
inicio
;Configurar los puertos A y B.
call pa3saluno; desactivo el teclado, RA3=1
call pabconfig
;Configuración inicial de la LCD.
call lconfigI
;Configuración de trabajo de la LCD.
call lconfigW
programa
call lcdPIC
progra
call pa3cero; activo el teclado con RA3=0 y hago PB entradas
call binasc; convierto el código binario en ASCII
movwf 40h; cargo 40h con W
call vertecla; veo la tecla pulsada
call pa3saluno; desactivo el teclado, RA3=1
goto progra
;--------------------------------------
;Leer el Puerto B: RB0,RB1,RB2 y RB3.
;y transformarlo en ASCII.
; 0-31, 1-32, 2-33
; 4-34, 5-35, 6-36
; 8-37, 9-38, A-39
; C-3c, D-30, E-3e
; En las combinaciones 3,7,B y F
; pondré el símbolo ffh.
;--------------------------------------
binasc
movf PORTB,0; leo el puerto PB y lo llevo a W
andlw 0fh; pongo a cero los bits altos y lo dejo en el W
addwf PCL,1; sumo al contador de programa bajo lo que tenía el acumulador
retlw 31h; regreso de subrutina con el W cargado con ASCII.
retlw 32h
retlw 33h
retlw 0ffh
retlw 34h
retlw 35h
retlw 36h
retlw 0ffh
retlw 37h
retlw 38h
retlw 39h
retlw 0ffh
retlw 3ch
retlw 30h
retlw 3eh
retlw 0ffh
;-----------------------------------
;Subrutina de ver la tecla pulsada.
;-----------------------------------
vertecla
call pabconfig; subrutina de configurar Puerto A y B para la LCD.
movlw 0fh; dirección de visión de la tecla pulsada
call wdir; carga dirección 0fh en la pantalla
movf 40h,0; cargo el dato en ASCII presente en 40h en W
call wdato; escribir el símbolo en la pantalla (dirección 0fh)
call pabI0O; subrutina de hacer los pines entradas excepto
;RA0= E (habilitación de la pantalla)= 0, deshabilitada.
return
;----------------------------------------
;Subrutina para poner un texto.
;---------------------------------------
;P I C _ 1 6 F 8 4 A , _ v . 0 0
lcdPIC
call pabconfig; subrutina de configurar Puerto A y B para la LCD.
call lclear; borrar pantalla
call lhome; dirección 00h de la pantalla
;-------------------------------------------
;-------------------------------------------
;Subrutinas de la pantalla LCD.
;-------------------------------------------
;--------------------------------------
;Subrutina de configuración del puerto A y B.
;-------------------------------------
pabconfig
call pacontrol
call pbbusO
return
;---------------------------------------------
;Subrutina de configuración inicial
;de la pantalla lCD.
;---------------------------------------------
lconfigI
call mseg20
call l8xx
call mseg6
call l8xx
call useg150
call l8xx
call l817
call ldisplay0xx
call lclear
call lmode10
return
;-------------------------------------------
;Subrutina de configuración de la
;LCD para comenzar a trabajar.
;-------------------------------------------
lconfigW
call ldisplay10x
call lcursorder
return
;-----------------------------------------------------
;Puerto A 3,4= entradas, 0,1 y 2 = salidas
;y las pongo a cero.
;-----------------------------------------------------
pacontrol
call banco1
bcf TRISA,0
bcf TRISA,1
bcf TRISA,2
call banco0
bcf PORTA,0
bcf PORTA,1
bcf PORTA,2
return
;---------------------------
;PA3 como salida y a uno:
;inhabilito teclado
;---------------------------
pa3saluno
call banco1
bcf TRISA,3
call banco0
bsf PORTA,3
return
;--------------------------------
;PA3 a cero: activo teclado
;y PB entrada.
;--------------------------------
pa3cero
call banco1
movlw 0ffh
movwf TRISB
call banco0
bcf PORTA,3
return
;------------------------------
;Puerto B= salidas
;y las pongo a cero.
;------------------------------
pbbusO
call banco1
movlw 00h
movwf TRISB
call banco0
movlw 00h
movwf PORTB
return
;----------------------------------------------------
;Puerto B y RA2,1 = entradas y
;la RA0 se queda como salida a cero para
;inhabilitar la LCD.
;---------------------------------------------------
pabI0O
call banco1
movlw 0ffh
movwf TRISB
bsf TRISA,1
bsf TRISA,2
call banco0
return
;----------------------------------------
;Pulso de habilitación del LCD.
;----------------------------------------
;Flanco de subida
lE1
nop
bcf PORTA,0
nop
bsf PORTA,0
return
;Flanco de bajada
lE2
nop
bcf PORTA,0
nop
return
;------------------
;Escribir dato.
;------------------
lwd
bsf PORTA,2
bcf PORTA,1
call lE1
return
;---------------------------
;Escribir instrucción.
;--------------------------
lwi
bcf PORTA,2
bcf PORTA,1
call lE1
return
;-----------------------------
;Escribir instrucciones. De 20h a puerto B.
;----------------------------
w20pb
movf 20h,0
movwf PORTB
return
;--------------------------------------------------
;Escribir instrucción de "No operación".
;--------------------------------------------------
lnop
movlw 00h
call winst
return
winst
movwf 20h
call lwi
call w20pb
call lE2
call useg45
return
;----------------------------------------------------
;Escribir inst. de limpiar display y poner a cero el contador de direcciones.
;----------------------------------------------------
lclear
movlw 01h
call winstt
return
winstt
movwf 20h
call lwi
call w20pb
call lE2
call mseg2
return
;---------------------------------------
;Escribir inst. de cursor a casa.
;--------------------------------------
lhome
movlw 02h
call winstt
return
;------------------------------------------
;Escribir inst. de modo de entrada.
;------------------------------------------
;-----------------------------------------------------------------
;El cursor se mueve incremental (I/D= 1) y el display no se desplaza automáticamente (S= 0).
;-----------------------------------------------------------------
lmode10
movlw 06h
call winst
return
;------------------------------------------------
;Escribir inst. del control del display.
;------------------------------------------------
;------------------------------------------------------
;Display on, D= 1; Cursor off, C= 0; B= x.
;------------------------------------------------------
ldisplay10x
movlw 0ch
call winst
return
;-----------------------------------------
;Display off, D= 0; C= x; B= x.
;-----------------------------------------
ldisplay0xx
movlw 08h
call winst
return
;----------------------------------------------------
;Desplazar display o mover cursor (S/C) y especificar dirección (R/L).
;----------------------------------------------------
;---------------------------------------------------
;Desplazar display y no cursor (S/C=1) a la derecha (R/L=1).
;---------------------------------------------------
ldisplayder
movlw 1ch
call winst
return
;------------------------------------------------
;Mover cursor y no dispaly (S/C=0) a la derecha (R/L=1).
;------------------------------------------------
lcursorder
movlw 14h
call winst
return
;---------------------------------------------------------------
;Función Set.
;Configurar la pantalla: bus de 4 o 8 bits (DL),
;1 o 2 líneas (N) y nº de puntos (5x10 o 5x7) (F).
;---------------------------------------------------------------
l8xx
call lwi
movlw 30h
movwf 20h
call w20pb
call lE2
call useg45
return
l817
movlw 30h
call winst
return
;--------------------------------------------------
;Subrutina para colocar datos seguidos
;-------------------------------------------------
wdato
movwf 20h
call lwd
call w20pb
call lE2
call useg45
return
;----------------------------------------------------
;Subrutina para colocar datos en cualquier
;posición de la pantalla: DDRAM address.
;----------------------------------------------------
wdir
addlw 80h
movwf 20h
call lwi
call w20pb
call lE2
call useg45
return
;------------------------------
;Retardos para la LCD.
;------------------------------
;---------------------------
;Retardo de 2 mseg.
;--------------------------
mseg2
call banco0
movlw 0ffh
movwf 30h
movlw 03h
movwf 31h
salto5s
decfsz 30h,1
goto salto5s
decfsz 31h,1
goto salto5s
return
;--------------------------
;Retardo de 6 mseg.
;--------------------------
mseg6
call banco0
movlw 0ffh
movwf 30h
movlw 08h
movwf 31h
salto41s
decfsz 30h,1
goto salto41s
decfsz 31h,1
goto salto41s
return
;---------------------------
;Retardo de 20 mseg.
;---------------------------
mseg20
call banco0
movlw 0ffh
movwf 30h
movlw 1ah
movwf 31h
salto4s
decfsz 30h,1
goto salto4s
decfsz 31h,1
goto salto4s
return
;---------------------------
;Retardo de 45 useg.
;---------------------------
useg45
call banco0
movlw 0fh
movwf 30h
salto6s
decfsz 30h,1
goto salto6s
return
;------------------------------
;Retardo de 150 useg.
;------------------------------
useg150
call banco0
movlw 32h
movwf 30h
salto61s
decfsz 30h,1
goto salto61s
return
;--------------------
;Retardo de 1 seg.
;--------------------
sg1
call banco0
movlw 0c2h
movwf 10h
movwf 11h
movlw 04h
movwf 12h
sal1
decfsz 10h,1
goto sal1
goto recarga1
sal2
decfsz 11h,1
goto sal1
goto recarga2
sal3
decfsz 12h,1
goto sal1
return
recarga1
movlw 0c2h
movwf 10h
goto sal2
recarga2
movlw 0c2h
movwf 11h
goto sal3
;------------------
;Retardo de 5 seg.
;------------------
sg5
call sg1
call sg1
call sg1
call sg1
call sg1
return
;------------------------------------------
;Subrutinas de cambios de bancos.
;------------------------------------------
banco0
bcf STATUS,RP0
return
banco1
bsf STATUS,RP0
return
END
PRÁCTICA nº 11
Hacer funcionar en ambos sentidos un motor paso a paso unipolar mediante dos pulsadores.
Dispone de cuatro bobinas puenteadas, o puenteadas dos a dos (puentealas tú) o ninguna puenteada (
puentealas las cuatro). El problema es saber la secuencia de activación del motor. O buscas el motor en la red o
lo haces experimentando.
Experimentando:
1. Leer la tensión y ohmios en el motor para saber la intensidad que consume, aplica la ley de Ohm.
2. Para un experimento inicial busca un motor con bastantes ohmios, cientos de ohmios. Usa tensiones
entre 5 y 12 voltios, si no pone tensión en el motor.
3. En las impresoras de inyección los puedes encontrar.
4. Simplemente dando tensión manualmente averigua la secuencia hacia la derecha y por tanto, hacia la
izquierda.
5. Elegir un integrado o transistores que conmuten bien las bobinas y poner diodos de recirculación a cada
bobina.
El motor que usaré es de un impresora de tinta con las características siguientes:
MARCA: NMB PM42S-048-ML06 (MINEBEA).
No pone voltaje, ohmios ni corriente. Búscalo en la red o experimenta.Dispone en su conector una disposición
bastante aclaratoria:
Midiendo entre rojo y marrón o negro, da unos 90 ohmios. Igual entre rojo y naranja o amarillo.
1 + +
2 + +
3 + +
4 + +
8 4 2 1
Los valores hexadecimales a sacar por el puerto B, haciendo los bits altos igual a cero:
1 0Ah
2 09h
3 05h
4 06h
El buffer ULN 2803 invierte por lo tanto los valores serán: F5h, F6h, FAh y F9h. Sólo nos queda elegir un
integrado que disipe esa corriente que consume el motor. Elijo el ULN 2803, capaz de aguantar cada transistor
en colector abierto hasta 500 mA
; ;------------------------------------------------------------------------------
;PROGRAMA COMPROBADO:
;Manejo de un motor paso a paso unipolar.
;Según pulsador, giro a derechas o a izquierdas.
;------------------------------------------------------------------------------
;PIC 16F84A/ 4 MHz/
;Bits de configuración para el programador:
;CP(protección de la memoria de código):..............................No
;PWRTE(activación del temporizador "Power-up"):..............No
;WDTE(activación del "perro guardián"):...............................No
;FOSC1-FOSC0(tipo de oscilador):........................................Xtal
;------------------------------------------------------------------------------
;PROGRAMA
LIST p=16f84A
INCLUDE "p16f84A.inc"
ORG 00h
goto inicio
ORG 10h
inicio
;Configurar el Puerto B como salida.
;ponerlo a cero
call banco1
movlw 00h
movwf TRISB
call banco0
movlw 00h
movwf PORTB
;Programa principal.
derecha
btfss PORTA,0
goto izquierda
call der
goto derecha
izquierda
btfss PORTA,1
goto derecha
call izq
goto izquierda
;----------------------------------
;Subrutinas de giro a derecha e
;izquierda del motor.
;----------------------------------
izq
incf 31h,1; incremento puntero
movlw 0fh; elimino bits altos
andwf 31h,1; AND de 31h con valor 0Fh
movf 31h,0; guardo en W
call tabgiro; tabla de los valores de secuencia del motor
movwf PORTB ; envio al puerto B
der
decf 31h,1; decremento el puntero
movlw 0fh
andwf 31h,1
movf 31h,0
call tabgiro
movwf PORTB
call msg1
return
tabgiro
addwf PCL,1
retlw 0f9h
retlw 0fah
retlw 0f6h
retlw 0f5h
retlw 0f9h
retlw 0fah
retlw 0f6h
retlw 0f5h
retlw 0f9h
retlw 0fah
retlw 0f6h
retlw 0f5h
retlw 0f9h
retlw 0fah
retlw 0f6h
retlw 0f5h
;-------------------------
;SUBRUTINAS DE TIEMPOS.
;-------------------------
;0c1h=193 goto= 2 useg
;decfsz= 1 useg o 2 useg si el PC es modificicado o
;la condición es verdadera
;(decfsz= 1 useg) + (goto= 2 useg)= 3 useg.
; 3 x 193 = 579
; 579 x 579 = 335241 useg.
; 335241 x 3 = 1005723 useg.
sg1
call banco0
movlw 0c1h
movwf 10h
movwf 11h
movlw 03h
movwf 12h
salto1
decfsz 10h,1
goto salto1
goto recarga1
salto2
decfsz 11h,1
goto salto1
goto recarga2
salto3
decfsz 12h,1
goto salto1
return
recarga1
movlw 0c1h
movwf 10h
goto salto2
recarga2
movlw 0c1h
movwf 11h
goto salto3
;----------------
;1 milisegundo.
;----------------
msg1
call banco0
movlw 0ffh
movwf 10h
movlw 40h
movwf 11h
sal
decfsz 10h,1
goto sal
call sal1
decfsz 11h,1
goto sal
return
sal1
movlw 0ffh
movwf 10h
return
;----------------
;10 milisegundo.
;----------------
msg10
call banco0
movlw 0ffh
movwf 10h
movlw 80h
movwf 11h
sal2
decfsz 10h,1
goto sal2
call sal3
decfsz 11h,1
goto sal2
return
sal3
movlw 0ffh
movwf 10h
return
;-----------------------------------
;SUBRUTINAS DE CAMBIO DE BANCOS.
;-----------------------------------
banco0
bcf STATUS,IRP
bcf STATUS,RP1
bcf STATUS,RP0
return
banco1
bcf STATUS,IRP
bcf STATUS,RP1
bsf STATUS,RP0
return
banco2
bsf STATUS,IRP
bsf STATUS,RP1
bcf STATUS,RP0
return
banco3
bsf STATUS,IRP
bsf STATUS,RP1
bsf STATUS,RP0
return
END