Está en la página 1de 30

http://lonely113.blogspot.

com

PIC16F84A
I. CARACTERÍSTICAS

CPU

 Sólo 35 instrucciones Assembler.


 Instrucciones de 1 ciclo excepto las de salto (2 ciclos).
 Entrada de Reloj de hasta 20 MHz.
 Memoria de programa de 1024 palabras (14 bit).
 68 bytes de RAM de datos.
 64 bytes de EEPROM de datos.
 15 registros de función especial.
 8 niveles de Stack.
 Direccionamiento directo, indirecto y relativo.
 4 fuentes de interrupción.

o Externo por el pin RB0/INT.


o Desbordamiento de timer TMR0.
o Externo por cambio en los pines RB4-RB7.
o Escritura de EEPROM completa.

Periféricos

 13 pines I/O con control de dirección individual.


 Corriente alta para control directo de LEDs.

o Máx. 25mA como fuente.


o Máx. 25mA como sumidero.

 TMR0: Contador de 8 bits configurable.

Microcontrolador

 10000 ciclos de Lectura/Escritura de memora Flash de programa.


 10000000 ciclos de Lectura/escritura de memoria EEPROM de datos.
 Retención de datos de EEPROM > 40 años.
 In Circuit Serial Programming (ICSP).
 Watchdog Timer con su propio oscilador RC.
 Protección de código.
 Modo SLEEP de ahorro de energía.
 Opción de selección de tipo de oscilador.
http://lonely113.blogspot.com

II. DIAGRAMA DE BLOQUES


http://lonely113.blogspot.com

III. PINES

Nombre de Pin Pin Nº Descripción


OSC1/CLKIN 16 Entrada de oscilador de Cristal externo.
OSC2/CLKOUT 15 Salida de oscilador.
̅̅̅̅̅̅̅̅ 4 Master Clear.
Entrada de Voltaje de Programación.
RA0 17 PORTA. Puerto I/O bidireccional de 5 bit.
RA1 18
RA2 1
RA3 2
RA4/T0CKI 3 RA4/T0CKI: Entrada de reloj para timer TMR0.
RB0/INT 6 RB0/INT: Entrada de Interrupción externa.
RB1 7
RB2 8 PORTB. Puerto I/O bidireccional de 8 bit.
RB3 9 Puede ser configurado con resistores Pull-up.
RB4 10
RB5 11 RB4-RB0: entradas de interrupción externa.
RB6 12 RB6: Entrada de RELOJ en programación serial.
RB7 13 RB7: Entrada de datos en programación serial.
VSS 5 GND
VDD 14 Voltaje de alimentación.
http://lonely113.blogspot.com

IV. ORGANIZACIÓN DE MEMORIA DE PROGRAMA

 Contador de Programa de 13 bit.


 Stack de 8 niveles.
 Memoria de programa implementado físicamente hasta la dirección 3FFh.
 Vector RESET en dirección 0000h (Dirección de Inicio de programa).
 Vector de Interrupción en dirección 0004h (Dirección de inicio de rutina de
interrupción).
http://lonely113.blogspot.com

V. ORGANIZACIÓN DE MEMORIA DE DATOS

 Memoria de datos dividido en 2 bancos (Banco 0 y Banco 1).


 Las primeras 12 localizaciones están reservadas para los Registros de Función
Especial. Controlan el funcionamiento del PIC.
 El resto de localizaciones corresponde a los Registros de Propósito General.
http://lonely113.blogspot.com

A. Registros de Propósito General

 68 registros SRAM a partir de la dirección 0Ch hasta la dirección 7Fh (Banco 0).
 Las direcciones 8Ch – CFh (Banco 1) apuntan a los mismos registros del Banco 0.
Por ejemplo: Apuntar a la dirección 8Ch es igual que apuntar a la dirección 0Ch.
 Direcciones 50h a 7Fh no implementadas físicamente.

B. Registros de Propósito Especial

1. Registro STATUS (0x03h y 0x83h)

Contiene el estado aritmético del ALU, el estado del RESET y el bit de selección
de Banco para la memoria de datos.

R/W R/W R/W R R R/W R/W R/W


IRP RP1 RP0 ̅̅̅̅ ̅̅̅̅̅ Z DC C
7 6 5 4 3 2 1 0

IRP: No implementado. Mantener en “0”.


RP1: No implementado. Mantener en “0”.
RP0: Bit de selección de Banco de registros.
0: Banco 0.
1: Banco 1.
TO (Flag): Time-out
0: Tras conectar la alimentación, luego de instrucciones CLRWDT o SLEEP.
1: Por desbordamiento del Watchdog timer WDT.
PD (Flag): Power down (Apagado)
0: tras conectar la alimentación o luego de ejecutar la instrucción CLRWDT.
1: Al ejecutar el comando SLEEP.
Z (Flag): Cero
0: El resultado de una operación aritmética o lógica no es 0.
1: El resultado de una operación aritmética o lógica es 0.
DC (Flag): Digit Carry.
0: No hay acarreo en el cuarto bit de menor peso.
1: Acarreo en el cuarto bit de menor peso.
Importante en operaciones BCD.
C (Flag): Acarreo
0: No hay acarreo en el bit más significativo.
1: Acarreo en el bit más significativo.
http://lonely113.blogspot.com

2. Registro OPTION (0x81h)

Registro de Lectura/Escritura.

R/W R/W R/W R/W R/W R/W R/W R/W


RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
7 6 5 4 3 2 1 0

RBPU: Habilitación de resistores Pull-up en el puerto B.


0: Pull-up deshabilitado.
1: Pull-up habilitado.
INTEDG: Selección de flanco de interrupción para el pin RB0/INT.
0: Interrupción en flanco de bajada.
1: Interrupción en flanco de subida.
T0CS: Selección de fuente de reloj para TMR0.
0: Reloj interno de instrucción (Fosc/4).
1: Transición en el pin RA4/T0CKI.
T0SE: Tipo de flanco del pin RA4/T0CKI para incrementar TMR0.
0: Flanco de subida.
1: Flanco de bajada.
PSA: Asignación del divisor de frecuencia.
0: El divisor de frecuencia se asigna a WDT.
1: El divisor de frecuencia se asigna a TMR0.
PS2-PS0: Razón de división:

PS2-PS1-PS0 Razón TMR0 Razón WDT


000 1:2 1:1
001 1:4 1:2
010 1:8 1:4
011 1:16 1:8
100 1:32 1:16
101 1:64 1:32
110 1:128 1:64
111 1:256 1:128
http://lonely113.blogspot.com

3. Registro INTCON (0x0Bh)

Registro de Lectura/Escritura para control de todas las fuentes de


interrupciones.

R/W R/W R/W R/W R/W R/W R/W R/W


GIE EEIE T0IE INTE RBIE T0IF INTF RBIF
7 6 5 4 3 2 1 0

GIE: Habilitación global de interrupciones.


0: Todas las interrupciones deshabilitadas.
1: Todas las interrupciones habilitadas.
EEIE: Habilitación de interrupciones de escritura completa de EEPROM.
0: Interrupciones deshabilitadas.
1: Interrupciones habilitadas.
T0IE: Habilitación de interrupción de desbordamiento de TMR0.
0: Interrupciones deshabilitadas
1: Interrupciones habilitadas.
INTE: Habilitación de interrupciones por RB0/INT.
0: Interrupciones deshabilitadas
1: Interrupciones Habilitadas.
RBIE: Habilitación de interrupciones por cambio en los pines RB4-RB7.
0: Interrupciones deshabilitadas.
1: Interrupciones habilitadas.
T0IF (Flag): Interrupción por desbordamiento de TMR0.
0: TMR0 no se ha desbordado.
1: TMR0 se ha desbordado (Debe ser borrado por software).
INTF (Flag): Interrupción por RB0/INT.
0: No ha ocurrido interrupción por RB0/INT.
1: Ha ocurrido interrupción por RB0/INT (Debe ser borrado por software).
RBIF (Flag): Interrupción por cambio en los pines RB4-RB7.
0: Ningún pin de RB4-RB7 ha cambiado.
1: Al menos un pin de RB4-RB7 ha cambiado (Se borra por software).

4. Registros PCL (0x02h) y PCLATH (0Ah)

El contador de programa (PC) tiene una longitud de 13 bits. El byte menos


significativo es denominado registro PCL y es un registro de lectura/escritura. El
grupo de bits más significativos del PC (bits 9-13) se denomina registro PCH.
Este registro no se puede leer ni escribir directamente.

Todos los cambios del registro PCH pasan a través del registro PCLATH.
http://lonely113.blogspot.com

5. Registros INDF (0x00h) y FSR (0x04h)

Registros utilizados para direccionamiento indirecto. INDF no está


implementado físicamente.

6. Registro TMR0 (0x01h)

Registro que almacena el valor del contador TMR0 (Timer 0).

7. Registro EEDATA (0x08h)

Guarda el contenido de una dirección de la memoria EEPROM antes de su


escritura o después de su lectura. La memoria EEPROM tarda aproximadamente
10 ms en completar un ciclo de lectura o escritura.

8. Registro EEADR (0x09h)

Guarda la dirección de la memoria EEPROM que se quiere escribir o leer. Puede


direccionar 256 bytes, pero sólo los primeros 64 bytes están disponibles en la
EEPROM.

9. Registro EECON1 (0x88h)

R/W R/W R/W R R


EEIF WRERR WREN WR RD
4 3 2 1 0

EEIF (Flag): Interrupción de escritura de la memoria EEPROM.


0: No se ha completado la escritura.
1: Se ha completado la escritura (Se debe borrar por software).
WRERR (Flag): Error de escritura.
0: Se ha completado la operación de escritura sin error.
1: Se ha producido un error de escritura (MCLR o WDT reset).
WREN: Habilitación de escritura.
0: Escritura de EEPROM deshabilitada.
1: Escritura de EEPROM habilitada.
WR: Control de escritura.
0: Se ha completado la escritura un dato.
1: Inicio de escritura de dato en EEPROM (Se borra automáticamente).
WD: Control de lectura.
0: No se ha iniciado la lectura de un dato.
1: Inicio de lectura de un dato de EEPROM (Se borra automáticamente).
http://lonely113.blogspot.com

10. Registro EECON2 (0x89h)

No implementado físicamente. Se utiliza como dispositivo de seguridad durante


la escritura de la memoria EEPROM.

11. Registros PORTA (0x05h) y TRISA (0x85h)

PORTA es un puerto I/O bidireccional de 5 bit. El registro correspondiente de


configuración de dirección es TRISA.

PORTA
RA4 RA3 RA2 RA1 RA0
4 3 2 1 0

TRISA
TRISA4 TRISA3 TRISA2 TRISA1 TRISA0
4 3 2 1 0

TRISAX=0: RAX como salida.


TRISAX=1: RAX como entrada.

Cuando se utiliza el Pin RA4/T0CKI como entrada de pulsos de reloj el bit


TRISB4 de ponerse a “1” (RA4/T0CKI como entrada).

12. Registros PORTB (0x06h) y TRISB (0x86h)

PORTB es un puerto I/O bidireccional de 8 bit. Dispone de resistencias Pull-up


que se pueden habilitar o deshabilitar. El registro correspondiente de
configuración de dirección es TRISB.

PORTB
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
7 6 5 4 3 2 1 0

TRISB
TRISB7 TRISB6 TRISB5 TRISB4 TRISB3 TRISB2 TRISB1 TRISB0
7 6 5 4 3 2 1 0

TRISBX=0: RBX como salida.


TRISBX=1: RBX como entrada.

Cuando se utilizan los pines de interrupción éstos deben configurarse como


entradas.
http://lonely113.blogspot.com

VI. JUEGO DE INSTRUCCIONES

1. Orientadas a Registros (18 instrucciones)

Nemónico, Descripción Flags Ciclos


operandos
ADDWF f,d Sumar W y f. C, DC, Z 1
ANDWF f,d AND entre W y f. Z 1
CLRF f Borrar f. Z 1
CLRW - Borrar W. Z 1
COMF f,d Complemento bit a bit de f. Z 1
DECF f,d Disminuir f en 1. Z 1
DECFSZ f,d Disminuir f en 1. Saltar la siguiente instrucción si el 1(2)
resultado es 0.
INCF f,d Incrementar f en 1. Z 1
INCFSZ f,d Incrementar f en 1. Saltar la siguiente instrucción si 1(2)
el resultado es 0.
IORWF f,d OR inclusivo entre W y f. Z 1
MOVF f,d Mover (copiar) f. Z 1
MOVWF f Mover (copiar) W a f. 1
NOP - No realizar ninguna operación. 1
RLF f,d Rotar f a la izquierda. Incluye bit Carry. C 1
RRF f,d Rotar f a la derecha. Incluye bit Carry. C 1
SUBWF f,d Restar W de f. C, DC, Z 1
SWAPF f,d Intercambio de nibles en f. 1
XORWF f,d OR exclusivo entre W y f. Z 1

2. Orientadas a Bit (4 instrucciones)

Nemónico, Descripción Flags Ciclos


operandos
BCF f,b Poner bit a “0”. 1
BSF f,b Poner bit a “1”. 1
BTFSC f,b Verificar bit. Saltar la siguiente instrucción si es “0”. 1(2)
BTFSS f,b Verificar bit. Saltar la siguiente instrucción si es “1”. 1(2)
http://lonely113.blogspot.com

3. Operaciones con literales y de control (13 instrucciones)

Nemónico, Descripción Flags Ciclos


operandos
ADDLW k Sumar W y literal. Guarda en W. C, DC, Z 1
ANDLW k AND entre W y literal. Guarda en W. Z 1
CALL k Llamada a subrutina. 2
CLRWDT - Borrar Watchdog timer. ̅̅̅̅, ̅̅̅̅ 1
GOTO k Ir a dirección. 2
IORLW k OR inclusivo entre W y literal. Guarda en W. Z 1
MOVLW k Mover literal a W. 1
RETFIE - Retorno de interrupción. 2
RETLW k Retorno de subrutina con carga de literal en W. 2
RETURN - Retorno de subrutina. 2
SLEEP - Entrar en modo de espera. ̅̅̅̅, ̅̅̅̅ 1
SUBLW k Restar W de literal. Guarda en W. C, DC, Z 1
XORLW k OR exclusivo entre W y literal. Guarda en W. Z 1

Donde:

f: Dirección de registro de memoria de datos.

d: Ubicación donde se guardará en resultado de una operación.

d=0: El resultado se guarda en el registro W.


d=1: El resultado de guarda en la dirección f de la memoria de datos.

k: Literal.

b: Bit de registro (0 - 7)
http://lonely113.blogspot.com

VII. PROGRAMACION ASSEMBLER

a) Directivas para el ensamblador

Los siguientes códigos son directivas para el ensamblador. No tienen traducción al


lenguaje de máquina.

 Directiva EQU

La directiva EQUivalent permite definir direcciones o valores literales


igualándolos con nombres descriptivos de la función que realizarán.

STATUS equ 0x03 ; Define STATUS igualándolo con la


; direccion 03h (Registro STATUS).
PORTA equ 0x05 ; Define PORTA que igualandolo con la
; direccion 05h (Puerto A).
TEMP equ 0x0C ; Define un registro TEMP en la
; direccion 0Ch.
TIME equ 0x0A ; Asigna el nombre TIME al literal 0Ah.

 Directiva ORG

Indica al compilador a partir de qué posición de memoria se situarán las


instrucciones que le siguen a esta directiva en la memoria de programa.

ORG 0x00 ; El codigo que sigue comenzara en la


; direccion 00h en la memoria de programa.
ORG 0x04 ; El codigo que le sigue debe ser la rutina
; de interrupción, pues el vector de
; interrupcion se ubica en la direccion 04h.

 Directiva END

Indica al compilador el final programa. Debe situarse al final de todo el


programa.

ORG 0x00 ; Inicio de programa


;
;
END ; Fin de programa

 Directiva LIST

Indica al ensamblador el tipo de dispositivo con el que se está trabajando.

LIST P=16f84a
http://lonely113.blogspot.com

 Directiva INCLUDE

Sirve para incluir librerías existentes que se usarán a la hora de compilar el


programa.
INCLUDE “p16f84a.inc”

Esta directiva incluye el fichero p16f84a.inc que contiene definiciones de


registros de propósito especial y sus bits así como bits de configuración.

;------Register Definitions------- ;----- OPTION_REG Bits ----------


W EQU H'0000' NOT_RBPU EQU H'0007'
F EQU H'0001' INTEDG EQU H'0006'
;----- Register Files------------- T0CS EQU H'0005'
INDF EQU H'0000' T0SE EQU H'0004'
TMR0 EQU H'0001' PSA EQU H'0003'
PCL EQU H'0002' PS2 EQU H'0002'
STATUS EQU H'0003' PS1 EQU H'0001'
FSR EQU H'0004' PS0 EQU H'0000'
PORTA EQU H'0005' ;----- EECON1 Bits --------------
PORTB EQU H'0006' EEIF EQU H'0004'
EEDATA EQU H'0008' WRERR EQU H'0003'
EEADR EQU H'0009' WREN EQU H'0002'
PCLATH EQU H'000A' WR EQU H'0001'
INTCON EQU H'000B' RD EQU H'0000'
OPTION_REG EQU H'0081' ;-------RAM Definition------------
TRISA EQU H'0085' __MAXRAM H'CF'
TRISB EQU H'0086' __BADRAM H'07', H'50'-H'7F', H'87'
EECON1 EQU H'0088' ;---------Configuration Bits-----
EECON2 EQU H'0089' _CP_ON EQU H'000F'
;----- STATUS Bits --------------- _CP_OFF EQU H'3FFF'
IRP EQU H'0007' _PWRTE_ON EQU H'3FF7'
RP1 EQU H'0006' _PWRTE_OFF EQU H'3FFF'
RP0 EQU H'0005' _WDT_ON EQU H'3FFF'
NOT_TO EQU H'0004' _WDT_OFF EQU H'3FFB'
NOT_PD EQU H'0003' _LP_OSC EQU H'3FFC'
Z EQU H'0002' _XT_OSC EQU H'3FFD'
DC EQU H'0001' _HS_OSC EQU H'3FFE'
C EQU H'0000' _RC_OSC EQU H'3FFF'
;----- INTCON Bits --------------
GIE EQU H'0007'
EEIE EQU H'0006'
T0IE EQU H'0005'
INTE EQU H'0004'
RBIE EQU H'0003'
T0IF EQU H'0002'
INTF EQU H'0001'
RBIF EQU H'0000'

Si se desea se puede crear un fichero *.INC que contenga definiciones o


subrutinas para importarlo a programas que los requieran y así ahorrar
tiempo.
http://lonely113.blogspot.com

b) Uso de Comentarios

Escribir “;” al inicio de cada línea de comentario en el programa. Todo lo que se


escriba a la derecha del “;” hasta el final de línea será ignorado por el
ensamblador.

movlw 0x05 ;Mover 5h a W.


movwf PORTA ;Mover W al puerto A.
call DELAY ;Llamada a subrutina DELAY
movlw 0x06 ;Mover 6h a W
movwf PORTB ;Mover W al Puerto B.

Es conveniente insertar una cabecera al inicio de cada programa con información


del autor y el funcionamiento.
;--------------------------------------
;Autor:
;Fecha:
;Titulo:
;Descripcion:
;--------------------------------------

c) Etiquetas (Label)

Se sitúan a la izquierda de las instrucciones y sirven para identificar con facilidad


un segmento del código o “nombrar” una subrutina. El compilador relaciona la
etiqueta con la dirección de la instrucción que está a su derecha. Se utiliza
principalmente para realizar saltos o llamar a subrutinas.

LABEL movlw 0x05


movwf PORTA
call MOVER ;Llamada a subrutina MOVER
movwf PORTB
goto BEGIN ; Salta a la instruccion
; identificada con LABEL
;---------------------------------------------------------------
;Subrutinas

MOVER movlw 0xFF


return

end
http://lonely113.blogspot.com

d) Instrucciones

1) MOVLW, ADDLW, SUBLW

Instrucciones de operaciones aritméticas entre el registro W y literales.


org 0x00
movlw 0x0C ; Mover literal 0Ch al registro W
addlw 0x03 ; Sumar 03h al registro W
sublw 0x1F ; Sustraer W de 1Fh
; El resultado final es 10h en W
end

Dependiendo del resultado de estas operaciones los flags C, Z y DC podrían


activarse.

2) ANDLW, IORLW, XORLW

Instrucciones de operaciones lógicas entre el registro W y literales.


org 0x00
movlw 0x11 ; Mover literal 11h al registro W
andlw 0x10 ; AND entre W y 10h bit a bit
iorlw 0x0F ; OR entre W y 0Fh bit a bit
xorlw 0x10 ; XOR entre W y 10h bit a bit
; El resultado final es 0Fh en W
end

El resultado de estas operaciones puede hacer que el flag de cero Z se active.

3) MOVF, MOVWF, ADDWF, SUBWF

Instrucciones de operaciones aritméticas entre W y la memoria de datos.


REG1 equ 0x0D

org 0x00
movlw 0x0F ; Mover literal 0Fh al registro W
movwf 0x0C ; Mover W a la direccion 0Ch.
movlw 0x10 ; Mover 10h a W
addwf 0x0C,1 ; Sumar W con el dato en la
; direccion 0Ch. Guardar en
; direccion 0Ch.
movf 0x0C,0 ; Mover el dato en direccion 0Ch.
; a W.
movwf REG1 ; Mover W a REG1 (direccion 0Dh)
; El resultado final es 1Fh en
; REG1 (direccion 0Dh)
end

Dependiendo del resultado de estas operaciones los flags C, Z y DC podrían


activarse.
http://lonely113.blogspot.com

4) ANDWF, IORWF, XORWF, COMF, SWAPF

Instrucciones de operaciones lógicas entre W y la memoria de datos.

REG1 equ 0x0D

org 0x00
movlw 0x08 ; Mover literal 08h al registro W
movwf REG1 ; Mover W a la direccion 0Ch.
movlw 0x07 ; Mover 07h a W.
iorwf REG1,1 ; OR entre W y REG1. Guardar en
; REG1
comf REG1,1 ; Complementa los bits de REG1
; Guardar en REG1
swapf REG1,0 ; Intercambio de nibles de REG1
; Guardar en W
; El resultado final es 0Fh en W
end

El resultado de estas operaciones puede hacer que el flag de cero Z se active,


menos la instrucción SWAPF.

5) CLRW, CLRF, CLRWDT

CLRW: Borra el registro W


CLRF: Borra una dirección de la memoria de datos.
CLRWDT: Reinicia el contador del WDT (Watchdog timer)

REG1 equ 0x0D

org 0x00
movlw 0x0F ; Mover literal 0Fh al registro W
movwf REG1 ; Mover W a la direccion 0Ch.
clrw ; Borra W
clrf REG1 ; Borra REG1
; W y REG1 finalmente con 00h.
end

CLRW y CLRF hacen que el flag Z se active. CLRWT hace que los flags TO y PD
se activen (activos en bajo).
http://lonely113.blogspot.com

6) DECF, INCF

DECF: Disminuye en 1 el dato en una dirección de la memoria de datos.


INCF: Incrementa en 1 el dato en una dirección de la memoria de datos.

REG1 equ 0x0D

org 0x00
movlw 0x01 ; Mover literal 01h al registro W
movwf REG1 ; Mover W a la direccion 0Ch.
incf REG1,1 ; Incrementar REG1 en 1
; Guardar en REG1
incf REG1,1
decf REG1,0 ; Disminuir REG1 en 1
; Guardar en W
; W queda finalmente con 02h.
end

El resultado de estas operaciones puede hacer que el flag de cero Z se active.

7) DECFSZ, INCFSZ

De manera similar a las instrucciones anteriores, la diferencia es que saltan la


siguiente instrucción si se activa el flag Z (Si el resultado de ejecutar la
instrucción es 0).

REG1 equ 0x0D

org 0x00
movlw 0x01 ; Mover literal 01h al registro W
movwf REG1 ; Mover W a REG1
decfsz REG1,0 ; Disminuir REG en 1. Guardar en W
movlw 0xFF ; No se ejecuta esta instrucción
; porque la operacion anterior
; hace que Z se active
nop ; No realizar operación
; El resultado final es 00h en W

end

El resultado de la instrucción INCFSZ será 0 cuando se incremente 1 a FFh.


http://lonely113.blogspot.com

8) BCF, BSF

BCF: Poner a 0 un bit de un registro.


BSF: Poner a 1 un bit de un registro.

REG1 equ 0x0D

org 0x00
movlw 0x01 ; Mover literal 01h al registro W
movwf REG1 ; Mover W a REG1
bcf REG1,0 ; Pone a 0 Bit 0 de REG1
bsf REG1,4 ; Pone a 1 Bit 1 de REG1
; Resultado final es 10h en REG1
end

9) RLF, RRF

Rotar bits a la izquierda o a la derecha respectivamente. Incluyen el estado


actual del bit carry C en la rotación.

REG1 equ 0x0D


STATUS equ 0x03

org 0x00
movlw 0x01 ; Mover literal 01h al registro W
movwf REG1 ; Mover W a REG1
bcf STATUS,0 ; Pone a 0 Bit de carry C.
rlf REG1,1 ; Rotar a la izquierda
; Guardar en REG1
rlf REG1,1 ; Rotar a la izquierda
; Guardar en REG1

rrf REG1,0 ; Rotar a la derecha


; Guardar en W
; El resultado final es 02h en W
end
http://lonely113.blogspot.com

10) BTFSC, BTFSS

BTFSC: Verificar bit de registro, saltar la siguiente instrucción si es 0.


BTFSS: Verificar bit de registro, saltar la siguiente instrucción si es 1.

REG1 equ 0x0D

org 0x00
movlw 0x0F ; Mover literal 0Fh al registro W
movwf REG1 ; Mover W a REG1
btfsc REG1,4 ; Verifica Bit 4 de REG1
movlw 0xCC ; No se ejecuta
btfss REG1,7 ; Verifica bit 7 de REG1
movlw 0xF0 ; Se ejecuta
; El resultado final es F0h en W
end

11) GOTO, CALL

GOTO: Instrucción de salto incondicional sin retorno. Carga en el PC la


dirección que se encuentra a su derecha.

CALL: Llamada a subrutina con retorno. Carga en el PC la dirección que se


encuentra a su derecha y guarda en el Stack la dirección de retorno de
subrutina.

La instrucción de retorno es RETURN que carga en el PC la dirección de retorno


almacenada en el Stack.

12) RETURN, RETLW, RETFIE

RETURN: Retorno de subrutina. Carga la dirección de retorno del Stack al PC.

RETLW k: Retorno de subrutina. Carga la dirección de retorno del Stack al


PC y carga el literal k al registro W.

RETFIE: Retorno de rutina de interrupción. Carga la dirección de retorno del


Stack al PC y pone a 1 el bit GIE (Habilitación global de interrupciones) del
registro INTCON.

Este grupo de instrucciones y las anteriores se explicarán con mayor detalle en


la siguiente sección.
http://lonely113.blogspot.com

e) Establecimiento de dirección de puertos I/O

Configuración del modo de operación de los puertos I/O (como salidas o


entradas). Es posible configurarlos pin a pin. En el siguiente ejemplo se muestra la
manera de hacerlo:
; Se asume que se incluye el fichero “p16f84a.inc”

org 0x00
bsf STATUS,5 ; Cambio al banco 1
movlw 0x03 ; b’00000011’ a W
movwf TRISA ; b’00000011’ al registro TRISA
; RA0 y RA1 como entradas
; RA2-RA4 como salidas
movlw 0xF0 ; b’11110000’ a W
movwf TRISB ; b’11110000’ al registro TRISB
; RB0-RA3 como salidas
; RB4-RB7 como entradas
Bcf STATUS,5 ; Volver al banco 0

; Continua el programa

f) Estructura básica de un programa

;------------------------------------------------------------
;Autor:
;Fecha:
;Titulo:
;Descripcion:
;------------------------------------------------------------

#INCLUDE “p16f84a.inc” ; Usar la fichero de definiciones


LIST P=16f84a ; PIC16F84A

;------------------------------------------------------------
; Definiciones del usuario
;------------------------------------------------------------

ORG 0x00 ; Inicio de programa

;------------------------------------------------------------
; Modo de operacion de puertos I/O, interrupciones
;------------------------------------------------------------

;------------------------------------------------------------
; Codigo del programa
;------------------------------------------------------------

;------------------------------------------------------------
;Subrutinas
;------------------------------------------------------------

END ; Fin de programa


http://lonely113.blogspot.com

VIII. RUTINAS BASICAS

a) Puertos

Para leer o escribir en los puertos I/O primero se debe configurar los mismos
como entradas o salidas en los registros TRISA y TRISB (revisar el apartado
anterior). Luego se esto los registros PORTA y PORTB serán tratados como
cualquier otro registro.

El siguiente ejemplo lee el puerto A (entrada) y muestra el estado de los 4


primeros bit (RA3-RA0) en los 4 primeros bit del puerto B (RB3-RB0). Se podría
conectar Leds en el puerto B para observar el comportamiento.
INCLUDE “p16f84a.inc”
LIST p=16f84a
org 0x00
bsf STATUS,5 ; Cambio al banco 1
movlw 0x1F ; b’00011111’ a W
movwf TRISA ; PORTA como entrada
movlw 0xF0 ; b’11110000’ a W
movwf TRISB ; RB0-RA3 como salidas
; RB4-RB7 como entradas
bcf STATUS,5 ; Volver al banco 0
BEGIN: movf PORTA,0 ; Leer PORTA y mover a W
andlw 0x0F ; AND entre W y literal. Borra el
; nible superior. Guarda en W
movwf PORTB ; Mover W a PORTB. Se escribe en
; el nible inferior (Salidas).
goto BEGIN ; Bucle infinito
end ; Fin de programa

b) Bucles de retardo

El PIC ejecuta las instrucciones a muy alta frecuencia. En algunos casos es


necesario retrasar la ejecución de ciertas instrucciones para poder observar los
cambios en los Pines de salida.

Por ejemplo, si necesitáramos un oscilador conectado a un Led la frecuencia de


oscilación estaría sujeta a la frecuencia del Cristal (ciclo de instrucción=fosc/4).
#INCLUDE “p16f84a.inc”
LIST p=16f84a
org 0x00
bsf STATUS,5 ; Cambio al banco 1
clrf TRISA ; PORTA como salida
Bcf STATUS,5 ; Volver al banco 0
clrf PORTA ; Borrar PORTA
BEGIN: bsf PORTA,0 ; Poner a 1 PA0
nop ; LED en PA0
bcf PORTA,0 ; Poner a 0 PA1
goto BEGIN ; Bucle infinito
End ; Fin de programa
http://lonely113.blogspot.com

Si se trabaja con un oscilador de 10 MHz cada instrucción se ejecutaría a 2.5 MHZ


y dependiendo de la cantidad de instrucciones el led seguramente oscilaría a
cientos de KHz (imposible de ser percibidos por el ojo humano)

En este caso es necesario colocar bucles de retardo para hacer que el encendido y
apagado del Led sea a mucha menor frecuencia tal que pueda ser percibido por el
ojo humano. Esto se consigue con el uso de contadores anidados como se
muestra en el siguiente ejemplo:
INCLUDE “p16f84a.inc”
LIST p=16f84a
CONTA1 equ 0x0C
CONTA2 equ 0x0D
org 0x00
bsf STATUS,5 ; Cambio al banco 1
clrf TRISA ; PORTA como salida
Bcf STATUS,5 ; Volver al banco 0
clrf PORTA ; Borrar PORTA
BEGIN: bsf PORTA,0 ; Poner a 1 PA0
movlw 0xFA ; Inicio de rutina de retardo
movwf CONTA1 ; Mueve valores de inicio de
movwf 0xFF ; cuenta a CONTA1 y CONTA2
movwf CONTA2
LOOP1: decfsz CONTA1 ; Disminuir CONTA1
goto LOOP1 ; Saltar a LOOP1 si CONTA1>0
movlw 0xFA ; Reiniciar CONTA1 cuando
movwf CONTA1 ; llegue a 0
decfsz CONTA2 ; Ademas disminuir CONTA2
goto LOOP1 ; Saltar a LOOP1 si CONTA2>0
; Continuar si CONTA2=0
; Fin de rutina de retardo
bcf PORTA,0 ; Poner a 0 PA1
movlw 0xFA ; Inicio de rutina de retardo
movwf CONTA1
movwf 0xFF
movwf CONTA2
LOOP2: decfsz CONTA1
goto LOOP2
movlw 0xFA
movwf CONTA1
decfsz CONTA2
goto LOOP2 ; Fin de rutina de retardo
Goto BEGIN ; Bucle infinito
End ; Fin de programa

Es necesario colocar dos retardos entre el cambio de 1 a 0 y de 0 a 1.

El bucle de retardo cuenta de 250 (FAh) ciclos de instrucción 255 (FFh) veces, es
decir, 250x255= 63750 ciclos de instrucción antes de pasar a la siguiente
instrucción. Se puede calcular el tiempo de retardo teniendo en cuenta la
frecuencia del cristal y la cantidad de ciclos que toma cada instrucción para ser
ejecutada.
http://lonely113.blogspot.com

c) Subrutinas

Una subrutina es un fragmento de código que puede ser llamado cuantas veces se
necesite en el programa principal. Facilita la modificación del código y la reducción
de uso de memoria de programa. Las subrutinas deben ir al final del programa
para evitar que se ejecuten junto con el programa principal pues el PIC no
diferencia uno del otro.

En el ejemplo anterior se observa que se requieren 2 bucles de retardo, incluirlos


en el programa principal tiene varias desventajas, entre ellas: Análisis engorroso,
programa simple pero muy extenso, ocupa mucha memoria de programa, etc.

Es conveniente crear una subrutina de retardo y llamarlo en el programa principal


donde se requiera:
INCLUDE “p16f84a.inc”
LIST p=16f84a

CONTA1 equ 0x0C


CONTA2 equ 0x0D

org 0x00
bsf STATUS,5 ; Cambio al banco 1
clrf TRISA ; Borrar el registro TRISA
; PORTA como salida
Bcf STATUS,5 ; Volver al banco 0
clrf PORTA ; Borrar PORTA
BEGIN: bsf PORTA,0 ; Poner a 1 PA0
call DELAY ; Llamada a rutina de retardo
bcf PORTA,0 ; Poner a 0 PA1
Call DELAY ; Llamada a rutina de retardo
goto BEGIN ; Bucle infinito

;Subrutinas
;------------------------
DELAY movlw 0xFA ; Inicio de rutina de retardo
movwf CONTA1
movwf 0xFF
movwf CONTA2
LOOP: decfsz CONTA1
goto LOOP
movlw 0xFA
movwf CONTA1
decfsz CONTA2
goto LOOP ; Fin de rutina de retardo

end ; Fin de programa

El programa se ve mucho más simple y ordenado.


http://lonely113.blogspot.com

d) Tablas de datos

Las tablas de datos son subrutinas que agrupan una cierta cantidad de valores
numéricos ordenadamente y donde cada uno de ellos puede ser leído
dependiendo de algún criterio. El uso más común es la conversión de un formato
de datos a otro, por ejemplo Hexadecimal a 7 segmentos (para un display cátodo
común), Hexadecimal a ASCII (Para un LCD), etc.

El siguiente ejemplo convierte un valor hexadecimal, que se lee en el puerto A


(RA3-RA0), a un código para visualizar dicho valor en un display de 7 segmentos
conectado al puerto B (RB7-RB1).
INCLUDE “p16f84a.inc”
LIST p=16f84a

org 0x00 ; Inicio de Programa


bsf STATUS,5 ; Inicio configuracion E/S
movlw 0x0F ; b'00001111'
movwf TRISA ; RA0-RA3 como entradas
clrf TRISB ; Puerto B como salida
bcf STATUS,5 ; Fin configuracion E/s
BEGIN: movf PORTA,0 ; Mueve PORTA a W
call CONV ; Llama a subrutina CONV
movwf PORTB ; Mueve W a PORTB
goto BEGIN ; Bucle infinito

;Subrutina
; Tabla de conversion Hexadecimal a 7 segmentos.

CONV addwf PCL,1


retlw 0x7E ;0 PC+0
retlw 0x0C ;1 PC+1
retlw 0xB6 ;2 PC+2
retlw 0x9E ;3 PC+3
retlw 0xCC ;4
retlw 0xDA ;5
retlw 0xFA ;6
retlw 0x0E ;7
retlw 0xFE ;8
retlw 0xDE ;9
retlw 0xEE ;A
retlw 0xF8 ;B
retlw 0x72 ;C
retlw 0xBC ;D
retlw 0xF2 ;E
retlw 0xE2 ;F PC+F

end ;Fin de programa


http://lonely113.blogspot.com

La tabla es la subrutina CONV. Toma el valor hexadecimal que se encuentre en W


(proveniente del puerto A) y la suma al registro PCL (PCL almacena el byte bajo del
PC, la dirección de la siguiente instrucción a ejecutar). Automáticamente Se
apunta a la dirección actual en el PC. La instrucción RETLW retorna de la subrutina
y mueve al registro W el valor presente a su derecha.

Por ejemplo, suponiendo que inicialmente W=05h:

1. Se llama a la subrutina, entonces PC=PC+5h.


2. Se apunta a la instrucción: “retlw 0xDA ;5” que convierte 05h al valor
correspondiente que mostrará “5” en el display.
3. Retorno de interrupción y carga de 0xDA en el registro W.

e) Interrupciones

Una interrupción es un evento que hace que el microcontrolador deje de ejecutar


la tarea principal para pasar a una rutina (de interrupción). Finalizada ésta el
microcontrolador vuelve a la tarea principal.

La rutina de interrupción debe comenzar en la dirección 0x04h (Vector de


interrupción).

Es conveniente que justo al inicio de la rutina de interrupción se incluyan


instrucciones para guardar el contenido del registro W y el estado de los flags del
registro STATUS en ubicaciones temporales, pues éstos cambiarán al ejecutarse la
rutina de interrupción.

Tipos

1) Internas

 Por desbordamiento del registro TMR0. Cuando pasa de FFh a 00h.


 Escritura de datos en EEPROM completa.

2) Externas

 Por cambio de estado en el pin RB0/INT.


 Por cambio de estado en uno de los pines RB4-RB7.

Este tipo de interrupciones son aprovechables para implementar programas.


http://lonely113.blogspot.com

2.1. Por cambio de estado en alguno de los pines RB3-RB7

Para utilizar interrupciones por cambio de estado en uno de los pines RB3-
RB7 se debe tener en cuenta:

 Habilitar interrupciones Globales: poniendo a 1 el bit GIE del registro


INTCON.

 Habilitar interrupciones por el puerto B: Poniendo a 1 el bit RBIE del


registro INTCON.

 Permitir interrupciones por el puerto B: Cuando ocurre una


interrupción el bit RBIF del registro INTCON se pone a 1 para pasar a
la rutina de interrupción y no permitir más interrupciones. Se debe
poner a 0 con alguna instrucción antes del retorno de interrupción.
Caso contrario no se permitirá más interrupciones.

 No se dispone de ningún bit para especificar el tipo de flanco, por


esto la rutina de interrupción debe incluir algún mecanismo para que
ejecute ciertas instrucciones para un determinado flanco.

2.2. Por cambio de estado en el pin RB0/INT

Para utilizar interrupciones por el pin RB0/INT se debe tener en cuenta:

 Habilitar interrupciones Globales: poniendo a 1 el bit GIE del registro


INTCON.

 Habilitar interrupciones por el pin RB0/INT: Poniendo a 1 el bit INTE


del registro INTCON.

 Especificar el tipo de flanco: Cambiando el bit INTEDG del registro


OPTION.

0: Flanco de bajada
1: Flanco de subida (por defecto)

 Permitir interrupciones por RB0/INT: Cuando ocurre una interrupción


el bit INTF del registro INTCON se pone a 1 para pasar a la rutina de
interrupción y no permitir más interrupciones. Se debe poner a 0 con
alguna instrucción antes del retorno de interrupción. Caso contrario
no se permitirá más interrupciones.
http://lonely113.blogspot.com

El siguiente ejemplo es un contador decimal (0-9) de pulsaciones. El


pulsador se conecta al pin RB0/INT y produce una interrupción cada vez
que se pulsa. La cuenta se muestra en BCD mediante 4 led conectados al
puerto A (RA0-RA3).

include “p16f84a.inc”
LIST P=16f84a
COUNT equ 0x0C
TEMP equ 0x0D
TEMP2 equ 0x0E
org 0x00 ; Inicio de programa
goto BEGIN
org 0x04 ; Inicio de rutina de interrupcion
movwf TEMP ; Mover registro W a memoria temporal TEMP
movf STATUS,0
movwf TEMP2 ; Salva el estado de flags
incf COUNT,1 ; Incrementar COUNT y guardar en memoria
movlw 0x0A ; Mover d'10' a W
subwf COUNT,0
btfss STATUS,0 ; Si COUNT=10 saltar a CLEAR
goto RESUME ; Si COUNT<10 saltar a RESUM
goto CLEAR
RESUM: bcf INTCON,1 ; Habilita interrupciones por RB0
movf TEMP2,0
movwf STATUS
movf TEMP,0 ; Mover TEMP a W
retfie ; Retorno de interrupcion
CLEAR: clrf COUNT ; Borrar COUNT
movf TEMP2,0
movwf STATUS
movf TEMP,0
bcf INTCON,1 ;Permitir interrupciones
retfie ;Retorno de interrupción

;Programa Principal

BEGIN: bsf INTCON,7 ; Habilitacion global de interrupciones


bsf INTCON,4 ; Interrupciones por RB0
bcf INTCON,1 ; Permitir interrupciones por RB0
bsf STATUS,5 ; Configuracion E/S
movlw 0x01 ; b'00000001'
movwf TRISB ; RB0 como entrada RB1-RB7 como salidas
clrf TRISA ; PORTA como salida
bcf STATUS,5 ; Fin configuracion E/S
LOOP: movf COUNT,0
movwf PORTA ;Mueve COUNT a PORTA. Se muestra en BCD
goto LOOP ;Bucle infinito
end ; Fin de programa

Más ejemplos en http://lonely113.blogspot.com


http://lonely113.blogspot.com

IX. PROGRAMACIÓN DEL PIC

Registro de configuración

Existe un registro CONFIG (dirección 2007h) que dispone de ciertas opciones a la


hora de programar (escribir) el PIC. Sólo se puede acceder a este registro en el
momento de la programación del dispositivo.

CP ̅̅̅̅̅̅̅̅̅̅ WDT FOSC1 FOSC0


13 12 11 10 9 8 7 6 5 4 3 2 1 0

CP: Bit de protección de código.


1: Protección de código deshabilitada.
0: Protección de código habilitada.

̅̅̅̅̅̅̅̅̅̅̅: Power-up timer o temporizador de encendido.


1: Power-up timer deshabilitado
2: Power-up timer habilitado

FOSC1, FOSC0: Bit de selección de tipo de oscilador.

11: Oscilador RC
10: Oscilador HS
01: Oscilador XT
00: Oscilador LP

Los bits del registro CONFIG se pueden modificar mediante directivas al compilador
o directamente en el programa que se utiliza para programar el PIC.

1) Mediante directivas al compilador

El fichero “p16f84a.inc” define directivas para modificar los bits del registro
CONFIG.

;---------Configuration Bits-----
_CP_ON EQU H'000F'
_CP_OFF EQU H'3FFF'
_PWRTE_ON EQU H'3FF7'
_PWRTE_OFF EQU H'3FFF'
_WDT_ON EQU H'3FFF'
_WDT_OFF EQU H'3FFB'
_LP_OSC EQU H'3FFC'
_XT_OSC EQU H'3FFD'
_HS_OSC EQU H'3FFE'
_RC_OSC EQU H'3FFF'
http://lonely113.blogspot.com

Estas directivas se escriben luego de importar el fichero. Por ejemplo:

Se utilizará un oscilador XT (cristal) y se deshabilitará el WDT.

include “p16f84a.inc”
LIST P=16f84a

__CONFIG _WDT_OFF & _XT_OSC

NOTA: __CONFIG (doble barra)

2) Directamente en el programa

Por ejemplo el programa del Pickit 2 permite modificar estos bits:

También podría gustarte