programación pic16f84a

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.

Upload: percy-julio-chambi-pacco

Post on 30-May-2015

19.209 views

Category:

Documents


9 download

DESCRIPTION

Tutorial Básico de programación de PIC16F84A

TRANSCRIPT

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 RA1 RA2 RA3 RA4/T0CKI

17 18 1 2 3

PORTA. Puerto I/O bidireccional de 5 bit. RA4/T0CKI: Entrada de reloj para timer TMR0.

RB0/INT RB1 RB2 RB3 RB4 RB5 RB6 RB7

6 7 8 9

10 11 12 13

RB0/INT: Entrada de Interrupción externa. PORTB. Puerto I/O bidireccional de 8 bit. Puede ser configurado con resistores Pull-up. RB4-RB0: entradas de interrupción externa. RB6: Entrada de RELOJ en programación serial. 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, operandos

Descripción Flags Ciclos

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 resultado es 0.

1(2)

INCF f,d Incrementar f en 1. Z 1

INCFSZ f,d Incrementar f en 1. Saltar la siguiente instrucción si el resultado es 0.

1(2)

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, operandos

Descripción Flags Ciclos

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, operandos

Descripción Flags Ciclos

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.

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.

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

Directiva LIST Indica al ensamblador el tipo de dispositivo con el que se está trabajando. LIST P=16f84a

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.

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.

ORG 0x00 ; Inicio de programa

;

;

END ; Fin de programa

http://lonely113.blogspot.com

Directiva INCLUDE Sirve para incluir librerías existentes que se usarán a la hora de compilar el programa. 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. 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.

INCLUDE “p16f84a.inc”

;------Register Definitions-------

W EQU H'0000'

F EQU H'0001'

;----- Register Files-------------

INDF EQU H'0000'

TMR0 EQU H'0001'

PCL EQU H'0002'

STATUS EQU H'0003'

FSR EQU H'0004'

PORTA EQU H'0005'

PORTB EQU H'0006'

EEDATA EQU H'0008'

EEADR EQU H'0009'

PCLATH EQU H'000A'

INTCON EQU H'000B'

OPTION_REG EQU H'0081'

TRISA EQU H'0085'

TRISB EQU H'0086'

EECON1 EQU H'0088'

EECON2 EQU H'0089'

;----- STATUS Bits ---------------

IRP EQU H'0007'

RP1 EQU H'0006'

RP0 EQU H'0005'

NOT_TO EQU H'0004'

NOT_PD EQU H'0003'

Z EQU H'0002'

DC EQU H'0001'

C EQU H'0000'

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

;----- OPTION_REG Bits ----------

NOT_RBPU EQU H'0007'

INTEDG EQU H'0006'

T0CS EQU H'0005'

T0SE EQU H'0004'

PSA EQU H'0003'

PS2 EQU H'0002'

PS1 EQU H'0001'

PS0 EQU H'0000'

;----- EECON1 Bits --------------

EEIF EQU H'0004'

WRERR EQU H'0003'

WREN EQU H'0002'

WR EQU H'0001'

RD EQU H'0000'

;-------RAM Definition------------

__MAXRAM H'CF'

__BADRAM H'07', H'50'-H'7F', H'87'

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

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. Es conveniente insertar una cabecera al inicio de cada programa con información del autor y el funcionamiento.

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.

;--------------------------------------

;Autor:

;Fecha:

;Titulo:

;Descripcion:

;--------------------------------------

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.

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. 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. 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. Dependiendo del resultado de estas operaciones los flags C, Z y DC podrían activarse.

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

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

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

http://lonely113.blogspot.com

4) ANDWF, IORWF, XORWF, COMF, SWAPF Instrucciones de operaciones lógicas entre W y la memoria de datos. 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) CLRW y CLRF hacen que el flag Z se active. CLRWT hace que los flags TO y PD se activen (activos en bajo).

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

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

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. 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). El resultado de la instrucción INCFSZ será 0 cuando se incremente 1 a FFh.

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

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

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.

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

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

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.

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.

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

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:

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

; 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

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.

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

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

#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: 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.

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

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: El programa se ve mucho más simple y ordenado.

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

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).

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

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

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.

NOTA: __CONFIG (doble barra)

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

include “p16f84a.inc”

LIST P=16f84a

__CONFIG _WDT_OFF & _XT_OSC