Escolar Documentos
Profissional Documentos
Cultura Documentos
PIC 16F877
1
2.1. Características relevantes del PIC16F877
2.1.1. Introducción
Tabla 2.1. Gamas de los PIC's de acuerdo al número de bits de su bus de instrucciones
Tabla 2.2. Nombre del microcontrolador en base al rango de voltaje manejado y del tipo
de memoria ROM incluida
Rango de voltaje
Tipo de memoria
Estándar (4.5 a 6 volts) Extendido (2.5 a 6 volts)
EEPROM, OTP PIC16CXXX PIC16LCXXX
ROM PIC16CRXXX PIC16LCRXXX
Flash PIC16FXXX PIC16LFXXX
3
Figura 2.2. Algunos empaquetados de Circuito Integrado del PIC16F877
13 12 11 10 9 8 7 6 5 4 3 2 1 0
CP1 CP0 DEBUG - WRT CPD LVP BODEN CP1 CP0 #PWRTE WDTE FOSC1 FOSC0
2.1.2.3. Oscilador
Los PIC's de gama media permiten hasta 4 diferentes modos para el oscilador. El usuario
puede seleccionar alguno de estos 4 modos programando 2 bits de la palabra de configuración
del dispositivo denominados: FOSC1 y FOSC0, ubicados en un registro especial de
configuración en la localidad 2007H de la memoria de programa.
4
A continuación se describen los conceptos: Configuración del Oscilador, Tipos de Osciladores
y Rangos de Frecuencia para los Osciladores.
Tabla 2.3. Modos de configuración del oscilador para la operación del microcontrolador
Observación: Algunos PIC's poseen un modo de oscilación que les permite usar una
resistencia y un capacitor interno calibrados para 4 Mhz.
Donde:
- LP. Oscilador de cristal de cuarzo o resonador cerámico de baja potencia (Low
Power Cristal). Es un oscilador de bajo consumo con un cristal o resonador para trabajar
con frecuencias comprendidas entre 32 y 200 KHz.
- XT. Oscilador de cristal o resonador cerámico (Cristal/Resonador). Es un oscilador
estándar que permite una frecuencia de reloj comprendida entre 100 KHz y 4 MHz.
- HS. Oscilador de cristal o resonador de alta velocidad (High Spedd
Cristal/Resonador). Es un oscilador de una frecuencia comprendida entre 4MHz y 48
MHz.
- RC. Resistencia y capacitor (Resistor/Capacitor). Es un oscilador de bajo costo,
formado por una resistencia y un condensador
2. Tipos de Osciladores
Los tres modos LP, XT y HS usan un cristal o resonador externo, la diferencia sin embargo
es la ganancia de los drivers internos, lo cual se ve reflejado en el rango de frecuencia
admitido y la potencia consumida. A continuación se describe los diferentes tipos de
osciladores:
a. Cristal externo: En los tres modos mostrados en la Tabla 2.3 se puede usar un cristal
o resonador cerámico externo. En la Figura 2.5 se muestra la conexión de un cristal a
los pines OSC1 y OS2 del PIC.
5
Figura 2.5. Conexión de un cristal externo
Este modo sólo se recomienda cuando la aplicación no requiera una gran precisión en
la medición de tiempos.
c. Oscilador externo. También es posible conectar una señal de reloj generada mediante
un oscilador externo a la patita OSC1 del PIC. Para ello el PIC deberá estar en uno de
los tres modos que admiten cristal (LP, XT o HS). La conexión se muestra en la Figura
2.5.
6
Figura 2.7. Conexión de un oscilador externo
d. Oscilador interno de 4Mhz. En los PIC's que poseen este modo de oscilación, (modo
INTRC) el PIC usa un arreglo RC interno que genera una frecuencia de 4 Mhz con un
rango de error calibrable de ± 1.5%. Para calibrar el error de oscilación se usan los bits
CAL3, CAL2, CAL1 Y CAL0 del registro OSCCAL.
En resumen, los modos XT, LP o HS; de cristal o resonador se conecta entre los pines
OSC1/CLKIN y OSC2/CLKOUT, pero también permite conectar un oscilador externo al
pin OSC1/CLKIN. En la Figura 2.8 se muestra los modos de configuración del oscilador
principal del sistema.
En la Tabla 2.4 se muestran los rangos de frecuencia así como los capacitores
recomendados para un oscilador en base a cristal externo, en los tres modos LP, XT y HS.
7
Tabla 2.4. Rangos de frecuencia y capacitores recomendados para un oscilador en base a
cristal externo, en los tres modos LP, XT y HS
2.1.2.4. El Reset
Con la lectura de los bits #TO y #PD del registro de STATUS y los bits POR (Power-On Reset)
y BOR (Brown- Out Reset) del registro PCON (83h), se sabe en todo momento quién y cómo se
produjo un reset.
Se produce un Reset externo llevando a cero el pin #MCLR, si no se desea ningún sistema de
Reset externo, este pin se puede conectar directamente a la alimentación o a través de una
resistencia.
Cando la tensión de alimentación sobrepasa el límite de 1,7 V, para producir un Reset manual se
puede utilizar los circuitos y cálculos que muestra la Figura 2.10, dos circuitos externos de
Reset y fórmulas para calcular la tensión a la que tendrá lugar el pin #MCLR.
Figura 2.10. Circuitos externos de Reset y fórmulas para calcular la tensión a la que tendrá lugar
el pin #MCLR
Cuando se conecta la tensión de alimentación a los circuitos, sobre todo cuando la fuente de
alimentación tiene grandes condensadores de filtrado, la salida de tensión continua tarda en
crecer desde cero hasta alcanzar el máximo valor; una vez se hayan sobrepasado los 1, 7 V y
antes de llegar a la máxima tensión, en estos pocos milisegundos el microcontrolador tiene
tiempo para ejecutar algunas miles de instrucciones, pero antes de que comiencen a ser
9
ejecutadas hay que estar seguro de que el resto de los componentes que constituyen el diseño se
han terminado de inicializar. Es aquí donde se aprovechan las ventajas del Power-On Reset y si
se ha habilitado, las del temporizador Power-Up Timer (PWRT), bit configurable en la
programación del microcontrolador que añade 72 milisegundos adicionales al impulso interno
de Reset. Para la mayoría de los casos con el POR y el tiempo añadido por el PWRT será más
que suficiente para que, tanto la tensión de alimentación como el resto de los circuitos, se hayan
estabilizado. No obstante, si se desea que el microcontrolador permanezca inactivo hasta que la
tensión de alimentación esté‚ muy próxima a su máximo valor, no queda más remedio que,
además de habilitar el PWRT, se instale un circuito externo de Reset con tensión de disparo
ajustable, tres resistencias y un transistor así lo garantizan (ver el esquema de la Figura 2.10).
Los circuitos internos de Reset también tienen un circuito de control (OST, Oscillator Start-up
Timer) que añade un retardo de 1.024 ciclos del reloj externo después de los 72 mseg.
proporcionados por el PWRT. Este retardo asegura que el oscilador externo ha terminado de
estabilizarse antes de que la CPU comience a ejecutar instrucciones.
Otro de los modos de Reset es el Brown- Out Reset que tiene un comportamiento muy similar
al POR, sólo que los márgenes de tensión son diferentes, en este caso se sitúan entre 3,8 V y 4,2
V, en realidad lo que trata de detectar, es que la tensión de alimentación no tenga fallos o
pequeñas caídas de voltaje durante periodos de tiempo muy cortos.
No sustituye a los circuitos de Reset es una forma muy eficaz de controlar los pequeños fallos
que se pueden producir en la alimentación, bien por cortes rápidos de la tensión de entrada, o
bien porque se ha producido un pico de corriente muy elevado y la fuente de alimentación no ha
sido capaz de proporcionarlo y ha caído su tensión.
En la Figura 2.11 se pueden ver el diagrama de bloques del circuito de Reset dentro del chip, el
cual incorpora dos circuitos PWRT y OST, que se describen a continuación:
- El circuito PWRT, está formado por un contador de 10 bits que se encarga de contar
1.024 impulsos de reloj interno formado por una red RC (este oscilador no tiene nada que
ver con el oscilador principal). Este es el circuito encargado de proporcionar los 72
milisegundos de retardo;
- El circuito OST, está formado por un segundo contador también de 10 bits, que es
habilitado una vez que hayan transcurrido los 72 milisegundos de retardo del circuito
PWRT, y se encarga de contar 1.024 impulsos del oscilador externo; suficientes ciclos
para que al finalizar la cuenta el oscilador ya esté totalmente estabilizado.
10
Figura 2.11. Diagrama de bloques del circuito de Reset dentro del chip
La siguiente es una lista de las características que comparte el PIC16F877 con los dispositivos
más cercanos de su familia: PIC16F873, PIC16F874, PIC16F876 y PIC16F877:
1. CPU:
- Tecnología RISC
- Tiene 35 instrucciones
- Todas las instrucciones se ejecutan en un ciclo de reloj, excepto los saltos que requieren
dos
- Frecuencia de operación de 0 a 20 MHz (200 nseg de ciclo de instrucción)
- Opciones de selección del oscilador
2. Memoria:
- Hasta 8k x 14 bits de memoria Flash de programa
- Hasta 368 bytes de memoria de datos (RAM)
- Hasta 256 bytes de memoria de datos EEPROM
- Lectura/escritura de la CPU a la memoria Flash de programa
- Protección programable de código
- Stack de hardware de 8 niveles
3. Reset e interrupciones:
- Hasta 14 fuentes de interrupción
- Reset de encendido (POR)
- Timer de encendido (PWRT)
- Timer de arranque del oscilador (OST)
- Sistema de vigilancia Watchdog timer.
4. Otros:
- Modo SLEEP de bajo consumo de energía
11
- Programación y depuración serie "In-Circuit" (ICSP) a través de dos pines
- Rango de voltaje de operación de 2.0 a 5.5 V
- Alta disipación de corriente de la fuente: 25mA
- Rangos de temperatura: Comercial, Industrial y Extendido
- Bajo consumo de potencia:
Menos de 0.6mA a 3V, 4 Mhz
20 µA a 3V, 32 Khz
menos de 1µA corriente de standby (modo SLEEP).
5. Periféricos:
En la Tabla 2.5 se muestra los periféricos del PIC16F877 y los dispositivos más cercanos, con sus
respectivas características.
PIC16F873 PIC16F874
Periférico Características
PIC16F876 PIC16F877
3 a 5 Puertos con líneas digitales programables
PortA,B,C PortA,B,C,D,E
Paralelos individualmente
Contador/Temporizador de 8 bits con pre-
Timer0 Timer0
escalador de 8 bits
Contador/Temporizador de 16 bits con pre-
3 Timers Timer1 Timer1
escalador
Temporizador de 8 bits con pre-escalador y
Timer2 Timer2
post- escalador de 8 bits y registro de periodo
Captura Captura 16 bits, 1.5 nseg de resolución máxima
2 módulos
Comparación Comparación 16 bits, 200 nseg de resolución máxima
CCP
PWM PWM 10 bits
1 Conversor
AN0,...,AN4 AN0,...,AN7 de 10 bits, hasta 8 canales
A/D
SSP SSP Puerto Serie Síncrono
USART/SCI USART/SCI Puerto Serie Universal
Puertos Serie
Puerto serie para programación y depuración
ICSP ICSP
“in circuit”
Puerto
Paralelo PSP PSP Puerto de 8 bits con líneas de protocolo
Esclavo
12
Figura 2.12. Diagrama de pines y Diagrama de bloques de la organización interna del
PIC16F877
13
2.1.5. Descripción de la CPU
1. Ciclo de instrucción
El registro Program Counter (PC) es gobernado por el ciclo de instrucción como se muestra en
la Figura 2.13. Cada ciclo de instrucción la CPU lee (ciclo Fetch) la instrucción guardada en la
memoria de programa apuntada por PC y al mismo tiempo ejecuta la instrucción anterior, esto
debido a una cola de instrucciones que le permite ejecutar una instrucción mientras lee la
próxima.
Como puede verse, cada ciclo de instrucción (Tcy = 4Tosc) se compone a su vez de cuatro
ciclos del oscilador (Tosc= 1/Fosc)). Cada ciclo Q provee la sincronización para los
siguientes eventos:
Debido a esto cada ciclo de instrucción consume 4 ciclos de reloj, de manera que si la
frecuencia de oscilación es Fosc, Tcy será 4/Fosc.
14
El PC consta de 13 bits, separados en dos partes PCH y PCL: como se muestra en la
Figura 2.14.
Donde:
- PCL = El byte de orden bajo
- PCH = El byte de orden alto
• Registro W. Registro de 8 bits que siempre es uno de los operandos y puede guardar
resultados temporales de las operaciones realizadas por la ALU.
• Registro STATUS. Registro de 8 bits, cada uno de sus bits (denominados Banderas)
es un indicador de estado de la CPU o del resultado de la última operación, como
se indica en la siguiente Figura 2.15.
R/W-0 R/W-0 R/W-0 R-1 R-1 R/W-x R/W-x R/W-x
IRP RP1 RP0 #T0 #PD Z DC C
Bit 7 6 5 4 3 2 1 Bit 0
En la resta es al contrario
Notación:
# = Negación
R = Bit leíble, W= Bit Escribible, U= No implementado (se lee como 0)
n = Valor después del Reset de encendido
Las restas se realizan sumando el complemento a dos del segundo operando, por ejemplo,
para los datos 4FH y 25H:
En la Tabla 2.6 se resumen las 35 instrucciones que reconoce la CPU de los PIC de rango o
gama media, incluyendo su mnemónico, tiempo de ejecución, código de máquina y afectación
de banderas.
16
Tabla 2.6. Conjunto de Instrucciones de Rango o Gama Media
17
1. Descripción de algunas instrucciones
Ejemplo 1
Ejemplo 2
Se indica como comentario a un lado de cada instrucción como queda el contenido de W, del
registro 20h y de las banderas C, DC y Z.
Cada instrucción en lenguaje de máquina (binario) del PIC contiene un código de operación
(opcode) el cual puede ser de 3 a 4 o 6 bits, dependiendo del tipo de instrucción. A
continuación se describe el formato para cada tipo de instrucción de los PIC de rango
medio:
b : Especificación en tres bits del bit sobre el que se va a operar f = dirección de 7 bits del
archivo de registros.
Los PIC tienen dos tipos de memoria: Memoria de Datos y Memoria de programa, cada bloque
con su propio bus: Bus de datos y Bus de programa, para poder permitir el acceso simultáneo a
estos dos bloques; por lo cual cada bloque puede ser accedido durante un mismo ciclo de
oscilación.
Los PIC's de rango medio poseen un registro Contador del Programa (PC) de 13 bits, capaz de
direccionar un espacio de 8Kx14 posiciones de memoria de tipo FLASH, como todas las
instrucciones son de 14 bits, esto significa un bloque de 8k instrucciones. Acceder a una posición
de memoria no implementada, provoca la lectura o escritura de la posición de memoria
envolvente.
19
Figura 2.16. Organización de la Memoria de Programa
A continuación se describe el Vector de Reset, Vector de interrupción, Manejo del Contador del
Programa (PC), Paginación, y Memoria de Stack:
1. Vector de Reset
Cuando ocurre un reset el contenido del PC es forzado a cero, ésta es la dirección donde la
ejecución del programa continuará después del reset, por ello se le llama "dirección del
vector de reset".
2. Vector de interrupción
El registro PCLATH no es modificado en esta circunstancia, por lo cual habrá que tener
cuidado al manipular el registro PC (saltos y llamadas a subrutina) dentro de la Rutina de
Atención a la Interrupción.
El registro contador del programa (PC) especifica la dirección de la instrucción que la CPU
buscará (fetch) para ejecutarla.
20
El PC consta de 13 bits, separados en dos partes: como se muestra en la Figura 17.
El byte de orden bajo es llamado el registro PCL, mientras que el byte de orden alto es
llamado registro PCH. Este último contiene los bits PC<12:8> y no se puede leer o
escribir directamente, todas las actualizaciones al registro PCH deben ser hechas a través
del registro PCLATH.
4. Paginación
Para saltar entre una página y otra, los bits más significativos del PC deberán ser
modificados. Debido a que las instrucciones GOTO y CALL sólo pueden direccionar un
21
bloque de 2K (pues usan una dirección de 11 bits) deben existir otros dos bits que
completen los 13 bits del PC para moverse sobre los 8K de memoria de programa.
Estos dos bits extra se encuentran en un SFR denominado PCLATH (Program Counter
Latch High) en sus bits PCLATH<4:3>. Por esto antes de un GOTO o un CALL el usuario
deberá asegurarse que estos bits apunten a la página deseada.
5. Memoria de Stack
La memoria de datos RAM consta de dos áreas mezcladas y destinadas a funciones distintas:
Los SFR son localidades asociadas específicamente a los diferentes periféricos y funciones de
configuración del PIC y tienen un nombre específico asociado con su función. Mientras que los
GPR son memoria RAM de uso general.
1. Bancos de memoria
Direccionamiento
RP1:RP0 Banco
Indirecto (IRP)
0 0 0
0
0 1 1
1 0 2
1
1 1 3
Tabla 2.7. Selección de los bancos de memoria RAM con RP0 y RP1.
Cada banco consta de 128 bytes (de 00h a 7Fh), en las posiciones más bajas de cada banco
se encuentran los SFR, y arriba de éstos se encuentran los GPR. Toda la memoria de
datos está implementada en RAM estática.
Los Registros de Funciones Especiales (SFR) son registros usados por la CPU y los módulos
periféricos para controlar el funcionamiento deseado del dispositivo. Estos registros están
realizados como RAM estática. Estos Registros SFR están reflejados en varios bancos para
reducir el código y tener un acceso más rápido.
23
Un listado de los Registro Especiales de los PIC 16F87X se muestra en Anexo 3 “Registro
Especiales de los PIC16F87x.pdf”.
3. Direccionamiento Directo
Figura 2.20. Acceso a una posición de memoria mediante direccionamiento directo e indirecto
4. Direccionamiento indirecto
El registro INDF mismo al leerse de manera indirecta (con FSR=0) producirá un cero. Y
al escribirse de manera indirecta no es afectado.
Ejemplo 3
Este ejemplo se muestra el uso del direccionamiento indirecto, limpia un bloque de memoria
de datos desde la localidad 20h a la localidad 2Fh.
CLRF STATUS ; Selecciona Banco cero
MOVLW 0X20 ; Carga valor de apuntador a RAM
MOVWF FSR ; Inicializa apuntador
24
Sigue CLRF INDF ; Limpia localidad apuntada por FSR
INCF FSR,F ; Incrementa apuntador
BTFSS FSR,4 ; Si ya terminó escapa a continuar
GOTO sigue ; Si no repite
...
Ejemplo 4
En este ejemplo se muestra la manera como se cambia mediante instrucciones dentro del
programa de un banco a otro de la memoria RAM.
CLRF STATUS ; Limpia registro STATUS (Banco 0)
…
BSF STATUS,5 ; RP0=1, (Banco 1)
…
BSF STATUS,6 ; RP1=1, (Banco 3)
…
BCF STATUS,5 ; RP0=0, (Banco 2)
…
Aunque el archivo de registros en RAM puede variar de un PIC a otro, la familia del
PIC16F87x coincide casi en su totalidad. En la F igura 2.21 se muestra a detalle el mapa
de este archivo de registros y su organización en los cuatro bancos que ya se
describieron.
26
2.2. Programación del PIC16F877 en Assembler
Luego de hacer un programa se requiere grabar en el PIC para poder probar su funcionamiento,
para esto existen infinidad de grabadores y softwares que permiten hacer esta tarea. Una vez
grabado el programa muchas veces no funciona la aplicación y en muchos casos se debe a que no
se configura antes el software para grabar el PIC, esta configuración se trata de los FUSES.
Los PIC's incluyen en una posición reservada de memoria (2007H) la Palabra de Configuración
y a la cual solo se accede durante la grabación. La configuración de este registro determinará las
características de funcionamiento del PIC. En la Figura 2.22 se muestra la Palabra de
Configuración.
13 12 11 10 9 8 7 6 5 4 3 2 1 0
CP1 CP0 DEBUG - WRT CPD LVP BODEN CP1 CP0 #PWRTE WDTE FOSC1 FOSC0
bit 13-12: CP1:CP0: Bits de protección del código de la memoria Flash de programa (2)
bit 5-4:
11 = Sin protección de código
10 = 1F00h a 1FFFh código protegido (PIC16F877, 876)
10 = 0F00h a 0FFFh código protegido (PIC16F874, 873)
01 = 1000h a 1FFFh código protegido (PIC16F877, 876)
01 = 0800h a 0FFFh código protegido (PIC16F874, 873)
00 = 0000h a lFFFh código protegido (PIC16F877, 876)
00 = 0000h a 0FFFh código protegido (PIC16F8741873)
27
bit 7: LVP: Bit de habilitación de programación a bajo voltaje
1 = Patillas RB3/PGM tienen funciones PGM , bajo voltaje de programación
habilitado
0 = RB3 es digital I/O, HV habilitado, #MCLR se emplea para programación
Nota
(1)= Al habilitar el Brown-out Reset se habilita automáticamente el temporizador Power-up
(PWRT). Habilitando el Power-up Timer se habilita al mismo tiempo el Brown-out
Reset
(2)= Los dos pares de bit CP1:CP0 tienen que tener el mismo valor para habilitar el
esquema de la protección del código listado.
WRT: Permiso para Escritura en Modo FLASH. Se usa cuando en el programa se accede
a la memoria de datos EEPROM.
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.
FOSC1-FOSC0: Sirve para elegir el tipo de Xtal que se usa. LP (Baja potencia, de 35 a
200kHz), XT (Estándar, de 100kHz a 4MHz), HS (Alta Velocidad, más de 4MHz), RC
(Cuando se usa una Resistencia y un Condensador en vez de un Xtal).
2. En el código de programa. Es este caso se debe agregar una línea de código, con la
Directiva de Ensamblador __CONFIG, como se indica a continuación:
; Resto del programa...
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
De esta manera se asegura tener configurados los FUSES que se usarán en el software de la
aplicación. Este código hace lo mismo que la configuración en WinPIC800 que se mostró en
la Figura 2.23.
29
;==========================================================================
;
; Configuration Bits
;
;==========================================================================
Algunos FUSES que son comunes a todos los PICS, se muestran a continuación:
Las Directivas del Ensamblador son palabras reservadas para indicarle al MASM, que funciones
del microcontrolador se deben configurar cuando se compile el programa. Las directivas
indispensables para la correcta compilación del programa se describen en la Tabla 2.8:
30
DATA 0x012, 0x1345
DATA "Prueba 1,2,3"
Genera una serie de instrucciones RETLW, una por cada expresión que acompaña
a la directiva.
DT
DT 1, 2, 3, 5, 7
Directivas de Control
Las dos se emplean para asignar expresiones a símbolos, esos símbolos no pueden
CONSTANT luego cambiar de valor (son constantes). Sintaxis distinta, pero igual efecto.
EQU
CONSTANT longitud=0x10
31
longitud EQU 0x10
Las dos se emplean para asignar expresiones a símbolos, esos símbolos pueden
cambiar de valor (son variables). Sintaxis distinta, pero igual efecto.
VARIABLE
SET
VARIABLE BUFFER=0x20
BUFFER SET 0x20
Se emplea para definir una etiqueta para una cadena de caracteres siempre que
aparezca la etiqueta, se sustituye directamente por la cadena.
#DEFINE
#DEFINE bit_0 STATUS,RP0
32
Grupo de directivas para ensamblar instrucciones si es cierta o no una expresión.
IF versión==1
MOVLW 0x0A ;Esto se ensambla si expresión es cierta o distinta de 0
MOVWF PORTB
ENDIF
IF
ELSE
IF expresión
ENDIF
;Si la expresión es cierta se ensambla este grupo
Grupo 1 de Directivas e Instrucciones
ELSE
;y si es falsa, este otro
Grupo 2 de Directivas e Instrucciones
ENDIF
#DEFINE DE_B_a_A 1
IFDEF DE_B_a_A
MOVF PORTB,w
IFDEF
MOVWF PORTA
ELSE
MOVF PORTA,W
MOVWF PORTB
ENDIF
VARIABLE i
WHILE
i=0
ENDW
WHILE i < CONTADOR
RETLW i
i+=1
ENDW
Macros
Una macro debe ser definida primero antes de poder ser llamada en el código
fuente siguiente.
Definiciones:
33
Banco_0 MACRO
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
Banco_1 MACRO
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
Utilización:
movlw 0xF0
Banco_1
movwf TRISB
Banco_0
NOTA: Para mayor información ver el archivo "2 MPASM el ensamblador Microchip.pdf", o el
archivo del Data Sheet de MPASM.
NOTA. Como ésta es la numeración por defecto hay que tener mucho cuidado al colocar
números en decimal. Por ejemplo, la instrucción MOVLW 64 no utilizará el número 64
decimal sino el 100 decimal (64 hex = 100 dec)
- Binario. Para escribir números en binario utilizar B'xxxxxxxx' (comillas simples), así:
B'10011001', b'01110000'; o de la siguiente forma xxxxxxxxB, así: 10011001B,
01110000b.
- Decimal. Se utiliza la forma D'xxx' (comillas simples), así: D'112', d'10'; o la forma corta
anteponiendo un punto al número decimal, así: .200, .100.
- ASCII. Se utiliza la forma A'120' (comillas simples), así: A'p', a'*'; o la forma corta
anteponiendo solo con comillas simples, así: 'p', '*'.
Tener en cuenta siempre el tamaño de datos con el que se está trabajando, ya que en la mayoría
de los casos, se utilizará un número para almacenarlo en el acumulador y éste es de 8 bits, por lo
tanto, el número utilizado no debe exceder de 255 en decimal o FF en hexadecimal. En la Tabla
2.9 se muestra los tipos de datos para los PIC's en MPASM.
34
Tabla 2.9. Tipos de datos para los PIC's en MPASM
64 Por defecto
Un programa está constituido por un conjunto de instrucciones en secuencia, cada una de las
cuales identifican unívocamente las funciones que los PIC están en calidad de desarrollar. Cada
instrucción está representada por un código operativo (en inglés operation code o más
brevemente opcode) a 14 bit's y es almacenada en una posición de memoria EEPROM.
Pero es muy probable que opcode venga representado en notación hexadecimal, que representan
exactamente el mismo valor pero en forma más breve, es decir:
0x0100
2. Otras convenciones permiten definir las variables, las constantes, las etiquetas (label) de
referencia a las direcciones de memoria, etc. El conjunto de estas convenciones facilita la
escritura de un programa para los PIC's que viene implemento en lenguaje assembler. Un
programa escrito en lenguaje assembler puede ser escrito en una PC utilizando cualquier
procesador de palabra o editor en calidad de generar archivos de tipo ASCII. Un archivo
ASCII o, mejor dicho, un archivo de texto que contenga un programa en assembler es
llamado source o fuente assembler.
35
2.2.4.2. Compilador assembler o ensamblador
Una vez preparado el source assembler, es necesario un programa que traduzca las
instrucciones mnemónicas y todas las otras formas convencionales con las cuales fue escrito el
source en una serie de números (los opcode) reconocibles directamente por el PIC. Este
programa se llama compilador assembler o assemblador.
En la Figura 2.24 se esquematiza el flujo de operaciones y los archivos que se generan para pasar
de un source assembler a un PIC programado.
Los archivos de entrada que necesita el compilador assembler y los archivos de salida que se
generan luego de ejecutar dicho compilador, son archivos de entrada/salida con extensiones de
archivo predefinidas. Para la salida los archivos se generan de acuerdo al ensamblador utilizado.
Por ejemplo, para el compilador MPASM los archivos entrada/salida serían:
a. Archivos de entrada:
1. Código fuente (.asm): Archivo fuente de entrada al ensamblador.
2. Archivo include (.inc): Archivo de inclusión o cabecera.
b. Archivos de salida:
1. Archivo de listado (.lst): Archivo del listado generado por el ensamblador.
2. Archivo de error (.err): Archivo de errores de ensamblado.
3. Archivo hexadecimal (.hex, .hxl, .hxh): Archivo hexadecimal con código
ejecutable que se programa el microcontrolador.
36
4. Archivo de referencias cruzadas (.cof): Archivo para ver el código que se está
ejecutando cuando se simula con el Proteus.
5. Archivo de símbolos y depuración (.cod).
6. Archivo objeto (.o).
a. Archivos de entrada:
Etiquetas
Operación, Mnemónicos (instrucciones), Directivas y Macros
Operandos
Comentarios
Se considera como un espacio en blanco uno o más espacios o tabulaciones, que se utiliza
para separar las partes de una línea del código fuente, lo que hace que el código sea más
fácil de leer. Cualquier número de espacios en blanco o tabulaciones son exactamente
igual que uno.
37
Figura 2.25. Esquema de un programa en assembler.
Cabe indicar que las subrutinas deben ir al final del programa, antes de la directiva del
Ensamblador END.
A continuación se describe los cuatro tipos de información de cada línea del código
fuente:
- Etiquetas
Una etiqueta se usa para representar una línea o grupo de código, o un valor
constante. Se necesita para las instrucciones de salto.
Las etiquetas deben empezar en la columna 1. Pueden terminar en "dos puntos" (:),
espacio, tabulación o fin de línea. Las etiquetas deben comenzar por un caracter
alfabético o por un guión bajo (_) y puede contener caracteres alfanuméricos, guión
bajo (_) y el signo de interrogación (?).
Las etiquetas no deben comenzar por dos guiones bajos, ejem., __config; comenzar
por un guión bajo y un número, ejem., _2NDLOOP; y ser palabras reservadas del
ensamblador.
Las etiquetas pueden tener como máximo 32 caracteres. Por defecto, se distinguen
mayúsculas y minúsculas, pero esto puede anularse con la opción en línea de
comandos (/c). Si se utiliza "dos puntos" (:) al definir una etiqueta, se le trata como un
operador de la etiqueta y no como parte de la propia etiqueta.
Los mnemónicos de las instrucciones del ensamblador, las directivas y las llamadas a
macros deben colocarse de la segunda columna en adelante. Si hay una etiqueta en la
misma línea, las instrucciones deben separarse de esa etiqueta por "dos puntos", o por
uno o más espacios o tabulaciones.
38
Los mnemónicos le dicen al ensamblador qué instrucciones de código máquina
(códigos de operación) deben utilizarse. Por ejemplo, suma (add), ir a (goto) o
movimientos (movwf). A diferencia de las etiquetas que se crean por el programador,
los mnemónicos los proporciona el lenguaje ensamblador que se utilice. Los
mnemónicos no son en ningún caso sensibles a mayúsculas/minúsculas.
Las directivas son órdenes del ensamblador que aparecen en el código fuente pero
que normalmente no son traducidas directamente a códigos de operación. Se utilizan
para controlar al ensamblador: sus entradas, salidas y asignación de datos. Las
directivas no son en ningún caso sensibles a mayúsculas/minúsculas.
Las macros son conjuntos de instrucciones y directivas definidas por el usuario que
se insertarán en el código fuente al realizar el ensamblado siempre que la macro se
invoque.
- Operandos
Los operandos dan información a la instrucción sobre los datos que deben utilizarse y
donde se encuentran. Los operandos deben separarse de los mnemónicos por uno o
más espacios, o tabulaciones. Los operandos múltiples deben separarse por comas.
- Comentarios
Los comentarios son texto que explica el funcionamiento de una línea o líneas de
código. El ensamblador MPASM trata lo que esté después de un punto y coma como
un comentario. Todos los caracteres que siguen al punto y coma se ignoran hasta el
final de la línea. Las constantes de la cadena que contienen un punto y coma se
permiten y no se confunden con comentarios.
Además, del source con extensión .ASM es necesario entregar al compilador un segundo
archivo producido por Microchip con extensión .INC diferente según el tipo de PIC que
se esté utilizando, este source contiene algunas definiciones dependientes del chip
utilizado. Estos archivos se llaman de cabecera y se encuentran en el directorio de
instalación de MPASM o de MPLABX.
; This header file defines configurations, registers, and other useful bits of
; information for the PIC16F877 microcontroller. These names are taken to match
; the data sheets as closely as possible.
;==========================================================================
;
; Revision History
;
;==========================================================================
;1.12 01/12/00 Changed some bit names, a register name, configuration bits
; to match datasheet (DS30292B)
;1.00 08/07/98 Initial Release
;==========================================================================
;
; Verify Processor
;
;==========================================================================
IFNDEF __16F877
MESSG "Processor-header file mismatch. Verify selected processor."
ENDIF
;==========================================================================
;
; Register Definitions
;
;==========================================================================
W EQU H'0000'
F EQU H'0001'
42
;----- PIE1 Bits ----------------------------------------------------------
43
;----- EECON1 Bits --------------------------------------------------------
;==========================================================================
;
; RAM Definition
;
;==========================================================================
__MAXRAM H'1FF'
__BADRAM H'8F'-H'90', H'95'-H'97', H'9A'-H'9D'
__BADRAM H'105', H'107'-H'109'
__BADRAM H'185', H'187'-H'189', H'18E'-H'18F'
;==========================================================================
;
; Configuration Bits
;
;==========================================================================
LIST
b. Archivos de salida:
Estos archivos no son muy relevantes, por ejemplo los archivos .LST y .ERR se utilizan para el
control de lo realizado en la compilación, solo el archivo .HEX (archivo hexadecimal) es el que
se utiliza realmente para programar el PIC; porque contiene el código ejecutable. El archivo
.HEX no es un archivo en formato binario y no corresponden directamente al contenido que
deberá tener la FLASH del PIC, pero su formato si corresponde directamente a lo que será
transferido al PIC en forma legible y con unas instrucciones. Para mayor información de los
archivos de salida revisar el archivo "2 MPASM el ensamblador Microchip".
44
Cabe destacar que la ejecución del compilador assembler depende del software que se utiliza,
para lo cual ver el manual de usuario correspondiente.
1. Por una sola vez se debe crear en el disco duro un directorio de trabajo en el cual de ahora
en adelante se almacenan todos los source, por ejemplo el nombre puede ser:
C:\PICPRG
2. Instalar el software necesario para compilar los sources, en este caso el fabricante
Microchip tiene el IDE MPLABX que contiene el compilador MPASM.
4. En el IDE del MPLABX seleccionar desde la barra de menú principal run la opción Build
Main Project, ejecuta el programa MPASM, en el cual se configura el tipo de PIC a ser
compilado.
Dentro del proyecto Ejemplo en los directorios build y dist se obtienen entre otros los
siguientes archivos nuevos:
Ejemplo.hex
Ejemplo.lst
Ejemplo.err
Ejemplo.cod
Ejemplo.o
Por último, se debe programar el PIC, para lo cual se utiliza únicamente el archivo
"Ejemplo21.hex", que contiene el archivo compilado en formato Intel Hex 8.
La programación de los chips se puede realizar con cualquier programador, para lo cual es
necesario el software respectivo, por lo que se recomienda hacer referencia a la respectiva
documentación.
Como ejemplo orientativo, para usar diagramas de flujo (la sintaxis ver los archivos del
directorio "Diagramas de Flujo") se hace a continuación el desarrollo de un programa sencillo.
45
Se trata de obtener la nota media de un alumno durante un trimestre. El análisis de esta tarea, que
se la llama MEDIA, puede dar el siguiente procedimiento:
1. leer NOMBRE
2. leer NOTA
3. no hay más notas (nota<0), ir al punto 7
4. acumular las notas
5. incrementar el número de notas
6. ir al punto 2
7. calcular la MEDIA
8. imprimir NOMBRE
9. imprimir MEDIA
INICIO
contador 0
media 0
Leer: nombre
Leer: nota
media media+nota
contador contador+1
SI
nota>=0
NO
media media/contador
Imprimir:
nombre
media
FIN
Realizar un circuito para hacer encender en forma secuencial un diodo LED, cuya frecuencia de
intermitencia es determinada por una subrutina que introduce un retardo software, es decir, un
retardo basado en el tiempo de ejecución de un ciclo continuo de instrucciones.
46
1. Diagramas de Flujo
INICIO
LED←1
Delay
LED←0
SI
LED=1
NO
LED←1
47
Delay
cont0←0
cont1←0
cont0←cont0-1
SI
cont0<>0
NO
cont1←cont1-1
SI
cont1<>0
NO
FIN
2. Código en Assembler
;Declaracion de constantes
LED EQU 0
;Declaracion de variables
Cont0 EQU 0x20
Cont1 EQU 0x21
;Reset Vector
ORG 00H
;Cambia al banco 1
48
bsf STATUS,RP0
bcf STATUS,RP1
;Cambia al banco 0
bcf STATUS,RP0
;Inicio programa
MainLoop
call Delay
btfsc PORTB,LED
goto SetToZero
bsf PORTB,LED
goto MainLoop
SetToZero
bcf PORTB,LED
goto MainLoop
;Subroutinas
;Software Delay
Delay
clrf Cont0
clrf Cont1
DelayLoop
decfsz Cont0,1
goto DelayLoop
decfsz Cont1,1
goto DelayLoop
return
END
Se va analizar línea por línea el contenido del código source, desde de la primera línea de
código:
o PROCESSOR. Es una directiva del compilador assembler que permite definir que
microcontrolador se utiliza en el programa. Las directivas no son instrucciones mnemónicas
que el compilador traduce en el respectivo opcode, pero si, son simples indicaciones que se
entrega al compilador para determinar el funcionamiento durante la compilación. En este
caso se debe informar al compilador que la instrucción entregada al source es la relativa a un
PIC16F877:
PROCESSOR 16F877
Las directivas del compilador tienen sentido solo durante la compilación del source, por lo
tanto un PIC no podrá nunca seguir una directiva.
o RADIX. Esta directiva sirve para informar al compilador que los números reportados sin
notación, deben concebirse como números decimales. Es decir, si se desea especificar, por
ejemplo el número hexadecimal 10 (16 decimal) se escribiría 10H o también, 0x10 o
49
también, H'10'; pero no se puede escribir solamente 10, porque sería interpretado como 10
decimal.
RADIX DEC
o EQU. Esta directiva es muy importante porque permite definir las constantes simbólicas al
interno del source. En particular la palabra LED de ahora en adelante en el source será
equivalente al valor 0. La finalidad principal de la existencia de la directiva EQU es la de
poder hacer los source más legibles y de permitir cambiar los valores constantes en un único
punto del source.
LED EQU 0
Declaración de Variables
La directiva EQU también se utiliza para la declaración de variables, porque las etiquetas
asignadas a las direcciones de memoria se utilizan como punteros. La dirección desde
empieza a definirse el área de datos al interno del PIC es 20H para el PIC16F877, es decir,
un área en la cual almacena variables durante la ejecución del programa. Esta área coincide
con el área RAM del PIC definida por Microchip como el área de los FILE REGISTER. Los
file register son localizaciones RAM disponibles por el usuario. Esta dirección de inicio es
fija y no puede ser cambiada respecto a las localizaciones precedentes que son ocupadas por
otros registros especializados para uso interno.
Cont0 EQU 20H
Cont1 EQU 21H
Las label's Cont0 y Cont1 son marcas escogidas por el programador, que en el resto del
source asumirá los valores de la direcciones en las cuales fueron colocados. Los nombres de
las label’s (etiquetas) pueden ser cualquiera a excepción de las palabras reservadas al
compilador (tales como las instrucciones mnemónicas y las directivas).
Una label se distingue de una constante simbólica porque su valor viene colocado en etapa de
compilación y no asignado por el programador estáticamente. Por esta confusión en la
actualidad no se la utiliza para declarar variables, pero se la menciona porque se utiliza
en aplicaciones implementadas en versiones anteriores del compilador assembler
incorporadas al IDE MPLABX.
50
La forma correcta de declarar variables es como se muestra a continuación:
CBLOCK 20H
Cont0
Cont1
ENDC
Donde CBLOCK y ENDC son directivas que definen el inicio y fin del bloque de la
definición de las variables. Y 20H es la dirección de la memoria RAM donde comienza la
declaración de las variables Cont0 y Cont1.
o ORG. Es una directiva que hace referencia a una dirección en el área de programa (en la
EEPROM) y no en el área de datos. A partir de este punto, se empieza a insertar las
instrucciones mnemónicas que el compilador deberá convertir en las pertinentes opcode para
el PIC.
ORG 00H
El primer opcode seguido por el PIC después del reset es el almacenado en la localización 0,
correspondiente al valor 00H insertado en la ORG.
o bcf. En este caso la instrucción mnemónica bcf significa BIT CREAR FILE REGISTER, es
decir, pone un 0 (condición lógica baja) uno de los bits contenidos en la localización de la
RAM especificada.
- RPO y RP1 son parámetros que también vienen definidos en el archivo "P17F877.INC"
con los valores 05H y 06H, que corresponden al número del bit que se quiere poner en 1
y 0, respectivamente. Cada file register tiene una longitud de 8 bit y la numeración de
cada uno parte de 0 (bit menos significativo) hasta llegar a 7 (bit más significativo).
Las siguientes instrucciones coloca un 1 en el quinto bit y un 0 en el sexto bit del file register
STATUS, siendo esta operación necesaria para acceder a los file register TRISA y TRISB,
que se encuentran en el banco 1 de la memoria de datos:
bsf STATUS, RP0
bcf STATUS, RP1
o Para utilizar el puerto B del PIC, se haría movlw esta instrucción significa: MOVE
LITERAL TO W REGISTER, es decir mueva un valor constante al acumulador. En este
caso el valor constante de almacenar en el acumulador es 11111110B, es decir, un valor
binario de 8 bits, donde el bit más a la derecha representa el bit 0 o el bit menos significativo.
movlw 11111110B
Luego con la instrucción movwf que significa: MOVE W TO FILE REGISTER, es decir,
mueva el valor del acumulador al registro. En este caso transfiere el valor contenido en el
51
acumulador (inicializado oportunamente con la instrucción movlw 11111110B) al registro
TRISB.
movwf TRISB
- TRISB es un registro que también es definido a través de una directiva EQU, cuya
función es definir el funcionamiento de cada línea de I/O del puerto B. En particular cada
bit con 1 del registro TRISB determina un ingreso en la respectiva línea del puerto B
mientras cada 0 determina una salida.
En la Tabla 2.10 se muestra la configuración que tomarán los pines del puerto B del PIC,
después de la ejecución de esta instrucción.
No. bit registro TRISB Línea puerto B No. Pin Valor Estado
0 RB0 33 0 Output
1 RB1 34 1 Input
2 RB2 35 1 Input
3 RB3 36 1 Input
4 RB4 37 1 Input
5 RB5 38 1 Input
6 RB6 39 1 Input
7 RB7 40 1 Input
Nótese como el valor 0 en el bit 0 del registro TRISB determina la configuración en la salida
de la respectiva línea del PIC. En la aplicación actual esta línea viene utilizada para activar el
LED que va a prender y apagar.
o bcf. Esta instrucción significa BIT CLEAR FILE REGISTER, es decir, encera el bit
indicado por el parámetro. Del punto de vista funcional esta instrucción se escogió para tener
el acceso a los registros internos del banco 0 en vez de los registros internos del
banco 1 de los cuales hacen parte TRISA Y TRISB.
bcf STATUS, RP0
o bsf. Esta instrucción significa BIT SET FILE REGISTER, es decir, setea el bit indicado por
el parámetro. En este caso se tiene acceso al LED conectado a la línea RB0 para ponerle a 1.
52
o MainLoop. Es una label o mejor una referencia simbólica hacia una dirección de memoria.
El valor de la label se calcula en etapa de compilación en base al número de instrucciones, a
las directivas ORG y a las otras instrucciones que de alguna manera ocupan espacio en la
memoria del PIC. En este caso, se cuentan las instrucciones a partir de la última directiva
ORG, y el valor que será asignado a MainLoop es 08H.
En realidad el valor que asumen las label's no tiene mucha importancia, puesto que su
finalidad es de evitar conocer la posición precisa de los opcode en la memoria del PIC,
permitiendo de todas maneras diferenciar una determinada posición de memoria.
En este caso la label MainLoop viene utilizada como punto de inicio de un ciclo (de inglés
loop) de encendido y de apagado del LED, es decir, una parte de código que será repetida
cíclicamente al infinito. Por lo tanto, más adelante se encontrará una referencia a esta label.
MainLoop
o call. Esta instrucción determina una llamada (del inglés call) y una subrutina que empieza en
correspondencia con la label Delay.
Las subrutinas son partes del programa especializadas para efectuar una función específica.
Cada vez que sea necesaria esta función es suficiente llamarla con una sola instrucción, en
vez de repetir cada vez todas las instrucciones necesarias para efectuarla. En este caso la
subrutina introduce un retardo igual al tiempo de encendido y apagado del LED.
Las instrucciones que componen la subrutina Delay son explicadas más adelante.
call Delay
o btfsc. El significado de esta instrucción es BIT TEST FLAG, SKIP IF CLEAR, es decir,
controla el estado de un bit interno de un registro y salta a la instrucción sucesiva si el valor
de tal bit es cero. En este caso, el bit a controlar corresponde a la línea de output (salida) a
que está conectado el LED, por medio de este "test" se puede determinar por lo tanto si el
LED está prendido o apagado, es decir, si el LED está prendido se apagará, si está apagado
se prenderá.
btfsc PORTB,LED
o goto. Esta instrucción es un salto incondicional (del inglés GO TO, ir) a la etiqueta
SetToZero, donde se encontrará las instrucciones para apagar el LED. Esta instrucción será
saltada a la instrucción sucesiva si el LED está ya apagado.
goto SetToZero
o Las dos siguientes instrucciones prenden el LED y reenvían el programa al inicio del ciclo
de prendido y apagado.
bsf PORTB,LED
goto MainLoop
o Las dos siguientes instrucciones apagan el LED y reenvían el programa al inicio del ciclo de
prendido y apagado.
SetToZero
bcf PORTB,LED
53
goto MainLoop
La subrutina Delay
Esta subrutina introduce un retardo de alrededor de un segundo y puede ser llamada todas las
veces en la source, a través de la instrucción call Delay.
En la práctica el retardo viene obtenido siguiendo miles de instrucciones que no hacen nada. Este
tipo de retardo se llama retardo software o retardo a programa. Es el tipo de retardo más simple
de implementar y puede ser utilizado cuando no se necesita que el PIC haga otras tareas mientras
realiza el retardo.
Delay
clrf Cont0
clrf Cont1
DelayLoop
decfsz Cont0,1
goto DelayLoop
decfsz Cont1,1
goto DelayLoop
retlw 0
o Delay y DelayLoop. Son dos etiquetas. Delay identifica la dirección de inicio de la subrutina
y se utiliza para las llamadas del cuerpo principal del programa. DelayLoop se llama
internamente de la subrutina y sirve como punto de ingreso para el ciclo (del inglés loop) de
retardo.
o Las instrucciones:
clrf Cont0
clrf Cont1
clrf. El significado de esta instrucción es CLEAR FILE REGISTER, que encera los dos
sitios de RAM de las direcciones 20H y 21H, referenciada por las label's Cont0 y Cont1.
decfsz Cont0, 1
o goto. Salto incondicional a la etiqueta DelayLoop, que es el principio del ciclo de retardo.
goto DelayLoop
o Una vez alcanzado el cero con el contador Cont0 se ejecutan las instrucciones:
decfsz Cont1,1
goto DelayLoop
54
Que decrecrementa el contador Cont1 hasta que éste también alcance el cero, pero el registro
Cont1 en particular será decrementado en uno cada 256 decrementos de Cont0.
return
4. El circuito en Proteus
C1
22pF
U1 D1
R1
X1 13
OSC1/CLKIN RB0/INT
33
CRYSTAL 14 34 100
OSC2/CLKOUT RB1
35 LED-RED
C2 RB2
2 36
RA0/AN0 RB3/PGM
3 37
RA1/AN1 RB4
4 38
RA2/AN2/VREF-/CVREF RB5
22pF 5 39
RA3/AN3/VREF+ RB6/PGC
6 40
RA4/T0CKI/C1OUT RB7/PGD
7
RA5/AN4/SS/C2OUT
15
RC0/T1OSO/T1CKI
R2 8
RE0/AN5/RD RC1/T1OSI/CCP2
16
4k7 9 17
RE1/AN6/WR RC2/CCP1
10 18
RE2/AN7/CS RC3/SCK/SCL
23
RC4/SDI/SDA
1 24
MCLR/Vpp/THV RC5/SDO
25
RC6/TX/CK
26
RC7/RX/DT
19
RD0/PSP0
20
RD1/PSP1
21
RD2/PSP2
22
RD3/PSP3
27
RD4/PSP4
28
RD5/PSP5
29
RD6/PSP6
30
RD7/PSP7
PIC16F877
55
1. Diagrama de Flujo
INICIO
Shift←0x01
PORTB←Shift
C←0
Shift←Rotar a Izq.
SI
Shift<4>=0
NO
Shift←Intercabia Nibbles
Delay
El Diagrama de Flujo de la subrutina Delay, es la misma que la del ejemplo anterior, del ejemplo
Ejemplo21.asm.
2. Código en Assembler
;**************************************************
; Pic by example
; Ejemplo22.asm
;
; (c) 1999, Sergio Tanzilli (tanzilli@picpoint.com)
; http://www.picpoint.com/picbyexample/index.htm
;**************************************************
PROCESSOR 16F877
RADIX DEC
56
INCLUDE "P16F877.INC"
;Declaracion de Variables
CBLOCK 20H
Cont0
Cont1
Shift
ENDC
;Reset Vector
ORG 00H
;Cambia al banco 1
bsf STATUS,RP0
bcf STATUS,RP1
;Cambia al banco 0
bcf STATUS,RP0
;Inicio programa
MainLoop
movf Shift,W
movwf PORTB
bcf STATUS,C
rlf Shift,F
btfsc Shift,4
swapf Shift,F
call Delay
goto MainLoop
; Subrutinas
;Software Delay
Delay
clrf Cont0
clrf Cont1
DelayLoop
decfsz Cont0,1
goto DelayLoop
decfsz Cont1,1
goto DelayLoop
return
END
57
o Las líneas de I/O utilizadas son RB0 para el primer led, RB1 para el segundo, RB2 para el
tercero y RB3 para el cuarto. Estos serán por lo tanto configurados como salidas al inicio del
programa:
movlw 11110000B
movwf TRISB
los bit menos significativos correspondientes a las líneas RB0,1,2,3 son puestos en cero para
definir las líneas de salida.
o En el área de memoria del REGISTER FILE (que el source inicia con la directiva CBLOCK
20H), se declara las variables que tendrán las siguientes direcciones: Cont0=0x20,
Cont1=0x21 y Shift=0x22.
CBLOCK 20H
Cont0
Cont1
Shift
ENDC
Las variables Cont0 y Cont1 se utilizan en la subrutina Delay, para hacer el retardo
alrededor de un segundo. La variable Shift se utiliza para determinar la secuencia de
encendido de los leds.
o Antes de ejecutar el ciclo principal (label MainLoop) se inicializa el nuevo registro Shift a
00000001B con las siguientes instrucciones:
movlw 00000001B
movwf Shift
o En este punto, en el ciclo principal del programa transfiere el valor almacenado en el registro
Shift al puerto B, obteniendo el encendido del primer led, con las siguientes instrucciones:
movf Shift, W
movwf PORTB
o Luego desplaza el Shift a la izquierda del valor contenido en Shift, con las siguientes
instrucciones:
bcf STATUS, C
rlf Shift, F
La primera instrucción sirve para poner en cero el bit CARRY del REGISTRO DE
ESTADO. La instrucción RLF Rotate Left F through Carry (gira a la izquierda a través del
bit carry desplaza un bit a la izquierda del valor almacenado en el registro Shift,
introduciendo en la posición ocupada por el bit 0 el valor del bit de Carry. Para lograr que el
bit introducido sea siempre cero debe ejecutarse antes de la RLF la instrucción "bcf
STATUS, C" para encerar este bit.
En este punto el registro Shift valdrá 00000010B, por lo tanto, en el ciclo sucesivo, una vez
transferido tal valor al puerto B se obtendrá el apagado del LED1 y el prendido del LED2, y
así sucesivamente para los ciclos siguientes.
58
o Cuando el bit 4 de Shift valga 1, los cuatro bits se han encendido al menos una vez y es
necesario empezar de nuevo desde el LED1. Las siguientes instrucciones desarrollan este
tipo de control:
btfsc Shift, 4
swapf Shift, F
La instrucción "btfsc Shift, 4" controla si el bit 4 del registro Shift vale 1. Si es así, ejecuta la
instrucción "swapf Shift, F", de lo contrario la salta.
La instrucción SWAP (del inglés "cambia") en la práctica cambia los cuatro bit más
significativos contenidos en el registro Shift con los cuatro menos significativos, del valor
inicial del registro Shift igual a 00010000B obtenido después de varias repeticiones del ciclo
MainLoop se obtiene el valor 00000001B, que es en la práctica el reinicio del primer led.
4. El circuito en Proteus
C1
22pF
U1 D1
R1
X1 13
OSC1/CLKIN RB0/INT
33
14 34
CRYSTAL OSC2/CLKOUT RB1
35
100 D2
C2 2
RB2
36
R2 LED-RED
RA0/AN0 RB3/PGM
3 37
4
RA1/AN1 RB4
38
100 D3
22pF 5
RA2/AN2/VREF-/CVREF RB5
39
R3 LED-RED
RA3/AN3/VREF+ RB6/PGC
6 40
7
RA4/T0CKI/C1OUT RB7/PGD 100 D4
RA5/AN4/SS/C2OUT
15
R4 LED-RED
RC0/T1OSO/T1CKI
R5 8
RE0/AN5/RD RC1/T1OSI/CCP2
16 100
4k7 9 17 LED-RED
RE1/AN6/WR RC2/CCP1
10 18
RE2/AN7/CS RC3/SCK/SCL
23
RC4/SDI/SDA
1 24
MCLR/Vpp/THV RC5/SDO
25
RC6/TX/CK
26
RC7/RX/DT
19
RD0/PSP0
20
RD1/PSP1
21
RD2/PSP2
22
RD3/PSP3
27
RD4/PSP4
28
RD5/PSP5
29
RD6/PSP6
30
RD7/PSP7
PIC16F877
1. Análisis matemático
34(D) = 00100010(B)
para lo cual se debe separar los dígitos decimales, mediante la división por 10.
34 10
4 3
Decenas (Cociente) = 3
Unidades (Residuo) = 4
se obtiene:
59
34(D) = 0011 0100 (BCD)
3 4
4 es el residuo
3 cuentas de las restas sucesivas es el cociente
Por último, para cantidades con centenas, se debe tener en cuenta que el contador de las restas
sucesivas debe llegar a 10, que corresponde a una centena y el contador debe inicializarse a cero
para contar las nuevas decenas.
2. Diagrama de Flujo
unidades , en el PORTBL
decenas , en el PORTBH
centenas , en el PORTA
60
INICIO
numero PORTC
decena 0
centena 0
unidad numero
numero numero-10
SI
numero>=10
NO
NO
decena=10
FIN
SI
decena 0
centena centena+1
Para implementar la aplicación en assembler a partir del Diagrama de Flujo se debe tener en
cuenta las siguientes "condiciones":
La resta es similar a la suma, con el contenido del registro W actúa como sustraendo y, el
operando como minuendo. Igualmente hay que apreciar que el flag CARRY se debe
interpretar de forma inversa a como se hace con la suma (a "0" hay pedido).
Si Z=1, decena=10, y
Si Z=0, decena<>10
3. Código en Assembler
61
;Configuration de los flags del PIC
;XT oscillator
;Disable watch dog timer
;Enable power up timer
;Disable code protect
;Declaración de Variables
CBLOCK 20H
numero
unidad
decena
centena
ENDC
;Reset Vector
ORG 00H
movlw 11111111B
movwf TRISC ;Configura el puerto C como entrada
movlw 00000000B
movwf TRISB ;Configura el puerto B como salida
movlw 11110000B
movwf TRISA ;Configura el nible bajo del puerto A como salida
Principal
movf PORTC,W ;Mueve el contenido del puerto C al registro W
movwf numero ;Almacena W en la variable numero
movlw 00000000B
movwf decena ;Encera la variable decena
movwf centena ;Encera la variable centena
repetir
movf numero,0 ;Guarda el valor de numero en unidad
movwf unidad
movlw 10
subwf numero,F ;numero = numero - 10
movlw 10
subwf decena,0
btfss STATUS,Z ;Si decena = 10
goto repetir
movlw 00000000B
movwf decena ;Encera la variable decena
incf centena,F ;Incrementa en 1 la centena
goto repetir
result
swapf decena,0 ;Envia los valores de las decenas y numero al
;puerto B
iorwf unidad,0
movwf PORTB ;Muestra decenas y unidades
END
62
4. El circuito en Proteus
C1
22pF
U1 D1
R1
X1 13
OSC1/CLKIN RB0/INT
33
14 34
CRYSTAL OSC2/CLKOUT RB1
35
100 D2
C2 2
RB2
36
R2 LED-RED
RA0/AN0 RB3/PGM
3 37
4
RA1/AN1 RB4
38
100 D3
22pF 5
RA2/AN2/VREF-/CVREF RB5
39
R3 LED-RED
RA3/AN3/VREF+ RB6/PGC
6 40
7
RA4/T0CKI/C1OUT RB7/PGD 100 D4
RA5/AN4/SS/C2OUT
15
R4 LED-RED
RC0/T1OSO/T1CKI
R5 8
RE0/AN5/RD RC1/T1OSI/CCP2
16 100 D5
9 17
4k7
10
RE1/AN6/WR RC2/CCP1
18
R6 LED-RED
RE2/AN7/CS RC3/SCK/SCL
23
1
RC4/SDI/SDA
24
100 D6
MCLR/Vpp/THV RC5/SDO
25
R7 LED-RED
RC6/TX/CK
26
RC7/RX/DT 100 D7
19
R8 LED-RED
RD0/PSP0
20
RD1/PSP1
21
100 D8
RD2/PSP2
22
R9 LED-RED
RD3/PSP3
27 100
RD4/PSP4
28 LED-RED
RD5/PSP5
29
RD6/PSP6
30
RD7/PSP7
PIC16F877
63