Você está na página 1de 17

Minitutorial de 

uC PIC16F877A   

La idea de este tutorial es empezar a programar los uC PIC, solo se necesita tener una
pequeña base o conocimiento de las instrucciones de los PIC's, ya que no pretendo
escribir un libro, sino mostrar las aplicaciones más comunes desde las ideas más
básicas como "encender un LED" hasta "manejar el bus I2C para conectar un RTC (Reloj
de tiempo real)". Empezaremos con las características principales del PIC16F877A y en
los siguientes posts ya estaremos programando. 

Caraterísticas: 
Memoria de Programa tipo Flash 8Kx14 
Memoria Datos 368 bytes 
EEPROM 256 bytes 
33 pines de Entrada/Salida 
Encapsulado: 40 pines DIP, 44 pines PLCC y 44 pines TQFP 
Soporta Xtal 20MHz 
Voltaje de Operación: 2.0 hasta 5.5VDC 

Periféricos: 
1 Conversor A/D de 10-bits (8 canales) 
2 Módulos CCP (Captura, Comparador, PWM) 
1 Modulo I2C 
1 USART (Puerto Serie) 
2 Timers de 8 bits 
1 Timer 16 bits 

El juego de instrucciones lo pueden encontrar en la Biblioteca del foro.


   
Descripción del PIC 16F877
Anuncios Google:

1. PIC 16f877
2. Características
3. Diagrama de bloques
4. Descripción de pines
5. Aplicación

PIC 16F877
Se denomina microcontrolador a un dispositivo programable capaz de realizar
diferentes actividades que requieran del procesamiento de datos digitales y
del control y comunicacióndigital de diferentes dispositivos.
Los microcontroladores poseen una memoria interna que almacena dos tipos de datos;
las instrucciones, que corresponden al programa que se ejecuta, y los registros,
es decir, los datos que el usuario maneja, así como registros especiales para el control
de las diferentes funciones del microcontrolador.

Los microcontroladores se programan en Assembler y cada microcontrolador varía


su conjunto de instrucciones de acuerdo a su fabricante y modelo. De acuerdo
al número de instrucciones que el microcontrolador maneja se le denomina
de arquitectura RISC (reducido) o CISC (complejo).
Los microcontroladores poseen principalmente una ALU (Unidad Lógico
Aritmética), memoria del programa, memoria de registros, y pines I/O (entrada y/0
salida). La ALU es la encargada de procesar los datos dependiendo de las instrucciones
que se ejecuten (ADD, OR, AND), mientras que los pines son los que se encargan
de comunicar al microcontrolador con el medio externo; la función de los pines puede
ser de transmisión de datos,alimentación de corriente para l funcionamiento de este o
pines de control especifico.
En este proyecto se utilizo el PIC 16F877. Este microcontrolador es fabricado por
MicroChip familia a la cual se le denomina PIC. El modelo 16F877 posee varias
características que hacen a este microcontrolador un dispositivo muy versátil, eficiente
y practico para ser empleado en la aplicación que posteorimente será detallada.
Algunas de estas características se muestran a continuación:
 Soporta modo de comunicación serial, posee dos pines para ello.
 Amplia memoria para datos y programa.
 Memoria reprogramable: La memoria en este PIC es la que se
denomina FLASH; este tipo de memoria se puede borrar electrónicamente (esto
corresponde a la "F" en el modelo).
 Set de instrucciones reducido (tipo RISC), pero con las instrucciones necesarias
para facilitar su manejo.
CARACTERISTICAS
En siguiente tabla de pueden observar las características más relevantes del dispositivo:

CARACTERÍSTICAS 16F877

Frecuencia máxima DX-20MHz

Memoria de programa flash palabra de 14 bits 8KB

Posiciones RAM de datos 368

Posiciones EEPROM de datos 256

Puertos E/S A,B,C,D,E

Número de pines 40

Interrupciones 14

Timers 3

Módulos CCP 2

Comunicaciones Serie MSSP, USART

Comunicaciones paralelo PSP

Líneas de entrada de CAD de 10 bits 8

Juego de instrucciones 35 Instrucciones

Longitud de la instrucción 14 bits

Arquitectura Harvard

CPU Risc

Canales Pwm 2

Pila Harware -

Ejecución En 1 Ciclo Máquina -

Descripción de los puertos:


Puerto A:
 Puerto de e/s de 6 pines
 RA0 è RA0 y AN0
 RA1 è RA1 y AN1
 RA2 è RA2, AN2 y Vref-
 RA3 è RA3, AN3 y Vref+
 RA4 è RA4 (Salida en colector abierto) y T0CKI(Entrada de reloj del modulo
Timer0)
 RA5 è RA5, AN4 y SS (Selección esclavo para el puerto serie síncrono)

Puerto B:
 Puerto e/s 8 pines
 Resistencias pull-up programables
 RB0 è Interrupción externa
 RB4-7 èInterrupcion por cambio de flanco
 RB5-RB7 y RB3 è programacion y debugger in circuit

Puerto C:
 Puerto e/s de 8 pines
 RC0 è RC0, T1OSO (Timer1 salida oscilador) y T1CKI (Entrada de reloj del
modulo Timer1).
 RC1-RC2 è PWM/COMP/CAPT
 RC1 è T1OSI (entrada osc timer1)
 RC3-4 è IIC
 RC3-5 è SPI
 RC6-7 è USART

Puerto D:
 Puerto e/s de 8 pines
 Bus de datos en PPS (Puerto paralelo esclavo)
 Puerto E:
 Puerto de e/s de 3 pines
 RE0 è RE0 y AN5 y Read de PPS
 RE1 è RE1 y AN6 y Write de PPS
 RE2 è RE2 y AN7 y CS de PPS

Dispositivos periféricos:
 Timer0: Temporizador-contador de 8 bits con preescaler de 8 bits
 Timer1: Temporizador-contador de 16 bits con preescaler que puede
incrementarse en modo sleep de forma externa por un cristal/clock.
 Timer2: Temporizador-contador de 8 bits con preescaler y postescaler.
 Dos módulos de Captura, Comparación, PWM (Modulación de Anchura de
Impulsos).
 Conversor A/D de 1 0 bits.
 Puerto Serie Síncrono Master (MSSP) con SPI e I2C (Master/Slave).
 USART/SCI (Universal Syncheronus Asynchronous Receiver Transmitter) con 9
bit.
 Puerta Paralela Esclava (PSP) solo en encapsulados con 40 pines

DIAGRAMA DE BLOQUES
Para ver el gráfico seleccione la opción "Descargar" del menú superior
DESCRIPCIÓN DE PINES
Para ver el gráfico seleccione la opción "Descargar" del menú superior

NOMBRE DEL PIN PIN TIPO TIPO DE DESCRIPCIÓN

BUFFER

OSC1/CLKIN 13 I ST/MOS Entrada del oscilador de cristal / Entrada de señal


de reloj externa

OSC2/CLKOUT 14 O - Salida del oscilador de cristal

MCLR/Vpp/THV 1 I/P ST Entrada del Master clear (Reset) o entrada de


voltaje de programación o modo de control high
voltaje test

RA0/AN0       PORTA es un puerto I/O bidireccional

RA1/AN1 2 I/O TTL RAO: puede ser salida analógica 0

RA2/AN2/ Vref- 3 I/O TTL RA1: puede ser salida analógica 1

RA3/AN3/Vref+ 4 I/O TTL RA2: puede ser salida analógica 2 o referencia


negativa de voltaje
RA4/T0CKI 5 I/O TTL
RA3: puede ser salida analógica 3 o referencia
RA5/SS/AN4 6 I/O ST
positiva de voltaje
  7 I/O TTL
RA4: puede ser entrada de reloj el timer0.
 
RA5: puede ser salida analógica 4 o el
esclavo seleccionado por el puerto serial síncrono.

RBO/INT       PORTB es un puerto I/O bidireccional. Puede ser


programado todo comoentradas
RB1      
RB0 pude ser pin de interrupción externo.
RB2 33 I/O TTL/ST
RB3: puede ser la entada de programación de bajo
RB3/PGM 34 I/O TTL
voltaje
RB4 35 I/O TTL
Pin de interrupción
RB5 36 I/O TTL
Pin de interrupción
RB6/PGC 37 I/O TTL
Pin de interrupción. Reloj de programación serial
RB7/PGD 38 I/O TTL

39 I/O TTL/ST
40 I/O TTL/ST

RCO/T1OSO/T1CKI 15 I/O ST PORTC es un puerto I/O bidireccional

RC1/T1OS1/CCP2 16 I/O ST RCO puede ser la salida del oscilador timer1 o la


entrada de reloj del timer1
RC2/CCP1 17 I/O ST
RC1 puede ser la entrada del oscilador timer1 o
RC3/SCK/SCL      
salida PMW 2
RC4/SD1/SDA 18 I/O ST
RC2 puede ser una entrada de captura y
RC5/SD0       comparación o salida PWN

RC6/Tx/CK 23 I/O ST RC3 puede ser la entrada o salida serial de reloj


síncrono para modos SPI e I2C
RC7/RX/DT 24 I/O ST
RC4 puede ser la entrada de datos SPI y modo
25 I/O ST I2C
26 I/O ST
RC5 puede ser la salida de datos SPI

RC6 puede ser el transmisor asíncrono USART o


el reloj síncrono.
RC7 puede ser el receptor asíncrono USART o
datos síncronos

RD0/PSP0       PORTD es un puerto bidireccional paralelo

RD1/PSP1 19 I/O ST/TTL

RD2/PSP2 20 I/O I/O ST/TTL


I/O I/O
RD3/PSP3 21 ST/TTL
I/O I/O
RD4/PSP4 22 I/O ST/TTL

RD5/PSP5 27 ST/TTL

RD6/PSP6 28 ST/TTL

RD7/PSP7 29 ST/TTL

30 ST/TTL
REO/RD/AN5 8 I/O ST/TTL PORTE es un puerto I/O bidireccional

RE1/WR/AN       REO: puede ser control de lectura para el puerto


esclavo paralelo o entrada analógica 5
RE2/CS/AN7 9 I/O ST/TTL
RE1: puede ser escritura de control para el puerto
     
paralelo esclavo o entrada analógica 6
10 I/O ST/TTL
RE2: puede ser el selector de control para
el puerto paralelo esclavo o la entrada analógica 7.

Vss 12.31 P - Referencia de tierra para los pines lógicos y de


I/O

Vdd 11.32 P - Fuente positiva para los pines lógicos y de I/O

NC - - - No está conectado internamente

APLICACIÓN

Primeros Programas 

Para empezar, necesitas tener el MPLAB y crear un nuevo proyecto, en el


tema MPLAB de la sección Software del foro se explica como, luego si quieres ir
probando cada ejemplo, pero no simulado sino implementado en un protoboard y no
tienes un grabador de PIC's pues en mi Blog enseño como hacer uno. 

Problema 1. Resolver: 50+15-8 

Código: [Descargar] [Ocultar] [Seleccionar]


   ;Mi primer programa: 50+15-8 
    list p=16f877A    ;Indica al compilador que PIC estoy usando 

    org 0000H        ;dirección de inicio del código en la memoria de


programa 
    movlw    .8        ;cargo en el registro de trabajo W el valor decimal
8 (W=8) 
    sublw    .15        ;resto 15-W y el resultado se guarda en W (W=15-
8) 
    addlw    .50        ;sumo 50+W y el resultado se guarda en W
(W=50+(15-8)) 
     
    goto    $        ;bucle infinito 
    end                ;fin de programa 

El símbolo $ se usa junto con goto para saltar sobre la misma linea de comando. Como
se darán cuenta empiezo a ingresar los datos de atrás para adelante, es decir, primero
ingresé 8 y al último 50, eso se debe a a sintáxis de las instrucciones de operaciones
con literales. 

Problema 2. Más que un problema, es un ejemplo de como se accede a la memoria de


datos. 

Código: [Descargar] [Ocultar] [Seleccionar]


;Acceso a la memoria de datos 
    list p=16f877A 

    org        0000H 
    incf    20H,1    ;Incremento en 1 el dato almacenado en la dirección
20H 
    decf    21H,1    ;Decremento en 1 el dato almacenado en la direccion
21H 
    movlw    52H        ;Almaceno en W el dato hexadecimal 52H (W=52H) 
    addwf    22H,1    ;Sumo al dato almacenado en 22H el dato almacenado
en W y el resultado lo almaceno en la dirección 22H 
    subwf    23H,0    ;Resto al dato almacenado en la dirección 23H el
dato almacenado en W y el resultado lo almaceno en W 
    movlw    13H        ;Almaceno el dato 13H en W 
    iorwf    24H,1    ;El dato almacenado en 24H hace un OR con W y el
resultado se almacena en 24H 
    swapf    24H,1    ;Intercambio de posición el dato almacenado en 24H,
el dato AB ahora será BA 
    rlf        24H,0    ;Desplazo un bit a la derecha del dato almacenado
en 24H y el resultado lo almaceno en W 
    goto    $        ;Bucle infinito 

    end                ;Fin de programa 

Problema 3. Almacenar datos en la memoria de datos. 

Código: [Descargar] [Ocultar] [Seleccionar]


;Almacenar datos en memoria 
    LIST p=16F877A 
    INCLUDE<P16F877A.INC>    ;Librería del PIC16F877A donde se definen
configuraciones, registros y otros bits de 
                            ;information útiles 

    ORG        0000H        ;Indica el origen, inicio, posición del código


en la memoria de programa. 
    movlw    .5            ;W=5    no se puede enviar un dato directamente
a memoria de datos, primero debe pasar por W 
    movwf    20H            ;20H=5    luego de W se envía recién a la
posición de memoria deseada. 
    movlw    .6            ;W=6 
    movwf    21H            ;21H=6 
    movlw    .7            ;W=7 
    movwf    22H            ;22H=7 
                        ;se grabaron los datos 5,6 y 7 en las posiciones
de memoria 20H,21H y 22H. 

    bsf        STATUS,RP0    ;Cambiando de banco de memoria, ahora estamos


en el banco 1 
    movlw    .8            ;W=8 
    movwf    20H            ;20H=8 
    movlw    .9            ;W=9 
    movwf    21H            ;21H=9 
    movlw    .10            ;W=10 
    movwf    22H            ;22H=10 
    goto    $            ;Bucle infinito 

    end                    ;Fin del programa. 

Para visualizar mejor la ejecución de estos 3 ejemplitos debes usar las opciones Watch
y File Registers del MPLAB. Fijate aquí: MPLAB 

Revisar en la Biblioteca el tema Bancos de Memoria del PIC para entender mejor el
último programita. 

Más básico pues en ninguna parte, el próximo post encendemos y


apagamos LED's.    

NOTA: Agregar .INC al nombre de la librería, es decir, debe decir


P16F877A.INC dentro de los símbolos <> luego del INCLUDE, yo uso la opción
CODE para publicar el código pero por alguna razón este elimina la extensión
INC del nombre de la librería. Agregenle la extensión y vuelvan a compilar sus
programas. Usen la opción DESCARGAR para bajar el código y luego le cambian
la extensión .txt por .asm, finalmente abren el codigo con el MPLAB y lo
agregan a su proyecto. Suerte.
   
Clase 03. Manejo de los puertos de I/O. 
 
En esta oportunidad vamos a aprender a trabajar con los puertos "digitales" que trae el
PIC16F877A. El uso del puerto analógico se verá más adelante, cuando lleguemos al
Conversor A/D. 

Primero que nada se tiene que aclarar varios puntos: 


1. Librería P16F877A.INC 
En el problema 3 hicimos uso de la librería P16F877A.INC con el comando
INCLUDE<P16F877A>, por qué? bueno, en la Memoria de Datos se encuentran
los Registros Especiales o SFRlos cuales gobiernan al uC y sus recursos, solo hace
falta configurarlos para poder hacer uso de ellos. Por tal motivo debemos conocer
en que dirección se encuentra el registro que nos permite, por ejemplo,
configurar los puertos como entradas o salidas, o que registro nos permite usar el
periférico PWM, etc. Cada registro posee una dirección establecida (verMemoria
de Datos) pero hay una manera más sencilla de utilizar estos registros y no tener
que memorizar cada dirección, Microchip en el MPLAB nos facilita esta tarea con
las librerías *.INC según el modelo del uC, en estas librerías encontraremos los
nombres de los registros asignados a su dirección respectiva, por ejemplo: 
STATUS EQU H'0003' 
RP0 EQU H'0005' 

bsf STATUS,RP0 ;el bit 5 del registro STATUS se pone a 1 

es lo mismo que poner: 

bsf .3,.5 
solo que el primer ejemplo lo entendemos mejor, nos indica que estamos
configurando el bit RP0 del Registro STATUS. 

Estas librerías las encontramos en la carpeta Microchip/MPASM Suite por si


queremos indagar más. EQU es un comando que sirve para relacionar un valor
con un nombre, viene de la palabra "equal" que significa "igual", lo podemos usar
no solo para relacionar direcciones sino también para crear constantes y
variables, eso lo veremos en los ejemplos. 

2. Qué es el Registro de Estado (STATUS) 


El Registro de Estado se encuentra en los 4 bancos de la memoria RAM (pueden
constatarlo en el artículo Memoria de Datos) es un Registro muy usado porque,
entre otras cosas, nos permite acceder a los registros de cualquier banco de
memoria con solo configurar algunos bits, y para que necesitamos eso? pues los
registros que hacen posible configurar los puertos como Entrada o Salida de
datos pues están en el Banco 1 y por defecto nos encontramos en el Banco 0. El
registro STATUS tienen la siguiente estructura: 

-----| IRP | RP1 | RP0 | TO# | PD# | Z | DC | C | 


Bit-----7-----6------5------4------3-----2---1-----0 

Por ahora solo nos interesa conocer como cambiar de Banco, para esto se utilizan
los bits RP1 y RP0. 

RP1 y RP0: Nos permiten elegir el Banco de Memoria 

| RP1|  RP0 |  Banco  | 
|--0--|---0--| Banco 0 | 
|--0--|---1--| Banco 1 | 
|--1--|---0--| Banco 2 | 
|--1--|---1--| Banco 3 | 

Ejemplo: Estamos en el Banco 0 y queremos pasar a Banco 1 

bsf STATUS,RP0 ;RP1=0 y RP0=1 con lo que estamos pasando al Banco 1 según
la tabla anterior (RP1=0 por defecto luego de resetear el uC). 

Bueno vamos aprovechar también para conocer para que sirven los bits Z y C. 

Z: más conocido como señalizador de 0, se activa o pone en nivel alto "1" cuando
el resultado de una operación es 0, por ejemplo: 

movlw .10 
sublw  .10 

esta operación da como resultado 0, en ese instante el bit Z del Registro STATUS
cambia a "1". 

C: más conocido como señalizador de acarreo, se pone en nivel alto "1" en las
operaciones de suma cuando existe acarreo y se pone en nivel bajo "0" en las
operaciones de resta cuando también existe acarreo por lo general cuando se
resta un numero mayor de uno menor, por ejemplo: 

movlw .255 
addwl  .1 

la suma supera los 8 bits, por lo tanto se activa "1" el señalizador de acarreo
indicando que se ha superado el límite de registro, es decir, hubo un
desbordamiento y por consiguiente un acarreo. 
movlw .5 
sublw  .4 

la resta da como resultado un número negativo, por lo tanto se pone a "0" el


señalizador de acarreo. 

movlw B'10000000'     
movwf 22H 
rlf 22H,7 

en este caso también se activa "1" el señalizador de acarreo. 

3. Puertos A, B, C, D y E 

Puerto A: Tiene 6 bits, de los cuales 5 pueden trabajar como Entradas


Analógicas o Entradas/Salidas Digitales. Por defecto, al resetear el PIC, estos 5
bits (RA0,RA1,RA2,RA3 y RA5) se configuran como entradas o canales analógicos
para trabajar con el Conversor A/D. Para configurarlos con Entradas/Salidas
Digitales se debe configurar antes el registro ADCON1, ubicado en la dirección
9FH en el Banco 1, con el valor 0000011x, x puede ser 1 o 0. 

movlw B'00000110' 
movwf ADCON1 

De esta forma se configura el puerto A como Entradas/Salidas Digitales, luego


para especificar que pines son de Entrada y cuales de Salida se debe modificar el
Registro TRISA. 

bsf STATUS,RP0 
movlw B'11110000' 
movwf TRISA 
bcf STATUS,RP0 

Esto significa que los bits 0..3 están configurados como Salidas Digitales y los
pines 4..7 están configurados como Entradas Digitales. 

Puerto B: Este puerto es netamente Digital, tiene 8 bits y solo basta con
modificar el Registro TRISB para especificar que bits son de Entrada y cuales de
Salida. Por defecto, luego de un Reset todos los puertos están configurados como
entradas (TRISX=11111111). 

Puerto C: Este puerto es similar al Puerto B, con la diferencia que también


pueden cumplir otras funciones que no veremos por ahora. Por defecto es un
puerto Digital y solo hay que configurar los bits como Entrada o Salida por medio
del Registro TRISC. 

Puerto D: Este puerto a diferencia de los 2 anteriores dispone en sus entradas


de un Trigger Schmitt. Cuenta con 8 bits, por defecto es un puerto Digital y solo
hay que configurar los bits como Entrada o Salida por medio del Registro TRISD. 

Puerto E: Este puerto tiene 3 bits y se puede configurar como E/S Digitales o
como entradas analógicas.Por defecto es Digital y hay que configurar si son
Entradas o Salidas por medio del Registro TRISE. 

Luego de la teoría viene la práctica. 

Problema 4. Colocamos una resistencia de 220ohms en serie con un LED a la salida del
pin RB0, el ánodo del LED se conecta con la resistencia y el cátodo a tierra. Se pide
encender el LED. 
Código: [Descargar] [Ocultar] [Seleccionar]
;Activar el LED del pin RB0. A la salida del Pin RB0 se coloca una 
;resistencia en serie con el ánodo del LED y el cátodo del LED a tierra. 
    LIST P=16F877A 
    INCLUDE<P16F877A.INC>    ;Librería para el PIC16F877A 

    ORG        0000H        ;Dirección inicial del Código de Programa 


    bsf        STATUS,RP0    ;Cambiando al Banco-1 
    bcf        TRISB,0        ;Configurando el pin RB0 como salida 
    bcf        STATUS,RP0    ;Regresando al Banco-0 

    bsf        PORTB,0        ;Mandando una señal ALTA "1" por RB0 para
encender 
                        ;el LED 
    goto    $            ;Bucle infinito 

    END                    ;Fin de Programa. 

Problema 5. Encender y Apagar el LED sucesivamente. 


Código: [Descargar] [Ocultar] [Seleccionar]
;LED del pin RB0 oscila entre ON/OFF 
    LIST p=16F877A 
    INCLUDE<P16F877A.INC> 

    ORG        0000H 
    bsf        STATUS,RP0    ;Banco-1 
    bcf        TRISB,0        ;RB0 como salida 
    bcf        STATUS,RP0    ;Banco-0 
REPITE                    ;Etiqueta REPITE 
    btfss    PORTB,0        ;Es RB0=1? 
    goto    ACTIVAR        ;NO lo es -> salto hasta ACTIVAR 
    bcf        PORTB,0        ;SI lo es -> RB0=0 (Apago el LED) 
    goto    REPITE 
ACTIVAR                    ;Etiqueta ACTIVAR 
    bsf        PORTB,0        ;RB0=1 (Enciendo el LED) 
    goto    REPITE        ;Salto hasta REPITE 

    END                    ;Fin de Programa. 

Problema 6. Conteo Binario. Esta vez colocamos un pulsador a la entrada de RB0, se


configura para que cada pulso ingrese un "1" al pin RB0. A la salida del Puerto D
colocamos 8 LEDs con sus respectivas resistencias de tal manera que se enciendan
cuando se mande un "1" por el Pierto D. Se pide encender los LEDs cada vez que se
presione el pulsador, de tal manera que se visualize un conteo binario de 8 bits. 
Código: [Descargar] [Ocultar] [Seleccionar]
;Enciendo LEDs colocados en Puerto D luego de presionar un pulsador
colocado 
;en RB0. Se visualiza un conteo en binario cada que presionamos el
Pulsador. 
    LIST p=16F877A 
    INCLUDE<P16F877A.INC> 

    ORG        0000H 
    bsf        STATUS,RP0    ;Banco-1 
    bsf        TRISB,0        ;RB0 como entrada 
    clrf    TRISD        ;PORTD como salida 
    bcf        STATUS,RP0    ;Banco-0 
;========================================= 
    clrf    PORTD        ;PORTD=00 (Apago todos los LEDs) 
REPITE 
    btfss    PORTB,0        ;Es RB0=1? (Se presionó el pulsador?) 
    goto    $-1            ;NO -> Regreso a la instrucción anterior 
    incf    PORTD,1        ;SI -> PORTD=PORTD+1 (Encienden los LEDs) 
    btfsc    PORTB,0        ;Es RB0=0? (Se soltó el pulsador?) 
    goto    $-1            ;NO -> Regreso a la instrucción anterior 
    goto    REPITE        ;SI -> Repito el proceso o bucle 
     
    END                    ;Fin de Programa. 

Así finalizamos esta clase. Espero haya sido de su agrado.    

Bytes.    

NOTA: Agregar .INC al nombre de la librería, es decir, debe decir


P16F877A.INC dentro de los símbolos <> luego del INCLUDE, yo uso la opción
CODE para publicar el código pero por alguna razón este elimina la extensión
INC del nombre de la librería. Agregenle la extensión y vuelvan a compilar sus
programas. Usen la opción DESCARGAR para bajar el código y luego le cambian
la extensión .txt por .asm, finalmente abren el código con el MPLAB y lo
agregan a su proyecto. Suerte.
   
Clase 04. Llamadas a rutinas y Configuración de los FUSES. 
 
En esta clase entenderemos el llamado a rutinas usando la instrucción CALL y su
diferencia con los saltos GOTO. Luego para finalizar explicaré la configuración de los
famosos FUSES o palabra de Configuración que se presentan cuando queremos
programar nuestro PIC y no sabemos como configurarlos para un correcto grabado. 

Llamado a Rutinas 

Dentro del set de instrucciones de los microcontroladores PIC encontramos 2


instrucciones de salto los cuales son: GOTO y CALL, ambas instrucciones nos permiten
"saltar" o desplazarnos a otra dirección de código de nuestro programa, pero con
algunas diferencias, mientras que con GOTO nos desplazamos a una posición del
programa o hacia una etiqueta, con CALL nos desplazamos hacia una posición de
programa donde se encuentra una rutina (conjunto de instrucciones) y para regresar
usamos la instrucción RETURN, en esta operación se ve involucrado el uso de la Pila. 

Ejemplo: Uso del GOTO 

instruccion1 
instruccion2 
ETIQUETA 
instruccion3 
instruccion4 



instruccionN 
GOTO ETIQUETA 


Explicación: Las instrucciones 1,2,3,..N se ejecutan y luego del GOTO el contador de
programa PC se dirige hasta la posición ETIQUETA y se vuelven a ejecutar las
instrucciones 3,4,5,...N. 

NOTA: PC o Contador de Programa es un registro especial de 13 bits que se encarga de


direccionar la memoria de código, almacena la posición de la instrucción a ejecutar. Se
observa mejor su funcionamiento usando el MPLAB. 

Ejemplo: Uso de CALL 

instruccion1 
instruccion2 
CALL RUTINA1 
instruccion4 
instruccion5 



RUTINA1 
instruccionN 
instruccion(N+1) 


RETURN 

Explicación: Se ejecutan las instrucciones 1 y 2, luego se desplaza el PC hasta la


RUTINA1 pero se almacena en la Pila la posición de la instrucción 4 (PC+1), luego se
ejecutan las intrucciones que están dentro de la RUTINA1 y cuando encuentra la
instrucción RETURN, el PC lee la Pila para saber donde debe regresar, en este caso
regresa a la instrucción 4 la ejecuta y continua ejecutando las que siguen. 

NOTA: La Pila es un segmento de memoria de 8 niveles donde se almacena las


posiciones de retorno cada vez que se usa la instrucción CALL, esto significa que no se
puede usar más de 8 llamadas a rutinas una dentro de otra, es decir, dentro del
llamado de una RUTINA llamo a otra RUTINA y así sucesivamente; de superar el límite
se desbordará la Pila y el programa hará cualquier cosa menos lo que queremos, ya que
regresará a cualquier dirección de memoria de código. 

Problema 7. Probando el funcionamiento de la instrucción CALL. En MPLAB usar la


herramienta Hardware Stack para ver el comportamiento de la Pila al usar CALL. (Ver
tutorial del MPLAB). 
Código: [Descargar] [Ocultar] [Seleccionar]
;Prueba de CALL 
    LIST P=16F877A 
    INCLUDE    <P16F877A.INC> 

;Los números que aparecen como comentario al final de cada instrucción,


indican 
;el valor del contador de programa PC. 
;Las instrucciones "nop" no hacen nada en especial más que gastar un ciclo
de intrucción 

    ORG 0000H 
    nop                    ;0 
    call    RUTINA1        ;1 
    nop                    ;2 
    call    RUTINA2        ;3 
    nop                    ;4 
    goto    $            ;5 
;**************************************** 
RUTINA1 
    nop                    ;6 
    return                ;7 
;**************************************** 
RUTINA2 
    nop                    ;8 
    call    RUTINA1        ;9 
    call    RUTINA3        ;A 
    nop                    ;B 
    return                ;C 
;**************************************** 
RUTINA3 
    return                ;D 
     
    END 

OBS: La memoria de programa del PIC16F877A es de 8k y el PC es un registro de 13


bits precisamente equivalente a 8k para poder abarcar toda la extensión de la memoria;
pero las instrucciones GOTO y CALL son de 11 bits, con lo cual solo abarcan 2k de
memoria, en teoría de esta forma no se podría saltar desde la posición inicial de la
memoria hasta la final; pero anteriormente hemos visto que la memoria se divide en
bancos de 2k, es cuestión de seleccionar el banco adecuado e indicar la posición del
salto. Eso se hace con ayuda del registro PCLATH, pero se verá más adelante, por ahora
nuestros programas son muy pequeños y no involucran más de 2k de memoria, así que
aún no es motivo de preocupación. 

Palabra de Configuración (FUSES) 

Luego de hacer un programa es lógico que queramos grabarlo en nuestro PIC para
poder probar su funcionamiento, para esto existen infinidad de grabadores y softwares
que nos permiten hacer esta tarea. Una vez grabado el programa muchas veces nos
damos con la sorpresa que no funciona nuestra aplicación y en muchos casos se debe a
que no configuramos antes el software para grabar el PIC, y nos dicen que se trata de
los FUSES, que debemos configurarlos, a que se refieren? 

Bueno, los PIC's incluyen en una posición reservada de memoria (2007H) la famosa
Palabra de Configuración y a la cual solo se accede durante la grabación. El como
configuremos este registro determinará las características de funcionamiento del PIC. 

Palabra de Configuración: 

/ CP1 / CP0 / DEBUG / --- / WRT / CPD / LVP / BODEN / CP1 / CP0 / PWRTE#
/ WDTE / FOSC1 / FOSC0 / 
- 13  -- 12 --    11    -- 10 --  9  --   8  --  7   --     6   --   5  --   4   --     3    --    
2    --      1   --    0   -- bits 

CP1-CP0: Código de protección de memoria de programa. Si no están activos


cualquiera puede leer nuestro progama que grabamos en la memoria. Se suele activar
solo cuando tienes una aplicación final que deseas vender y no quieres que lean tu
código. 

DEBBUG: Modo Depurador en Circuito. Se usa cuando se tiene herramientas de


Emulación como el ICD2 que combinado con el MPLAB permiten Emular una aplicación
directamente en Hardware. 

WRT: Permiso para escritura en Modo FLASH. Se usa cuando en nuestro programa


accedemos a la memoria de datos EEPROM. 

CPD: Código de Proteccíon de la memoria EEPROM de Datos. Es como nuestro password


en caso de querer proteger esa parte de la memoria. 
LVP: Bit de Permiso para Programación en Bajo Voltaje. Se usa con algunos modelos de
PIC's sobretodo con los LF que trabajan con voltajes de 3V hasta 6V. 

BODEN: Bit de Permiso para el Reseteo por Caída de Tensión. 

PWRTE#: Bit de Permiso para el Timer de conexión de alimentación. Se usa para


resetear el PIC cada vez que se conecta la fuente de alimentación de nuestra
aplicación. 

WDTE: Bit de Permiso del Timer del Perro Guardián. Se activa cuando se usa el Perro
Guardián o WDT en nuestras aplicaciones, se verá más adelante. 

FOSC1-FOSC0: Sirve para elegir el tipo de Xtal que usamos. LP (Baja potencia, de 35


a 200kHz), XT (Estándar, de 100kHz a 4MHz), HS (Alta Velocidad, más de
4MHz), RC (Cuando usamos una Resistencia y un Condensador en vez de un Xtal). 

La palabra de configuración se puede configurar desde el programa de grabación o


desde el código de programa. 

En el WinPIC800 para el caso del PIC16F877A yo lo configuro de esta forma: 

En caso de querer configurar directamente desde nuestro código de programa,


deberemos agregar una línea de código como esta: 
Código: [Descargar] [Ocultar] [Seleccionar]
LIST    P=16F877A 
INCLUDE <P16F877A.INC> 
__CONFIG
_BODEN_OFF&_CP_OFF&_WRT_ENABLE_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC&_DEBUG_OFF&_
CPD_OFF&_LVP_OFF 
;resto del programa... 

de esta manera nos aseguramos de tener configurados los FUSES usemos el software
que usemos (Ese código hace lo mismo que la configuración en WinPIC800 que
mostramos arriba). 

Eso es todo por hoy, espero haya sido de su agrado. 

La próxima clase, haremos rutinas de retardos con bucles. 

Bytes.  

Você também pode gostar