DESCRIPCIÓN GENERAL DEL PIC 16F877
1
2.1. Características relevantes del PIC16F877 2.1.1. Introducción Microchip ha dividido sus microcontroladores en cuatro grandes subfamilias (gamas) de acuerdo al número de bits de su bus de instrucciones, como se indica en la Tabla 2.1. Tabla 2.1. Gamas de los PIC's de acuerdo al número de bits de su bus de instrucciones Gama
Instrucciones 33 instrucciones de 12 bits o 35 instrucciones de 14 bits
Enana Base - Line
33 instrucciones de12 bits
Mid - Range High - End
35 instrucciones de 14 bits 58 y 80 instrucciones de 16 bits
Nomenclatura PIC12C508 y PIC12C509 PIC12XXX, PIC14XXX y PIC16C5X PIC16XXX PIC17XXX y PIC18XXX
1. Variantes principales de los PIC's Los microcontroladores que produce Microchip cubren un amplio rango de dispositivos cuyas características pueden variar como sigue:
Empaquetado (desde 8 pines hasta 80 pines) Tecnología de la memoria incluida (EEPROM, ROM, Flash) Voltajes de operación (desde 2.5 V. Hasta 6V) Frecuencia de operación (Hasta 48 Mhz)
2. Nomenclatura de los PIC's En el nombre específico del microcontrolador pueden aparecer algunas siglas que dependen del rango de voltaje manejado y del tipo de memoria ROM incluida, como se muestra en la Tabla 2.2. Tabla 2.2. Nombre del microcontrolador en base al rango de voltaje manejado y del tipo de memoria ROM incluida Tipo de memoria
Rango de voltaje Estándar (4.5 a 6 volts)
Extendido (2.5 a 6 volts)
EEPROM, OTP
PIC16CXXX
PIC16LCXXX
ROM
PIC16CRXXX
PIC16LCRXXX
Flash
PIC16FXXX
PIC16LFXXX
2.1.2. La Familia del PIC16F877 El microcontrolador PIC16F877 de Microchip pertenece a una gran familia de microcontroladores de 8 bits (bus de datos) que tienen las siguientes características generales que los distinguen de otras familias: - Arquitectura Harvard del Microcontrolador - Tecnología RISC de la CPU - Tecnología CMOS 2
Estas características se conjugan para lograr un dispositivo altamente eficiente en el uso de la memoria de datos y programa, y por lo tanto en la velocidad de ejecución. 2.1.2.1. Empaquetados de los PIC's Aunque cada empaquetado tiene variantes, especialmente en lo relativo a las dimensiones del espesor del paquete, en general se pueden encontrar paquetes tipo PDIP (Plastic Dual In Line Package), PLCC (Plastic Leaded Chip Carrier), QFP (Quad Flat Package) y SOIC (Small Outline I.C.); los cuales se muestran en las Figura 2.1.
Figura 2.1. Tipos de empaquetados de los PIC's En la Figuras 2.2 se muestra algunos empaquetados de Circuito Integrado de los PIC's.
3
Figura 2.2. Algunos empaquetados de Circuito Integrado del PIC16F877 En la Figura 2.3 se muestra la numeración de los pines en diferentes empaquetados
Figura 2.3. Numeración de los pines en diferentes empaquetados 2.1.2.2. Configuration word (2007H) La palabra de configuración (configuration word) selecciona las distintas configuraciones del microcontrolador, la cual está ubicada en la dirección de memoria 2007h, esta dirección de memoria está más allá de la memoria de programa de usuario. De hecho, pertenece al espacio de memoria de test/configuración (2000h - 3FFFh), a la que solo puede accederse durante la programación. En la Figura 2.4 se muestra la palabra de configuración 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
Figura 2.4. Palabra de configuración del PIC16F877 NOTA: El carácter # indica que la señal digital se activa en bajo. 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. 1. Configuración del Oscilador En algunos de los modos de configuración, el usuario puede indicar que se genere o no una salida del oscilador (CLKOUT) a través de un pin de Entrada/Salida. Los modos de configuración del oscilador para la operación del microcontrolador, se muestran en la Tabla 2.3. Tabla 2.3. Modos de configuración del oscilador para la operación del microcontrolador FOSC1
FOSC0
0
0
0
1
1
0
1
1
Modo de operación del oscilador LP Baja frecuencia (y bajo consumo de potencia) Cristal/Resonador cerámico, externos XT Media frecuencia (y medio consumo de potencia) Cristal/Resonador cerámico, externos HS Alta frecuencia o velocidad (y alto consumo de potencia) Cristal/Resonador cerámico, externos RC Resistencia/Capacitor externos
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 b. Circuito RC externo: En los modos RC y EXTRC el PIC puede generar su señal oscilatoria basada en un arreglo RC externo conectado a la patita OSC1, como se muestra en la Figura 2.6.
Figura 2.6. Conexión de un circuito RC externo Este modo sólo se recomienda cuando la aplicación no requiera una gran precisión en la medición de tiempos. Rangos de las resistencias y capacitores. La frecuencia de oscilación depende no sólo de los valores de Rext y Cext, sino también del voltaje de la fuente Vdd. Los rangos admisibles para resistencia y capacitor son: I. II.
Rext: de 3 a 100 Kohms Cext: mayor de 20 pF
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. Calibración del oscilador interno. El fabricante ha colocado un valor de calibración para estos bits en la última dirección de la memoria de programa. Este dato ha sido guardado en la forma de una instrucción RETLW XX. Si no se quiere perder este valor al borrar el PIC (en versiones EPROM con ventana) primero se deberá leer y copiar. Es una buena idea escribirlo en el empaquetado antes de borrar la memoria. 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. Conexión del Cristal o Resonador en modo (HS, XT o LP)
Oscilador en modo RC
Conexión de Oscilador externo en modo (HS, XT o LP)
Figura 2.8. Modos de configuración del oscilador principal del sistema. 3. Rangos de Frecuencia para los Osciladores 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 Modo LP XT
HS
Frecuencia típica
Capacitores recomendados C1
C2
32 khz
33 a 68 pf
33 a 68 pf
200 khz
15 a 30 pf
15 a 30 pf
200 khz
47 a 68 pf
47 a 68 pf
1 Mhz
15 a 30 pf
15 a 30 pf
4 Mhz
15 a 30 pf
15 a 30 pf
4 Mhz
15 a 30 pf
15 a 30 pf
8 Mhz
15 a 30 pf
15 a 30 pf
20 Mhz
15 a 30 pf
15 a 30 pf
En la Figura 2.9 se indica los valores de los Resonadores Cerámicos y Condensadores para cristales, necesarios a instalar entre la masa y lis piness de los cristales y/o resonadores. Resonadores Cerámicos
Condensadores para cristales
Figura 2.9. Valores de los Resonadores Cerámicos y Condensadores para cristales 2.1.2.4. El Reset En estos circuitos hay seis formas de que se produzca un Reset: 1. 2. 3. 4. 5. 6.
Power-On Reset (POR) #MCLR reset durante una operación normal Brown-Out Reset (BOR) #MCLR reset durante Sleep WDT reset durante una operación normal WDT por despertar de Sleep
NOTA: El carácter # indica que la señal digital se activa en bajo. 8
1. Reset con POR (Power-On 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. El impulso de inicialización POR es generado internamente cuando la tensión de alimentación se encuentra entre los límites de 1,2 V y 1,7 V, es un método cómodo de originar un Reset al conectar la alimentación, ya que no requiere de ningún componente adicional pero no siempre es el método ideal para realizarlo, en muchas ocasiones se necesita que éste se produzca a una tensión superior. 2. Reset con #MCLR durante una operación normal 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.
En este circuito cuando VDD desciende por En este circuito el transistor Q1 se debajo del valor VZ = +0,7V, se produce un bloquea y activa el Reset al pasar a nivel Reset por la activación de patilla MCLR#. bajo la patilla MCLR#, cuando el valor de VDD desciende por debajo de :
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. 3. Reset con BOR (Brown- Out Reset) 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. 4, 5 y 6. El resto de formas para producir un Reset El resto de formas para producir un Reset se analizará en los respectivos temas. Diagrama de bloques del circuito de Reset dentro del chip 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 2.1.3. Características generales del PIC16F877 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. Tabla 2.5. Periféricos del PIC16F877 y los dispositivos más cercanos Periférico 3 a 5 Puertos Paralelos
3 Timers
2 módulos CCP 1 Conversor A/D Puertos Serie Puerto Paralelo Esclavo
PIC16F873 PIC16F876
PIC16F874 PIC16F877
PortA,B,C
PortA,B,C,D,E
Timer0
Timer0
Timer1
Timer1
Timer2
Timer2
Captura Comparación PWM
Captura Comparación PWM
AN0,...,AN4
AN0,...,AN7
de 10 bits, hasta 8 canales
SSP USART/SCI
SSP USART/SCI
ICSP
ICSP
Puerto Serie Síncrono Puerto Serie Universal Puerto serie para programación y depuración “in circuit”
PSP
PSP
Características con líneas digitales programables individualmente Contador/Temporizador de 8 bits con preescalador de 8 bits Contador/Temporizador de 16 bits con preescalador Temporizador de 8 bits con pre-escalador y post- escalador de 8 bits y registro de periodo 16 bits, 1.5 nseg de resolución máxima 16 bits, 200 nseg de resolución máxima 10 bits
Puerto de 8 bits con líneas de protocolo
2.1.4. Diagrama de Bloques del PIC16F877 En la Figura 2.12 se muestra el diagrama de pines y el diagrama de bloques de la organización interna del PIC16F877, para tener una visión conjunta del exterior e interior del Chip.
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 La CPU es la responsable de la interpretación y ejecución de la información (instrucciones) guardada en la memoria de programa. Muchas de estas instrucciones operan sobre la memoria de datos. Para operar sobre la memoria de datos, además, si se van a realizar operaciones lógicas o aritméticas, requieren usar la Unidad de Lógica y Aritmética (ALU). La ALU controla los bits de estado (Registro STATUS), los bits de este registro se alteran dependiendo del resultado de algunas instrucciones. 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.
Figura 2.13. Ciclo de instrucción 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: Q1: Decodificación de la instrucción Q2: Lectura del dato (si lo hay) Q3: Procesa el dato Q4: Escribe el dato 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. 2. Algunos Registros de la CPU •
Registro PC. Registro de 13 bits que siempre apunta a la siguiente instrucción a ejecutarse. En el siguiente subtema se dan mayores detalles en el manejo de este registro. 14
El PC consta de 13 bits, separados en dos partes PCH y PCL: como se muestra en la Figura 2.14.
Figura 2.14. Registro PC separados en dos partes PCH y PCL Donde: - PCL = El byte de orden bajo - PCH = El byte de orden alto •
Registro de Instrucción. Registro de 14 bits. Todas las instrucciones se colocan en él para ser decodificadas por la CPU antes de ejecutarlas.
•
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 IRP Bit 7
R/W-0 RP1 6
R/W-0 RP0 5
R-1 #T0 4
R-1 #PD 3
R/W-x Z 2
R/W-x DC 1
R/W-x C Bit 0
Figura 2.15. Registro de STATUS (Direcciones 03h, 83h, 103h, 183h) A continuación se describe los bits del Registro de STATUS:
bit 7: IRP: Selección de bancos para el direccionamiento indirecto 1 = Bancos 2 y 3 (100h-1FFh) 0 = Bancos 0 y 1 (00h-FFh) bit 6-5: RP1:RP0: Selección del banco para el direccionamiento directo 11 = Banco 3 (180h- 1FFh) 10 = Banco 2(100h-17Fh) 01 = Banco 1 (80h-FFh) 00 = Banco 0 (00h-7Fh) Cada Banco es de 128 bytes bit 4:#T0: Flag de Timer Out 1 = Después de conectar VDD o ejecutar CLRWDT o SLEEP 0 = Al desbordarse el temporizador de WDT bit 3:#PD:Flag de Power Down 1 = Después de conectar VDD o al ejecutar la instrucción CLRWDT 0 = Al ejecutar la instrucción SLEEP 15
bit 2: Z: Flag de Cero 1 = El resultado de la última operación aritmética o lógica es Cero 0 = El resultado de la última operación aritmética o lógica es distinto cero bit 1: DC: Flag de acarreo en el 4º bit de menos peso 1 = Acarreo en la suma 0 = No acarreo en la suma En la resta es al contrario bit 0: C: Flag de acarreo en el octavo bit 1 = Se ha producido un acarreo en la suma y no en la resta 0 = Se ha producido un acarreo en la resta y no en la suma Este bit también se utiliza en las instrucciones de rotación
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
Banderas del Registro STATUS -
Z. Este bit se pone en 1 para indicar que el resultado de la última operación aritmética o lógica fue cero, de lo contrario se pone en 0.
-
C. Bit de acarreo/préstamo de la última operación aritmética, en el caso de préstamo (resta), el bit se invierte antes de guardarse.
-
DC. Acarreo/préstamo proveniente del cuarto bit menos significativo. Funciona igual que el bit C, pero para operaciones de 4 bits.
Las restas se realizan sumando el complemento a dos del segundo operando, por ejemplo, para los datos 4FH y 25H:
2.1.6. Conjunto de Instrucciones de Rango o Gama Media 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
A continuación se realiza la Descripción de algunas instrucciones y Formato General de las Instrucciones; 17
1. Descripción de algunas instrucciones Para obtener la descripción detallada de cada instrucción de la T abla 2.6 se deberá consultar la sección 29 del manual del fabricante (PICmicro Mid-Range MCU Reference Manual) o el ANEXO 1 de este documento. A continuación sólo se ejemplificarán algunas instrucciones con el propósito de clarificar la operación que realizan. Ejemplo 1 Para realizar la suma y la resta mencionadas en el subtema anterior (4Fh+25h y 4Fh-25h) se pueden usar las siguientes instrucciones. Suma
MOVLW 0x4F ADDLW 0x25
; Carga el primer sumando en W que es 0x4F ; Suma W + 25h y guarda el resultado en W
MOVLW 0x25 SUBLW 0x4F
; Carga el sustraendo en W 0x25 ; Resta 4Fh - W y guarda el resultado en W
... Resta
Ejemplo 2 En este ejemplo se ejemplifica el efecto de algunas instrucciones sobre el registro W, y sobre el registro de propósito general 20h de la memoria RAM. Inicio
MOVLW 0xF4 ADDLW 0x0B MOVWF 0X20 INCF 0x20,1 INCF 0X20,0 COMF 0X20,1 XORWF 0x20,1 MOVF 0x20,0
;W=F4h, ;W=FFh, ;W=FFh, ;W=FFh, ;W=01h, ;W=01h, ;W=01h, ;W=FEh,
0x20= ??, 0x20= ??, 0x20=FFh, 0X20=00h, 0x20=00h, 0x20=FFh, 0x20=FEh, 0x20=FEh,
C=?, C=0, C=0, C=0, C=0, C=0, C=0, C=0,
DC=?, DC=0, DC=0, DC=0, DC=0, DC=0, DC=0, DC=0,
;(El ensamblador permite escribir esta última como DECF 0x20,1 ;W=FEh, 0x20=FDh, C=0, DC=0, ANDWF 0x20,1 ;W=FEh, 0x20=FCh, C=0, DC=0, RLF 0x20,1 ;W=FEh, 0x20=F8h, C=1, DC=0, SWAPF 0x20,1 ;W=FEh, 0x20=8Fh, C=1, DC=0, BCF 0x20,3 ;W=FEh, 0x20=87h, C=1, DC=0, BSF 0x20,5 ;W=FEh, 0x20=A7h, C=1, DC=0,
Z=? Z=0 Z=0 Z=1 Z=0 Z=0 Z=0 Z=0 MOVFW 0x20) Z=0 Z=0 Z=0 Z=0 Z=0 Z=0
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. 2. Formato General de las Instrucciones. 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: a. Operaciones con el archivo de registros orientados a bytes
El bit d especifica el destino del resultado de la operación: 18
d = 0: destino W d = 1: destino f f = dirección de 7 bits del archivo de registros. b. Operaciones con el archivo de registros orientados a bits
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. c. Operaciones con literales y de control Formato para literales:
k : Literal = Valor de un operando de 8 bits Formato para CALL y GOTO:
k : Literal = Valor de un operando de 8 bits 2.1.7. Organización de la memoria del PIC 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. La Memoria de datos a su vez se divide en: -
Memoria RAM de propósito general Memoria RAM de Registros de Propósito Especial (Special Function Registers (SFR)) El tercer bloque de la Memoria de datos es la EEPROM.
2.1.7.1. La Memoria de Programa 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. El bloque total de 8K palabras x 14 bits de memoria de programa está subdividido en 4 páginas de 2Kx14. En la Figura 2.16 se muestra esta organización. 19
Figura 2.16. Organización de la Memoria de Programa Observación1: No todos los PIC's tienen implementado todo el espacio d e 8K de memoria de programa (Consultar las hojas de datos del PIC específico). Observación2: El fabricante puede grabar datos de calibración en localidades de memoria de programa por lo que se deberán anotar en papel antes de borrar los dispositivos con ventana transparente. 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 Cuando la CPU acepta una solicitud de interrupción ejecuta un salto a la dirección 0004h, por lo cual a ésta se le conoce como "dirección del vector de interrupción". El programador deberá colocar en esta dirección la Rutina de Atención a la Interrupción (Interrupt Service Routine (ISR)) o bien un salto al inicio de ella. 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. 3. Manejo del Contador del Programa (PC) 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.
Figura 17. Registro Contador del Programa (PC) 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. En la Figura 2.18 se ilustran las cuatro situaciones y las maneras correspondientes en que el PC puede ser actualizado.
Figura 2.18. Maneras en que el PC puede ser actualizado. 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. Si las instrucciones se ejecutan secuencialmente el PC cruza libremente los límites de página sin necesidad de que el usuario escriba en el PCLATH 5. Memoria de Stack La memoria de stack es un área de memoria completamente separada de la memoria de datos y la memoria de programa. El stack consta de 8 niveles de 13 bits cada uno. Esta memoria es usada por la CPU para almacenar las direcciones de retorno de subrutinas. El apuntador de stack no es ni leíble ni escribible. El vector de Reset está en la posición de memoria 0000h y el vector de interrupción está en la posición de memoria 0004h. En la Figura 2.19 se muestra el Mapa de Memoria y STACK del PIC16F877/878.
Figura 2.19. Mapa de Memoria y STACK del PIC16F877/878. Cuando se ejecuta una instrucción CALL o es reconocida una interrupción el PC es guardado en el stack y el apuntador de stack es incrementado en 1 para apuntar a la siguiente posición vacía. A la inversa, cuando se ejecuta una instrucción RETURN, RETLW o RETFIE el contenido de la posición actual del stack es colocado en el PC y el apuntador de stack es decrementado en 1. Nota 1: PCLATH no se modifica en ninguna de estas operaciones Nota 2: Cuando el apuntador de stack ya está en la posición 8 (se llamaron desde 8 subrutinas anidadas) y se ejecuta otro CALL se reinicia a la posición 1 sobrescribiendo 22
en dicha posición. No existe ningún indicador que avise de esta situación. Así que el usuario deberá llevar el control para que esto no ocurra este inconveniente. 2.1.7.2. La Memoria de Datos La memoria de datos RAM consta de dos áreas mezcladas y destinadas a funciones distintas: • •
Registros de Propósito Especial (SFR) Registro de Propósito General (GPR)
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. A continuación se va a describir Bancos de memoria, Registros de Funciones Especiales (FSR), Direccionamiento Directo y Direccionamiento Indirecto, Registros de la memoria RAM: 1. Bancos de memoria Toda la memoria de datos está organizada en 4 bancos numerados 0, 1, 2 y 3. Para seleccionar un banco se debe hacer uso de los bits del registro STATUS<7:5> denominados IRP, RP1 y RP0. Hay dos maneras de acceder a la memoria de datos: Direccionamiento directo e ndirecto. La selección de bancos se basa en la Tabla 2.7, selección de los bancos de memoria RAM con RP0 y RP1: Direccionamiento Indirecto (IRP) 0 1
RP1:RP0 0 0 1 1
0 1 0 1
Banco 0 1 2 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. 2. Registros de Funciones Especiales (FSR) 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. Los Registros de Función Especiales podemos clasificarlos en dos tipos:
Los correspondientes a la CPU, y Los que controlan los periféricos. 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 Para acceder una posición de memoria mediante direccionamiento directo, la CPU simplemente usa la dirección indicada en los 7 bits menos significativos del código de operación y la selección de banco de los bits RP1:RP0, como se ilustra en la Figura 2.20.
Figura 2.20. Acceso a una posición de memoria mediante direccionamiento directo e indirecto 4. Direccionamiento indirecto Este modo de direccionamiento permite acceder una localidad de memoria de datos usando una dirección de memoria variable a diferencia del direccionamiento directo, en que la dirección es fija. Esto puede ser útil para el manejo de tablas de datos. El registro INDF. Sirve para hacer posible el direccionamiento indirecto. Cualquier instrucción que haga un acceso al registro INDF en realidad accede a la dirección apuntada por el registro FSR (File Select Register). En la Figura 2.20 se muestra la manera en que esto se realiza. La selección de banco en el caso de direccionamiento indirecto se realiza mediante los bits IRP (STATUS<7>) y el bit 7 del registro FSR, como se muestra en la figura 2.20. 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 MOVLW 0X20 MOVWF FSR
; Selecciona Banco cero ; Carga valor de apuntador a RAM ; Inicializa apuntador
24
Sigue
CLRF INDF INCF FSR,F BTFSS FSR,4 GOTO sigue
; ; ; ;
Limpia localidad apuntada por FSR Incrementa apuntador Si ya terminó escapa a continuar 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 … BSF STATUS,5 … BSF STATUS,6 … BCF STATUS,5 …
; Limpia registro STATUS (Banco 0) ; RP0=1, (Banco 1) ; RP1=1, (Banco 3) ; RP0=0, (Banco 2)
5. El Archivo de Registros de la memoria RAM 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.
Figura 2.21. El Archivo de Registros de la memoria RAM 25
Cada uno de los registros de propósito especial, está asociado a un dispositivo interno del microcontrolador. En el siguiente tema se tratará con detalle el uso de cada uno de estos dispositivos y de los registros asociados a él.
26
2.2. Programación del PIC16F877 en Assembler 2.2.1. Palabra de Configuración (FUSES) 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
Figura 2.22. Palabra de Configuración (FUSES) del PIC16F877 2.2.1.1. Configuración de los Bits Los bits de la configuración pueden ponerse a 0 o a 1 para seleccionar las distintas configuraciones del dispositivo, por lo que se puede seleccionar varias configuraciones del dispositivo. Estos bits se graban en la posición de memoria situada en la dirección 2007h, Esta dirección de memoria está más allá de la memoria de programa de usuario. De hecho, pertenece al espacio de memoria de test/configuración (2000h - 3FFFh), a la que solo puede accederse durante la programación.
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) bit 11: DEBUG: Modo In-Circuit Debugger 1 = Deshabilitado modo In-Circuit Debugger, RB6 y, RB7 serán patillas de entrda/salida 0 = Habilitado modo In-Circuit Debugger, RB6 y RB7 dedicadas al debugger bit 10: Sin implementar: En lectura es "1" bit 9:
WRT: Habilita escritura en memoria Flash de programa 1 = Sin protección, se puede escribir con el control ECON. 0 = Sin protección, no se puede escribir con el control EECON
bit 8:
CPD: Protección de los datos de la memoria EEPROM 1 = Sin protección 0 = Datos de la EEPRON protegidos
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
bit 6:
BODEN: Bit de habilitación Brown-out Reset (1) 1 = BOR habilitado 0 = BOR deshabilitado
bit 3:
PWRTE: Bit de habilitación del temporizador Power-up (1) 1 = PWRT deshabilitado 0 = PWRT habilitado
bit 2:
WDTE: Bit de habilitación Watchdog 1 = WDT habilitado 0 = WDT deshabilitado
bit 1-0: FOSC1:FOSC0: Bit de selección del oscilador 11 = Oscilador RC 10 = Oscilador HS 01 = Oscilador XT 00 = Oscilador LP
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.
A continuación se describen cada uno de los bits de la Palabra de Configuración (FUSES): CP1-CP0: Código de protección de Memoria de Programa. Si no están activos cualquiera puede leer el programa que se graba en la memoria. Se suele activar solo cuando una aplicación final que se desea vender y no se quiere que lean el 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 el programa se accede a la memoria de datos EEPROM. CPD: Código de Protección de la Memoria EEPROM de Datos. Es como el 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 la aplicación. 28
WDTE: Bit de Permiso del Timer del Perro Guardián. Se activa cuando se usa el Perro Guardián o WDT en las aplicaciones, se verá más adelante. 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.2.1.2. Establecimiento de la palabra de configuración La palabra de configuración de los bits de la palabra de configuración (FUSES) se puede establecer de las dos siguientes formas: 1. Desde el programa de grabación, o 2. En el código de programa 1.
Desde el programa de grabación. Por ejemplo en el WinPIC800 para el caso del PIC16F877A se configura como se muestra en la Figura 2.23.
Figura 2.23. Establecimiento de la palabra de configuración desde el programa de grabación 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
__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. A continuación se indica los bits de configuración que se debe agregar al código de programa: 29
;========================================================================== ; ; Configuration Bits ; ;========================================================================== _CP_ALL _CP_HALF _CP_UPPER_256 _CP_OFF _DEBUG_ON _DEBUG_OFF _WRT_ENABLE_ON _WRT_ENABLE_OFF _CPD_ON _CPD_OFF _LVP_ON _LVP_OFF _BODEN_ON _BODEN_OFF _PWRTE_OFF _PWRTE_ON _WDT_ON _WDT_OFF _LP_OSC _XT_OSC _HS_OSC _RC_OSC
EQU H'0FCF' EQU H'1FDF' EQU H'2FEF' EQU H'3FFF' EQU H'37FF' EQU H'3FFF' EQU H'3FFF' EQU H'3DFF' EQU H'3EFF' EQU H'3FFF' EQU H'3FFF' EQU H'3F7F' EQU H'3FFF' EQU H'3FBF' EQU H'3FFF' EQU H'3FF7' EQU H'3FFF' EQU H'3FFB' EQU H'3FFC' EQU H'3FFD' EQU H'3FFE' EQU H'3FFF'
Por ejemplo: Para configurar el microcontrolador 16F877, previamente se debe establecer la palabra de configuración, como se muestra a continuación. PROCESSOR INCLUDE
16F877 "P16F877.INC"
;LIST P=16F877 ;# INCLUDE "P16F877.INC"
;Setup of PIC configuration flags ;XT oscillator, OSC: XT ;Disable watch dog timer, WDT: OFF ;Enable power up timer, PWRTE: ON ;Disable code protect, CP: OFF __CONFIG
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
Algunos FUSES que son comunes a todos los PICS, se muestran a continuación: WDT_ON WDT_OFF HS_OSC XT_OSC LP_OSC PWRTE_ON PWRTE_OFF
Enable the internal Watchdog timer. Disable the internal Watchdog timer. Use a High-speed crystal (Xtals over 4MHz). Use a standard crystal (4MHz or under). Use a low frequency crystal (KHz range). Enable power up timer. Disable power up timer.
2.2.2. Resumen de las Directivas del Ensamblador MPASM ©ATE-Uniovi 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: Tabla 2.8. Resumen directivas del ensamblador MPASM Directivas para carga o reserva en la Memoria de Programa DATA
Inicializa una o más palabras de la memoria de programa con datos o cadenas de caracteres.
30
DATA 0x012, 0x1345 DATA "Prueba 1,2,3" Almacena en paquetes de 14 bits dos caracteres ASCII representados con 7 bits. DA DA "abcdef" Reserva e inicializa bytes en la memoria de programa. DB DB 'T', 0xF0, 'S' Reserva e inicializa palabras en la memoria de programa. DW DW 0x39, 0x45B
DT
Genera una serie de instrucciones RETLW, una por cada expresión que acompaña a la directiva. DT 1, 2, 3, 5, 7
DE
Reserva y carga posiciones de la memoria de programa con bytes, en principio estaba pensada para rellenar la EEPROM de datos (empieza en la 0x2100), pero se puede emplear para cualquier posición de memoria de programa. ORG 0x2100 DE "Programa version 1.0"
FILL
Rellena un número de posiciones de memoria de programa con un mismo contenido (dato o instrucción si va entre paréntesis). FILL 0x190F, 5
RES
Reserva un determinado número de posiciones de la memoria de programa (avanza el puntero de cuenta de posición en la memoria de programa). RES 64 Carga la palabra de configuración del microcontrolador, previamente se debe haber declarado el microcontrolador.
__CONFIG __CONFIG Se emplea para cargar las 4 posiciones de identificación del microcontrolador. Se debe haber declarado previamente el microcontrolador. __IDLOCS __IDLOCS 1234 Directivas de Control Se emplean para declarar inicio y final de un bloque de constantes. Se asignan valores correlativos. CBLOCK ENDC
CONSTANT EQU
CBLOCK 0x20 A, B, C, D ENDC
;A = 0x20, B=0x21, C=0x22, D=0x23
Las dos se emplean para asignar expresiones a símbolos, esos símbolos no pueden luego cambiar de valor (son constantes). Sintaxis distinta, pero igual efecto. CONSTANT longitud=0x10
31
longitud EQU 0x10
VARIABLE SET
#DEFINE
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 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 bit_0 STATUS,RP0 Anula una asignación previa realizada con #DEFINE.
#UNDEFINE #UNDEFINE bit_0
ORG
Sitúa el código que se vaya generando después, a partir de la posición especificada. ORG 0x100 Final de código fuente.
END END Se incluye el archivo especificado, se inserta en la posición y será ensamblado. INCLUDE
INCLUDE "c:\mplab\P16F84A.INC" INCLUDE Se especifica el RADIX que se está usando.
RADIX RADIX dec
;pueden ser también hex u oct
Define el tipo de microcontrolador. PROCESSOR PROCESSOR 16F877A Para controlar la generación del archivo de listado (.LST) TITLE SUBTITLE
Título en la cabecera de las páginas. Subtítulo (segunda línea) en cabecera.
SPACE
Inserta líneas en blanco.
PAGE
Inserta salto de página.
LIST
Habilita listado y opciones del mismo.
NOLIST
Deshabilita generación en archivo .LST
MESSG
Saca mensajes en el archivo .LST
ERROR
También para sacar mensajes en .LST Especifica tipos de mensajes que aparecerán en archivo .LST
ERRORLEVEL
ERRORLEVEL 0 ERRORLEVEL 1 ERRORLEVEL 2
;Errores, warnings y mensajes ;Warnings y errores ;Errores
Directivas de Ensamblado condicional
32
Grupo de directivas para ensamblar instrucciones si es cierta o no una expresión.
IF ELSE ENDIF
IF versión==1 MOVLW 0x0A ;Esto se ensambla si expresión es cierta o distinta de 0 MOVWF PORTB ENDIF IF expresión ;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 Puede sustituir a la IF. Se ensambla si está definida la etiqueta.
IFDEF
IFNDEF
#DEFINE DE_B_a_A 1 IFDEF DE_B_a_A MOVF PORTB,w MOVWF PORTA ELSE MOVF PORTA,W MOVWF PORTB ENDIF Puede sustituir a las dos directivas anteriores IF e IFDEF. Se ensambla si no está definida la etiqueta Grupo de instrucciones y directivas que se ensamblan mientras la expresión sea cierta.
WHILE ENDW
VARIABLE i i=0 WHILE i < CONTADOR RETLW i i+=1 ENDW Macros Una macro es un conjunto de instrucciones que pueden ser insertadas en el código fuente mediante una simple llamada a macro. Una macro debe ser definida primero antes de poder ser llamada en el código fuente siguiente. Una macro puede llamar a otra macro o a sí misma de manera recursiva
MACRO EXITM ENDM
Definición de una macro: Etiqueta MACRO argumento1, arguento2, argumento3, ... Conjunto de Instrucciones EXITM (salida intermedia opcional) Más instrucciones ENDM Utilización de una macro: 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. 2.2.3. Tipos de datos para los PIC's en MPASM La convención utilizada por MPASM es la siguiente: -
Hexadecimal. Es la numeración por defecto, para mayor claridad para el programador se utiliza una letra H al final del número, así: 0100H; o al inicio del número de la siguiente forma: H'0100'. También se utiliza la notación del lenguaje C: 0x0100 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.
-
Octal. Se utiliza la forma O'xxx' (comillas simples), así: O'22', o'15'.
-
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 Tipo
Sintaxis
Ejemplo
Comentario
D''
D'100'
.
.100
H''
H'64'
H puede ser minúscula
xxxxH
0100H
H puede ser minúscula
0x
0x64
D puede ser minúscula
Decimal
Hexadecimal 64 Octal
O'' B''
O'144'
Por defecto O puede ser minúscula
B'01100100' B puede ser minúscula
Binario xxxxxxxxB
01100100B
B puede ser minúscula
A''
A'C'
A puede ser minúscula
''
'C'
ASCII
2.2.4. Escritura y compilación de un programa en assembler 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. Un ejemplo de opcode en notación binaria se muestra a continuación: 00 0001 0000 0000B 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.2.4.1. Convenciones para el programa en assembler 1. La primera convención es aquella de asociar a cada opcode, en total 35 (instrucciones) para él PIC16F87x, una sigla mnemónica, es decir, una sigla que ayude a recordar el significado de la instrucción. Por ejemplo, el opcode 0100H corresponde a la instrucción mnemónica CLRW que es la forma breve de la instrucción CLEAR W REGISTER, es decir, encera el registro W. 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.
Figura 2.24. Esquema del flujo de operaciones del compilador assembler 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
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). 4.
a. Archivos de entrada: 1.
Código fuente (.asm): Archivo fuente de entrada al ensamblador. La primera operación a efectuar es escribir el source assembler y su almacenamiento en un archivo de texto con extensión .ASM, que es el código fuente en una aplicación para el PIC. Para hacer esto es necesario utilizar un editor ASCII, es decir, un programa de escritura como por ejemplo el NOTEPAD.EXE de Windows o el EDIT.EXE de MS/DOS©. Es posible generar este archivo también con programas de elaboración de texto como Word©, teniendo el cuidado de almacenar siempre el archivo producido en formato texto y no en formato nativo. Esto para evitar que se almacenen los caracteres de control de formateo del texto que el compilador assembler no está en grado de tratar. En el código fuente cada línea puede contener cuatro tipos de información:
Etiquetas Operación, Mnemónicos (instrucciones), Directivas y Macros Operandos Comentarios
El orden y posición de éstos es importantes, por lo que se recomienda que la etiqueta se coloque en la primera columna y que los mnemónicos se coloquen una o dos columnas más allá, los operandos siguen al código mnemotécnico, y los comentarios pueden seguir a los operandos, mnemónicos o etiquetas, y pueden comenzar en cualquier columna. La anchura de columna máxima es de 255 caracteres. Esta distribución sirve para facilitar la depuración. Un espacio en blanco debe separar la etiqueta del código mnemotécnico, y también un espacio en blanco debe separar el código mnemotécnico y los operandos, y los operandos múltiples deben separarse por comas. 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. En la Figura 2.25 se muestra un esquema de un programa en assembler para indicar la forma de utilizar lo descrito anteriormente y las partes que constituyen dicho programa:
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.
-
Mnemónicos, directivas y macros 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.
2.
Archivo include (.inc): Archivo de inclusión o cabecera. 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. Como ejemplo, para añadir el archivo de cabecera para el dispositivo PIC18F877 en el código ensamblador del programa, se hará: #include p18f877.inc
En este caso el archivo P16F877.INC se muestra a continuación: LIST ; P16F877.INC Standard Header File, Version 1.00 NOLIST
Microchip Technology, Inc.
; 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. ; Note that the processor must be selected before this file is ; included. The processor may be selected the following ways: ;
1. Command line switch:
39
; ; ; ;
C:\ MPASM MYFILE.ASM /PIC16F877 2. LIST directive in the source file LIST P=PIC16F877 3. Processor Type entry in the MPASM full-screen interface
;========================================================================== ; ; Revision History ; ;========================================================================== ;Rev:
Date:
Reason:
;1.12 ; ;1.00
01/12/00 Changed some bit names, a register name, configuration bits to match datasheet (DS30292B) 08/07/98 Initial Release
;========================================================================== ; ; Verify Processor ; ;========================================================================== IFNDEF __16F877 MESSG "Processor-header file mismatch. Verify selected processor." ENDIF ;========================================================================== ; ; Register Definitions ; ;========================================================================== W F
EQU EQU
H'0000' H'0001'
;----- Register Files-----------------------------------------------------INDF TMR0 PCL STATUS FSR PORTA PORTB PORTC PORTD PORTE PCLATH INTCON PIR1 PIR2 TMR1L TMR1H T1CON TMR2 T2CON SSPBUF SSPCON CCPR1L CCPR1H CCP1CON RCSTA TXREG RCREG CCPR2L CCPR2H CCP2CON ADRESH ADCON0 OPTION_REG TRISA TRISB TRISC TRISD TRISE PIE1
EQU H'0000' EQU H'0001' EQU H'0002' EQU H'0003' EQU H'0004' EQU H'0005' EQU H'0006' EQU H'0007' EQU H'0008' EQU H'0009' EQU H'000A' EQU H'000B' EQU H'000C' EQU H'000D' EQU H'000E' EQU H'000F' EQU H'0010' EQU H'0011' EQU H'0012' EQU H'0013' EQU H'0014' EQU H'0015' EQU H'0016' EQU H'0017' EQU H'0018' EQU H'0019' EQU H'001A' EQU H'001B' EQU H'001C' EQU H'001D' EQU H'001E' EQU H'001F' EQU EQU EQU EQU EQU EQU
EQU H'0081' H'0085' H'0086' H'0087' H'0088' H'0089' H'008C'
40
PIE2 PCON SSPCON2 PR2 SSPADD SSPSTAT TXSTA SPBRG ADRESL ADCON1
EQU H'008D' EQU H'008E' EQU H'0091' EQU H'0092' EQU H'0093' EQU H'0094' EQU H'0098' EQU H'0099' EQU H'009E' EQU H'009F'
EEDATA EEADR EEDATH EEADRH
EQU EQU EQU EQU
H'010C' H'010D' H'010E' H'010F'
EECON1 EECON2
EQU EQU
H'018C' H'018D'
;----- STATUS Bits -------------------------------------------------------IRP RP1 RP0 NOT_TO NOT_PD Z DC C
EQU H'0007' EQU H'0006' EQU H'0005' EQU H'0004' EQU H'0003' EQU H'0002' EQU H'0001' EQU H'0000'
;----- INTCON Bits -------------------------------------------------------GIE PEIE T0IE INTE RBIE T0IF INTF RBIF
EQU EQU EQU EQU EQU EQU EQU EQU
H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- PIR1 Bits ---------------------------------------------------------PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF
EQU EQU EQU EQU EQU EQU EQU EQU
H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- PIR2 Bits ---------------------------------------------------------EEIF BCLIF CCP2IF
EQU EQU EQU
H'0004' H'0003' H'0000'
;----- T1CON Bits --------------------------------------------------------T1CKPS1 T1CKPS0 T1OSCEN NOT_T1SYNC T1INSYNC T1SYNC TMR1CS TMR1ON
EQU EQU EQU EQU EQU EQU EQU EQU
H'0005' H'0004' H'0003' H'0002' H'0002' ; Backward compatibility only H'0002' H'0001' H'0000'
;----- T2CON Bits --------------------------------------------------------TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
EQU EQU EQU EQU EQU EQU EQU
H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
41
;----- SSPCON Bits -------------------------------------------------------WCOL SSPOV SSPEN CKP SSPM3 SSPM2 SSPM1 SSPM0
EQU EQU EQU EQU EQU EQU EQU EQU
H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- CCP1CON Bits ------------------------------------------------------CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0
EQU EQU EQU EQU EQU EQU
H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- RCSTA Bits --------------------------------------------------------SPEN RX9 RC9 NOT_RC8 RC8_9 SREN CREN ADDEN FERR OERR RX9D RCD8
EQU H'0007' EQU H'0006' EQU H'0006' ; Backward compatibility only EQU H'0006' ; Backward compatibility only EQU H'0006' ; Backward compatibility only EQU H'0005' EQU H'0004' EQU H'0003' EQU H'0002' EQU H'0001' EQU H'0000' EQU H'0000' ; Backward compatibility only
;----- CCP2CON Bits ------------------------------------------------------CCP2X CCP2Y CCP2M3 CCP2M2 CCP2M1 CCP2M0
EQU EQU EQU EQU EQU EQU
H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- ADCON0 Bits -------------------------------------------------------ADCS1 ADCS0 CHS2 CHS1 CHS0 GO NOT_DONE GO_DONE ADON
EQU H'0007' EQU H'0006' EQU H'0005' EQU H'0004' EQU H'0003' EQU H'0002' EQU H'0002' EQU H'0002' EQU H'0000'
;----- OPTION_REG Bits ----------------------------------------------------NOT_RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
EQU H'0007' EQU H'0006' EQU H'0005' EQU H'0004' EQU H'0003' EQU H'0002' EQU H'0001' EQU H'0000'
;----- TRISE Bits --------------------------------------------------------IBF OBF IBOV PSPMODE TRISE2 TRISE1 TRISE0
EQU H'0007' EQU H'0006' EQU H'0005' EQU H'0004' EQU H'0002' EQU H'0001' EQU H'0000'
42
;----- PIE1 Bits ---------------------------------------------------------PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE
EQU EQU EQU EQU EQU EQU EQU EQU
H'0007' H'0006' H'0005' H'0004' H'0003' H'0002' H'0001' H'0000'
;----- PIE2 Bits ---------------------------------------------------------EEIE BCLIE CCP2IE
EQU EQU EQU
H'0004' H'0003' H'0000'
;----- PCON Bits ---------------------------------------------------------NOT_POR NOT_BO NOT_BOR
EQU EQU EQU
H'0001' H'0000' H'0000'
;----- SSPCON2 Bits -------------------------------------------------------GCEN ACKSTAT ACKDT ACKEN RCEN PEN RSEN SEN
EQU H'0007' EQU H'0006' EQU H'0005' EQU H'0004' EQU H'0003' EQU H'0002' EQU H'0001' EQU H'0000'
;----- SSPSTAT Bits ------------------------------------------------------SMP CKE D I2C_DATA NOT_A NOT_ADDRESS D_A DATA_ADDRESS P I2C_STOP S I2C_START R I2C_READ NOT_W NOT_WRITE R_W READ_WRITE UA BF
EQU EQU EQU
H'0007' H'0006' H'0005' EQU H'0005' EQU H'0005' EQU H'0005' EQU H'0005' EQU H'0005' EQU H'0004' EQU H'0004' EQU H'0003' EQU H'0003' EQU H'0002' EQU H'0002' EQU H'0002' EQU H'0002' EQU H'0002' EQU H'0002' EQU H'0001' EQU H'0000'
;----- TXSTA Bits --------------------------------------------------------CSRC TX9 NOT_TX8 TX8_9 TXEN SYNC BRGH TRMT TX9D TXD8
EQU H'0007' EQU H'0006' EQU H'0006' ; Backward compatibility only EQU H'0006' ; Backward compatibility only EQU H'0005' EQU H'0004' EQU H'0002' EQU H'0001' EQU H'0000' EQU H'0000' ; Backward compatibility only
;----- ADCON1 Bits -------------------------------------------------------ADFM PCFG3 PCFG2 PCFG1 PCFG0
EQU EQU EQU EQU EQU
H'0007' H'0003' H'0002' H'0001' H'0000'
43
;----- EECON1 Bits -------------------------------------------------------EEPGD WRERR WREN WR RD
EQU EQU EQU EQU EQU
H'0007' H'0003' H'0002' H'0001' H'0000'
;========================================================================== ; ; RAM Definition ; ;========================================================================== __MAXRAM __BADRAM __BADRAM __BADRAM
H'1FF' H'8F'-H'90', H'95'-H'97', H'9A'-H'9D' H'105', H'107'-H'109' H'185', H'187'-H'189', H'18E'-H'18F'
;========================================================================== ; ; Configuration Bits ; ;========================================================================== _CP_ALL _CP_HALF _CP_UPPER_256 _CP_OFF _DEBUG_ON _DEBUG_OFF _WRT_ENABLE_ON _WRT_ENABLE_OFF _CPD_ON _CPD_OFF _LVP_ON _LVP_OFF _BODEN_ON _BODEN_OFF _PWRTE_OFF _PWRTE_ON _WDT_ON _WDT_OFF _LP_OSC _XT_OSC _HS_OSC _RC_OSC
EQU H'0FCF' EQU H'1FDF' EQU H'2FEF' EQU H'3FFF' EQU H'37FF' EQU H'3FFF' EQU H'3FFF' EQU H'3DFF' EQU H'3EFF' EQU H'3FFF' EQU H'3FFF' EQU H'3F7F' EQU H'3FFF' EQU H'3FBF' EQU H'3FFF' EQU H'3FF7' EQU H'3FFF' EQU H'3FFB' EQU H'3FFC' EQU H'3FFD' EQU H'3FFE' EQU H'3FFF'
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". 2.2.4.3. Ejecución del compilador assembler El paso sucesivo es la compilación del source, es decir, la transformación en opcode de los códigos mnemónicos o instrucciones assembler. El compilador assembler que se utilizará es el MPASM.EXE con el IDE MPLABX producido por Microchip y disponible en el sitio Web de Microchip (http://www.microchip.com).
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. La compilación de un source assembler se realiza con los siguientes pasos: 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. 3. Crear el proyecto por ejemplo con el nombre Ejemplo en el directorio de trabajo C:\PICPRO que contenga el archivo "Ejemplo.asm". 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. 5. En el IDE del MPLABX en la ventana output se obtiene la siguiente salida, si no existe ningún error: BUILD SUCCESSFUL (total time: 501ms) Loading code from D:/ PICPRG /Ejemplo.X.production.hex... Loading completed 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 2.2.4.4. Programar el PIC 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. 2.3. Ejemplos de aplicación del microcontrolador PIC 16F877 2.3.1. Análisis de un problema sencillo 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. 2. 3. 4. 5. 6. 7. 8. 9.
leer NOMBRE leer NOTA no hay más notas (nota<0), ir al punto 7 acumular las notas incrementar el número de notas ir al punto 2 calcular la MEDIA imprimir NOMBRE imprimir MEDIA
Diagrama de Flujo del ejemplo MEDIA INICIO
contador 0 media 0
Leer: nombre
Leer: nota
nota>=0
media media+nota contador contador+1
SI
NO
media media/contador
Imprimir: nombre media
FIN
En los siguientes ejemplos se realiza básicamente la lectura y escritura de puertos de E/S digitales. 2.3.2. Ejemplo. Encender en forma secuencial un diodo LED 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. El circuito a ser realizado se presenta a continuación:
46
1. Diagramas de Flujo A continuación se presenta el Diagrama de Flujo del Programa Principal: INICIO
LED←1
Delay LED←0
LED=1
SI
NO LED←1
A continuación se presenta el Diagrama de Flujo de la subrutina Delay:
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 El código de este ejemplo en assembler se muestra a continuación: ;************************************************** ; Pic by example ; Ejemplo21.asm ; ; (c) 1999, Sergio Tanzilli ; ([email protected]) ; http://www.picpoint.com ;************************************************** PROCESSOR RADIX INCLUDE
16F877 DEC "P16F877.INC"
;LIST P=16F877 ;#INCLUDE "P16F877.INC"
;Configuracion de los flags del PIC: ;XT oscillator, OSC: XT ;Disable watch dog timer, WDT: OFF ;Enable power up timer, PWRTE: ON ;Disable code protect, CP: OFF __CONFIG
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;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 bcf
STATUS,RP0 STATUS,RP1
;Configura el pin 0 del Puerto B como salida movlw 11111110B movwf TRISB ;Cambia al banco 0 bcf STATUS,RP0 ;Se prende al inicio el LED bsf PORTB,LED ;Inicio programa MainLoop call Delay btfsc goto
PORTB,LED SetToZero
bsf goto
PORTB,LED MainLoop
SetToZero bcf goto
PORTB,LED MainLoop
;Subroutinas ;Software Delay Delay clrf clrf
Cont0 Cont1
DelayLoop decfsz goto
Cont0,1 DelayLoop
decfsz goto
Cont1,1 DelayLoop
return END
3. Análisis del código 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 INCLUDE. Es otra directiva que indica al compilador incluir en el source un segundo archivo denominado P16F877.INC. El compilador se limitará a sustituir la línea que contiene la directiva INCLUDE con el contenido del archivo indicado y a efectuar por lo tanto la compilación como si fuera también parte del source. INCLUDE "P16F877.INC"
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
Es importante notar que la palabra LED no identifica una variable, es simplemente un nombre simbólico válido durante la compilación. No será por lo tanto, posible introducir instrucciones tipo LED = 3 al interno del source, ya que la asignación dinámica de un valor a una variable es una operación que requiere la intervención de la CPU del PIC y por lo tanto debe ser expresada con instrucciones y no con directivas. 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 Cont1
EQU EQU
20H 21H
Cont0 y Cont1 son label's (etiquetas). 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 bsf. Es la primera instrucción mnemónica completa con parámetros, en este caso la instrucción mnemónica bsf significa BIT SET FILE REGISTER, es decir, pone un 1 (condición lógica alta) uno de los bits contenidos en la localización de la RAM especificada. 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. -
STATUS es el parámetro que viene definido en el archivo "P16F877.INC", a través de una directiva EQU. El valor asignado a este registro es 03H y corresponde a un file register (es decir, una localización RAM en el área de datos) reservado.
-
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. Tabla 2.10. Configuración de los pines del puerto B del PIC. 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. -
PORTB. Es una constante definida en el archivo "P16F877.INC" y permite referenciar el file register correspondiente a las líneas I/O del puerto B.
-
LED. Es el número de la línea que va a poner en 1. En el inicio del source la constante LED está definida igual 0, por lo tanto, la línea interesada será RB0. bsf PORTB, LED
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
o Para terminar el source assembler se utiliza la directiva END. 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. A continuación se verá el funcionamiento de esta subrutina: 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. o decfsz. La instrucción significa DECREMENT FILE REGISTER, SKIP IF ZERO, es decir, decrementa el contenido de un registro (en este caso Cont0 y salta a la instrucción siguiente si el valor alcanzado es cero). Si el valor alcanzado no es cero se ejecuta la instrucción siguiente. 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. o Cuando también Cont1 alcance el cero se ejecutará la instrucción: return
Cuyo significado es RETURN FROM SUBROUTINE, que determinara la salida de la rutina de retardo y la continuación de la ejecución de la instrucción sucesiva a la call Delay. 4. El circuito en Proteus C1 22pF
U1 X1 CRYSTAL
13 14
C2
2 3 4 5 6 7
22pF
R2 4k7
8 9 10 1
OSC1/CLKIN OSC2/CLKOUT
RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD
RA0/AN0 RA1/AN1 RA2/AN2/VREF-/CVREF RA3/AN3/VREF+ RA4/T0CKI/C1OUT RA5/AN4/SS/C2OUT RC0/T1OSO/T1CKI RE0/AN5/RD RC1/T1OSI/CCP2 RE1/AN6/WR RC2/CCP1 RE2/AN7/CS RC3/SCK/SCL RC4/SDI/SDA MCLR/Vpp/THV RC5/SDO RC6/TX/CK RC7/RX/DT RD0/PSP0 RD1/PSP1 RD2/PSP2 RD3/PSP3 RD4/PSP4 RD5/PSP5 RD6/PSP6 RD7/PSP7
33 34 35 36 37 38 39 40
R1
D1
100 LED-RED
15 16 17 18 23 24 25 26 19 20 21 22 27 28 29 30
PIC16F877
2.3.3. Ejemplo. Secuenciador de luces Modificar el Ejemplo21.asm para realizar un secuenciador a cuatro LED's. El nuevo source modificado se llamará Ejemplo22.asm. El nuevo circuito, prácticamente es igual al circuito presentado en el ejemplo Ejemplo21.asm, con la única variante que ahora los diodos LED’s conectados son cuatro, en vez de uno. El circuito a ser implementado se presenta a continuación:
55
1. Diagrama de Flujo A continuación se presenta el Diagrama de Flujo del Programa Principal: INICIO
Shift←0x01
PORTB←Shift C←0 Shift←Rotar a Izq.
Shift<4>=0
SI
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 ([email protected]) ; http://www.picpoint.com/picbyexample/index.htm ;************************************************** PROCESSOR RADIX
16F877 DEC
56
INCLUDE
"P16F877.INC"
;Configuracion de los flags del PIC: ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;Declaracion de Variables CBLOCK 20H Cont0 Cont1 Shift ENDC ;Reset Vector ORG 00H ;Cambia al banco 1 bsf STATUS,RP0 bcf STATUS,RP1 ;Configura los pines 0,1,2,3 del Puerto B como salidas movlw 11110000B movwf TRISB ;Cambia al banco 0 bcf STATUS,RP0 ;Se prende al inicio el bit 0 movlw 00000001B movwf Shift ;Inicio programa MainLoop movf movwf
Shift,W PORTB
bcf rlf
STATUS,C Shift,F
btfsc swapf
Shift,4 Shift,F
call
Delay
goto
MainLoop
; Subrutinas ;Software Delay Delay clrf Cont0 clrf Cont1 DelayLoop decfsz goto
Cont0,1 DelayLoop
decfsz goto
Cont1,1 DelayLoop
return END
3. Análisis del código
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 Configura los pines 0,1,2,3 del Puerto B como salidas: movlw movlw
11110000B TRISB
o Antes de ejecutar el ciclo principal (label MainLoop) se inicializa el nuevo registro Shift a 00000001B con las siguientes instrucciones: movlw movwf
00000001B 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 rlf
STATUS, C 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 swapf
Shift, 4 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 X1 CRYSTAL
C2
13 14 2 3 4 5 6 7
22pF
R5 4k7
8 9 10 1
OSC1/CLKIN OSC2/CLKOUT
RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD
RA0/AN0 RA1/AN1 RA2/AN2/VREF-/CVREF RA3/AN3/VREF+ RA4/T0CKI/C1OUT RA5/AN4/SS/C2OUT RC0/T1OSO/T1CKI RE0/AN5/RD RC1/T1OSI/CCP2 RE1/AN6/WR RC2/CCP1 RE2/AN7/CS RC3/SCK/SCL RC4/SDI/SDA MCLR/Vpp/THV RC5/SDO RC6/TX/CK RC7/RX/DT RD0/PSP0 RD1/PSP1 RD2/PSP2 RD3/PSP3 RD4/PSP4 RD5/PSP5 RD6/PSP6 RD7/PSP7
33 34 35 36 37 38 39 40 15 16 17 18 23 24 25 26
R1
D1
100
D2 LED-RED
100
D3 LED-RED
100
D4 LED-RED
R2 R3 R4 100
LED-RED
19 20 21 22 27 28 29 30
PIC16F877
2.3.4. Ejemplo. Convertir un número Binario a BCD de 0 a 255. 1. Análisis matemático Por ejemplo, convertir el número decimal 34 a BCD: 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
Pero con el PIC16F877 no se puede realizar las operaciones aritméticas multiplicación y división, por lo tanto la división se realiza por restas sucesivas, como se indica a continuación: 34 - 10 = 24, contador = 1 (primera resta) 24 - 10 = 14, contador = 2 (segunda resta) 14 - 10 = 4, contador = 3 (tercera resta) 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 A continuación se presenta el Diagrama de Flujo, considerando que en la aplicación se ingresa el dato en binario desde el puerto C y el resultado de la conversión en BCD se muestra en los siguientes puertos: unidades decenas centenas
, en el PORTBL , en el PORTBH , en el PORTA
60
INICIO
numero PORTC decena 0 centena 0
unidad numero numero numero-10
SI
numero>=10 NO
decena decena+1
NO
BL unidad (numero) BH decena A centena
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": Sí numero>=10. Es una resta: numero-10 y verificar el flag CARRY (C) 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 C=1, (minuendo>=sustraendo) numero>=10, y Si C=0, (minuendo<sustraendo) numero<10 Sí decena=10: Es una resta: 10-decena y verificar el flag ZERO (Z) Si Z=1, decena=10, y Si Z=0, decena<>10 3. Código en Assembler El código en assembler se presenta a continuación: ;************************************************** ; Convertir un numero Binario a BCD de 0 a 255 ; Ejemplo23.asm ; abril 2010 ;************************************************** PROCESSOR 16F877 RADIX DEC INCLUDE "P16F877A.INC"
61
;Configuration de los flags del PIC ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;Declaración de Variables CBLOCK 20H numero unidad decena centena ENDC ;Reset Vector ORG 00H bsf bcf
STATUS,RP0 STATUS,RP1
;Se coloca en el banco 1
movlw movwf
11111111B TRISC
;Configura el puerto C como entrada
movlw movwf
00000000B TRISB
;Configura el puerto B como salida
MOVLW 0x06 MOVWF ADCON1
;Configura todas los pines del puerto A ;como digitales
movlw movwf
;Configura el nible bajo del puerto A como salida
bcf Principal movf movwf movlw movwf movwf
11110000B TRISA STATUS,RP0
;Se coloca en el banco 0
PORTC,W numero
;Mueve el contenido del puerto C al registro W ;Almacena W en la variable numero
00000000B decena centena
;Encera la variable decena ;Encera la variable centena
repetir movf movwf movlw subwf
numero,0 unidad 10 numero,F
;Guarda el valor de numero en unidad
;numero = numero - 10
btfss goto
STATUS,C result
;Si numero >= 10
incf
decena, F
;Incrementa en 1 la decena
movlw subwf btfss goto
10 decena,0 STATUS,Z repetir
movlw movwf incf goto
00000000B decena centena,F repetir
;Si decena = 10
;Encera la variable decena ;Incrementa en 1 la centena
;Muestra el resultado en los puertos B y A result swapf
decena,0
;Envia los valores de las decenas y numero al ;puerto B
iorwf movwf
unidad,0 PORTB
;Muestra decenas y unidades
movf movwf
centena,0 PORTA
;Envia el valor de las centenas al puerto A ;Muestra centenas
END
62
4. El circuito en Proteus C1 22pF
U1 X1 CRYSTAL
C2
13 14 2 3 4 5 6 7
22pF
R5 4k7
8 9 10 1
OSC1/CLKIN OSC2/CLKOUT
RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD
RA0/AN0 RA1/AN1 RA2/AN2/VREF-/CVREF RA3/AN3/VREF+ RA4/T0CKI/C1OUT RA5/AN4/SS/C2OUT RC0/T1OSO/T1CKI RE0/AN5/RD RC1/T1OSI/CCP2 RE1/AN6/WR RC2/CCP1 RE2/AN7/CS RC3/SCK/SCL RC4/SDI/SDA MCLR/Vpp/THV RC5/SDO RC6/TX/CK RC7/RX/DT RD0/PSP0 RD1/PSP1 RD2/PSP2 RD3/PSP3 RD4/PSP4 RD5/PSP5 RD6/PSP6 RD7/PSP7
D1
R1
33 34 35 36 37 38 39 40
100
D2 LED-RED
100
D3 LED-RED
100
D4 LED-RED
100
D5 LED-RED
100
D6 LED-RED
100
D7 LED-RED
100
D8 LED-RED
R2 R3 R4
15 16 17 18 23 24 25 26
R6 R7 R8
19 20 21 22 27 28 29 30
R9 100
LED-RED
PIC16F877
R14
R15
R16
R17
R10
R11
R12
R13
300
300
300
300
300
300
300
300
63