Introducción.
Bienvenidos al inicio de la clase «Microprocesadores PIC». Estas páginas, mostrarán cómo se forma la estructura básica del dispositivo, directamente por el programa, métodos y técnicas, queremos acercarnos a uno de los microcontroladores que, por diversas razones más auge ha adquirido en los últimos tiempos, podemos decir que, ha invadido nuestras expectativas de trabajo, con un amplio margen de aplicaciones. Habrá sugerencias sobre como modificar el código para que usted pueda adaptar el PIC para satisfacer sus necesidades dentro de sus usos. Incluiré los mínimos diagramas de arquitectura internos, esto suele conducir a la turbación. Si alguien quiere mirar las hojas de datos (datasheet), entonces puede localizarlos en el sitio web de Microchip.
Esto es necesario al principio, ya que, nadie ha empezado desde CERO AL CUADRADO, toda la ayuda disponible va dirigida al principiante. Estando apartado, como educador durante los pasados años, puedo ver esto y si Ud. está de acuerdo, le fascinará con el acercamiento que he hecho. Esto no es un acercamiento convencional ya que esto implicaría muchos términos nuevos y complicaciones. Esto es, un ACERCAMIENTO SIMPLE, una vez que se domine el arte de programar, podrá poner un programa con sus habilidades junto con la información del mismo en sus proyectos.
Como digo, una marea de usuarios, estudiantes e ingenieros vienen utilizando para sus proyectos, algún microcontrolador de la familia PIC. Doy por supuesto que, el lector dispone de conocimientos básicos sobre electrónica digital, para los usuarios más avanzados o incluso con una formación media, podrán resultar estas primeras entregas algo superfluas, pero ya llegarán los capítulos avanzados.
Aquí presentare unos artículos sobre las posibilidades, rutinas y proyectos que, se han creado para tal fin, alguno me han llegado de colaboradores o algunos que me he atrevido a traducir a nuestro idioma [castellano], para que también los que utilizamos este idioma, podamos aprender y llevar a cabo los ejercicios que se proponen y así obtener un conocimiento mayor y más profundo si cabe, de unos microcontroladores que, nos pueden aportar una solución tanto personal como profesional para nuestros proyectos.
Con esta documentación el estudiante, de nuestros artículos PIC, estará preparado para la programación de estos dispositivos y para el diseño de sistemas digitales y/o analógicos basados en los mismos. Otro objetivo es, hacer lo más económico posible estos artículos, reduciendo en lo posible los gastos, aunque sin embargo, los estudiantes serán capaces de hacer estos ejercicios con muy pocos gastos, aún así, inevitablemente habrán algunos pequeños gastos.
Para empezar, deberemos centrar nuestro esfuerzo en unos chips o dispositivos muy concretos. Microchip fabrica una amplia gama de microcontroladores y distribuye los microcontroladores PIC, ofreciendo un entorno de desarrollo semi-gratuito, se trata del MPLAB, con esta aplicación como veremos, podemos programar, compilar y simular nuestros proyectos.
Los microcontroladores PIC, basados en la arquitectura RISC (Juego Reducido de Instrucciones), contemplan la mayoría de las características de esta arquitectura, destacando el juego de instrucciones homogéneo, reducido número de instrucciones y alta velocidad. Hay muchas versiones de chips diferentes disponibles, algunos tipos básicos de memoria reducida, otros superiores los que tienen convertidores digitales o analógicos y hasta los constituidos por A/D y PWM.
Para ayudar al principiante a entrar en la programación, los microcontroladores PIC16F84A y los PIC12C508A, en adelante nos referiremos con ‘F84 al PIC16F84 o ‘508A al PIC12C508A. Cuando se aprende a manejar uno de estos chips, conociendo su arquitectura y su reducido repertorio de instrucciones, será muy fácil aplicar los principios a otros tipos de la gama.
En estos artículos describiremos los aspectos relevantes para el uso y control del ‘F84A es la versión con un «puerto y medio» y el más pequeño como es el ‘508A, ambos dispositivos son muy pequeños en el mundo de los ‘micros’ pero ambos son el medio para empezar. La designación de pines de ambos se muestra en estas imágenes.
Se ha elegido la gama de dispositivos PIC, porque son los más económicos y quizás lo mejor para el principiante. Quizás alguien se pregunte por qué he realizado tanta información para la programación de estos chips, cuando ya existe una enorme cantidad disponible en libros y en otros sitios de la red desde hace tiempo y he de añadir, muy buena.
Una razón es que los seguidores de este sitio, habrán comprobado que desde hace años se presentan distintos tratados sobre la electrónica siempre desde un aparente desorden, quiero decir, sin jerarquía de que artículo va antes de cual otro, hasta cierto punto, esto obedece a un sistema con el que se pretende que nadie sienta la necesidad hacer un ordenado método de la adquisición de conocimientos.
Lo cotidiano de un técnico es que, cada día aprende una nueva técnica para desarrollar un trabajo y sin duda, sobre la marcha aplica sus conocimientos, sin embargo nadie le indica como aplicarlos, simplemente ocurre. Por lo tanto, creo que, el método de cómo se adquieren los conocimientos no es muy importante, lo verdaderamente importante es comprender lo que se lee.
Se que para algunos, estructurar los temas responde a la experiencia de que, el usuario que por primera vez estudia los micros o microcontroladores, le resultará mas sencillo aprender primero lo referente a la constitución interna del dispositivo y la arquitectura general de los microcontroladores, para una vez dominada ésta, pasar entonces a los detalles electrónicos de la circuitería y la programación. Sin embargo, en este manual no se establece ese orden, sino que, el propio usuario tiene la flexibilidad para optar por otras secuencias, esperando generar así, mayor interés en seguir aprendiendo.
Y esto es lo que he hecho. No se necesita saber el álgebra Booleana, matemáticas complejas o la forma de cómo hacer un doble XOR, haremos todo de manera simple y se será capaz de programar. El ‘curso’ también muestra como comunicar (interfaz) los chips con dispositivos externos, tomando ideas de un proyecto y aplicándolas a otro, se puede crear un circuito totalmente nuevo con la mayor destreza.
Alguien dijo, «hay una cosa asombrosa sobre la programación, un programa puede ser producido usando una idea sumamente compleja o una idea muy simple. El resultado final es el mismo, aunque el caso simple pueda tener unas instrucciones más para alcanzar el resultado final». ¡Y, quien se preocupa por unas pocas instrucciones de más, cuándo el micro procesa sobre 1.000.000 de instrucciones por segundo, sí, un millón por segundo!
EL PIC12C508A.
Comenzaremos con un programa simple de siete líneas para controlar un LED en un prototipo que, llamaremos Destello ‘508A. Recuerde dar nombre a sus experimentos, ya nos ocuparemos de esto. No se preocupe por ahora, si no entiende el significado de los parámetros que siguen. El programa enciende un LED, esto es todo lo que hace. El objetivo de este programa es mostrarle el número mínimo de líneas de código requerido para conseguir que haga algo el microcontrolador PIC.
1 2 3 4 5 6 7 8 |
Inicio BSF 03,5 ; inicia el registro MOVLW 3E ; mueve 3Eh = 0011 1110b al registro W MOVWF 06 ; copia W en f, apaga el bit0 o GP0 BCF 03,5 ; bit de borrado Salida MOVLW 01 ; inicia lazo de retardo MOVWF 06 ; copia W en f, pone a 1 la salida GP0 (enciende LED) GOTO Salida ; retorna al principio del lazo. |
Este simple programa para el 12C508A, iluminará un LED, repitiendo esta secuencia de forma indefinida, hasta que falte la energía al circuito. El circuito consta de un LED además del ‘508A, conectando tres patillas del CI, las dos de energía y la correspondiente al pin 7 (Propósito General In/Out línea GP0) y el programa. Este sería el organigrama que ilustra esta rutina que hace lucir un LED.
Esta figura, muestra un programa con los 4 pasos siguientes: Inicio, pone la salida activa [1] (inicia lazo), retardo de encendido de 0’1 segundo por la propia instrucción, desactivar pone la salida a [0] y produce un retardo de apagado de 0’9 segundos, volviendo al principio del lazo (loop), no vuelve a «inicio», solo a la etiqueta «salida».
La parte que se debe recordar es que, el procesador (el corazón del microcontrolador) debe mantenerse corriendo (latiendo) todo el tiempo. El chip contiene un oscilador de 4MHz, ésta frecuencia es dividida internamente por 4 para que en cada microsegundo, sea procesada una instrucción. Esto permite hacer muy fácil, rutinas de retardo exactas.
En este caso no necesitamos tiempos de retardo exactos, sin embargo podremos obtener resultados vía programa y el circuito trabajará exactamente como se proponga. El programa requiere de 0’1 segundo, esto quiere decir que se tendrá que producir un retardo de 100.000 ciclos [sin hacer nada], mientras la salida se mantiene encendida (EN). Acto seguido, el mismo programa solicita 0’9 segundos. Esto significa un retardo de 900.000 ciclos de nuevo, mientras la salida está en la condición apagado (AP).
La rutina necesaria está descrita a continuación (se puede copiar y pegar), son unas pocas líneas, se distinguen tres columnas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<strong>Etiqueta Comandos ;Comentarios</strong> Flash BSF 03h,5 ;Selecciona Pagina 1 MOVLW 00 ;pone literal 00 en W MOVWF 06 ;para hacer GP0 salida BCF 03h,5 ;y vuelve a pagina0 Loop1 BSF 06,0 ;Pone a 1 el bit0 del archivo 06h CALL Delay1 ;salta a Delay1 BCF 06,0 ;Pone a 0 el bit0 del archivo 06h MOVLW 09 ;fuerza un 9 en W MOVWF 0C ;activa lazo AA1 CALL Delay1 ;salta al retardo Delay1 DECFSZ 0C ;decrementa registro 0Ch y salta si es Cero GOTO AA1 ;repite lazo GOTO Loop1 ;salta a Loop1 Delay1 MOVLW 82h ;crea 130 lazos MOVWF 1A DelX DECFSZ 1B ;256 decrementa para volver a 1A GOTO DelX ;2µs instrucciones DECFSZ 1A GOTO DelX RETURN |
Sin embargo, antes de empezar a realizar este ejercicio, debería tenerse en cuenta que, un microcontrolador PIC12C508A, sólo se puede ‘quemar’ una vez (OTP), debido a que las celdas que componen su memoria reciben una descarga eléctrica durante la programación, el efecto producido ‘quemado’ no se puede cambiar. El fabricante garantiza que el chip es capaz de mantener el programa durante muchos años. Según esto, antes de utilizar el ‘508A, debemos asegurarnos completamente que el programa nos satisface y cuando el proyecto entero esté terminado, entonces pasarlo al ‘508A.
Hay otra forma más rápida de conseguir experiencia en nuestras practicas de programación si utilizamos un chip PIC16F84A. Esta es una versión mayor del ‘508A y por suerte casi todas las características del ‘508A se pueden encontrar en el ‘F84. Esto quiere decir que podemos tratar el ‘F84 como un ‘508A y usar los registros y los pines de entrada/salida que corresponden al ‘508A, el código escrito para el ‘F84 puede ser cargado en un ‘508A y este puede ser incluido en un proyecto.
Como el ‘508A es mucho más económico que el ‘F84 y nos propusimos hacer un proyecto muy barato, este es el otro motivo, además porque el ‘F84 puede ser programado y borrado cerca de 1.000 veces y esto nos ahorra malgastar chips. Podemos hacer todas nuestras prácticas de programación con un solo ‘F84 y poner el programa acabado, en un ‘508A y el proyecto estará terminado.
Verá en los siguientes artículos que, el ‘curso’ es completamente práctico y la mayor parte se consigue con la programación. Nuestros objetivos se deben conseguir con la programación, así que, puede producir los proyectos de microcontrolador y vender sus propios chips programados por poco. Esto es algo que, nunca ha sido posible hacerse antes.
Esto quiere decir que, nuestro ‘curso’ está en marcha a pesar de todo. Por este motivo, no censuro a cada uno de los grupos de usuarios del PIC o cada uno de los productores de programadores económicos ya que, el lector necesitará la ayuda de estas fuentes, una vez que consiga su ‘equipo’ para la programación. Todos estos otros grupos tienen una considerable entrada de valores por la programación de PIC, se entiende, otra cosa que debe recordar, es el concepto de programación mediante una Biblioteca de Rutinas y la utilización del ‘F84A como una herramienta de desarrollo para sus proyectos simples.
Los dos chips en los que nos centraremos como se ha dicho, son el PIC12C508A y PIC16F84A, estos le permitirán que pueda empezar a crear proyectos equivalentes a 6 u 8 chips (o aún más de la vieja tecnología de puertas y contadores etc.), sus cosas y otros productos como cerraduras electrónicas que usan una tarjeta para el acceso, las tarjetas de seguridad que transmiten un dato o más, demostraciones, juegos, dispositivos telefónicos, alarmas, dispositivos interfaces, osciladores, en robótica y otras partes.
Como dijo un programador: ‘ Ya nunca usaré el 555 otra vez ‘. Cada una de las ideas y proyectos que ya han sido producidos sobre y para un módulo de ‘tipo intérprete’ ahora puede ser creado con un sólo chip y producido en menos de 1/4 del coste.
Seguro que nuestro curso tendrá la disculpas de los que ya programáis con uno de esos módulos caros. Bastante a menudo se les ocurrirá una idea, que sea conveniente para su comercialización. Entonces es cuando el proyecto tendrá que ser convertido en un diseño mucho más barato para hacerlo comercializable. Y aquí es donde intervenimos, para que el coste de un chip, prototipo (placa PCB), un juego de discos, programa, libros y será capaz de lanzar su propio producto. Pero obviamente tendrá que comenzar por el principio y familiarizarse con el código y las capacidades de los distintos chips. Por lo dicho respecto al ‘508A, tomamos la decisión de usar el ‘F84A.
EL PIC16F84A
Aquí se muestra visto por la cara superior el símbolo y nombre de las patillas o pines de un PIC16F84A y similares, más adelante estos datos se ampliarán y reincidiremos sobre ellos.
En este dispositivo sus pines están organizados en puerto y medio, es decir, los pines RA0-RA4 corresponde a medio puerto A y los pines RB0-RB7 son el puerto B, a parte se encuentran los pines de oscilador OSC1 y OSC2, el de MCLR (aclarado maestro) y los propios de suministro de energía (Vdd y Vss). A continuación, describiré ligeramente para que se utiliza cada uno:
RA0 a RA4
RA es un puerto bidireccional (I/O). Es decir este puede ser configurado como una entrada o una salida, según interese. El número después de RA es el bit relativo, el número puede ser (0 a 4). Así que, tenemos un puerto de 5 bit direccional donde cada bit puede ser configurado individualmente como Entrada o Salida. Recordar que al tratarse de un puerto, un bit se considera una línea o pin del puerto.
RB0 a RB7
RB es un segundo puerto bidireccional (I/O). Esto se comporta exactamente del mismo modo que RA, excepto que hay 8 bits implicados, el número puede ser de 0 a 8 y cada bit como en RA, puede ser configurado individualmente como Entrada o Salida y también es una línea (pin) del puerto.
OSC1 y OSC2
Estos pines conocidos también como CLKIN y CLKOUT, en CLKIN puede conectarse un reloj externo, o donde conectamos un cristal, red RC o un resonador externo, para que el microcontrolador tenga una especie de ‘pulso cardíaco’. Debemos recordar que según el tipo de generador que decidamos usar de los descritos, es el que debe usarse a la hora de ‘quemar’ el programa, ya que si se cambia no oscilará o puede dar problemas de oscilación.
MCLR
Este pin tiene dos utilidades, es usado como (Reset) para borrar posiciones de memoria dentro del PIC (cuando queremos reiniciar de nuevo el programa). En el uso normal, este pin se conecta al terminal de suministro positivo, personalmente recomiendo intercalar un resistor de al menos 1k. El segundo uso es en el momento de la programación de este chip, el terminal MCLR es el pin por el que se aplica la tensión de programación por el software de quemado, en ese momento no se usa el resistor de 1k.
INT
Este es un pin de entrada que puede ser supervisado. Si este pin se pone alto (1), haremos que el programa comience de nuevo, se pare o cualquier otra función simple que deseemos. Básicamente se usa para » despertar» al dispositivo como ya se describirá en otros artículos.
TOCK1
Este pin es otra entrada de reloj, que maneja un temporizador interno. Este se utiliza en casos extremos en ausencia del reloj principal. Normalmente no se utiliza éste modo.
VDD y VSS
Estos son los pines de suministro de energía, VDD es la línea del positivo y VSS es la línea del negativo, masa o 0V. La tensión máxima de la fuente de suministro que se puede usar sin deteriorar el dispositivo para su normal funcionamiento son 6V y el mínimo de 2V, aunque recomiendo utilizar un diodo rectificador de paso en el caso de tensiones de 6V.
NOCIONES
Todo lo que hace el micro es, configurar y manejar bits entre distintos registros. Estos registros están implementados en la memoria RAM interna con un ancho de 8 bits, cada bit de cada registro o archivo tiene una función especifica. Los registros de las primeras posiciones en la memoria RAM, como ya se describe en otro artículo, se les ha dado el nombre de SFR (Registros de Función Especial), los de las siguientes posiciones son los de propósito general y se llaman GPR.
EL PIC16F84A DISPONE DE DOS CLASES DE MEMORIA.
Hay dos bloques de memoria en el PIC16F84A, estos son la memoria de programa y la memoria de datos. Cada bloque tiene su propio bús, de modo que el acceso a cada bloque puede ocurrir durante el mismo ciclo del oscilador.
Una es, la memoria flash que se encarga de almacenar y gestionar el programa, la memoria del ‘F84A es de 1k (1024 celdas o palabras) cada celda tiene un ancho de palabra de 14 bits y tiene la particularidad de que aunque se desconecte o falte la energía, no se altera su contenido. Sin embargo, el contenido permite ser reescrito sobre 10.000 veces, por medio de los llamados grabadores de microchips, con los que se procede al ‘quemado’, borrado y lectura de los programas.
La memoria de datos adicional mayor puede ser direccionada en la RAM de propósito general y los Registros de Función Especial (SFRs). La operación de los SFRs que controla el «corazón» se describe aquí. Los SFRs usados para controlar los módulos periféricos son descritos en la sección que habla de cada módulo individual periférico.
El área memoria de datos también contiene la memoria de datos EEPROM. Esta memoria no es directamente mapeada en la memoria de datos, pero es mapeada indirectamente. Es decir, un puntero de dirección indirecta, especifica la dirección de la memoria de datos EEPROM para lectura/escritura. Los 64 octetos de datos de la memoria EEPROM tienen la gama de dirección 00h-3Fh.
Memoria de Programa.
Los PIC16FXX tienen un contador de programa de 13 bit capaz de direccionar un espacio de memoria de programa de 8 kilobyte x 14. Para el PIC16F84A, el primer kilobyte x 14 (0000-03FFh) físicamente esta implementado (figura de la izquierda). El tener acceso a una posición superior a la dirección físicamente puesta en práctica causará un recirculado. Por ejemplo, para posiciones 20h, 420h, 820h, C20h, 1020h, 1420h, 1820h, y 1C20h, la instrucción será la misma. El vector RESET está en 0000h y el vector interrupt está en 0004h, esto le puede parecer enrevesado, sin embargo pronto verá como se le aclaran las ideas.
Memoria de Datos.
La memoria de datos se divide en dos áreas. La primera, es el área de Registros de Función Especial (SFR), mientras la segunda es el área de Registros de Propósito General (GPR). Los SFRs controlan el modo de operación del dispositivo.
Partes de memoria de datos son mapeadas, esto es tanto para el área SFR como para el área GPR. El área GPR es mapeada para permitir una capacidad mayor de 116 octetos de RAM de propósito general. Las áreas mapeadas del SFR son para los registros que controlan las funciones periféricas. Estos bancos requieren del empleo de bits de control para la selección de banco.
Estos bits de control mencionados antes, se localizan en el registro STATUS. La figura de la derecha, muestra la organización del mapa de memoria de datos. Las instrucciones MOVWF y MOVF pueden mover valores del registro W a cualquier posición en el archivo de registro («F») y viceversa.
Se puede tener acceso directo a toda la memoria de datos utilizando la dirección absoluta de cada archivo de registro o de modo indirecto mediante los Registros de Función Especial (SFR). El direccionado indirecto usa el valor actual del bit RP0 para el acceso a las áreas mapeadas de memoria de datos.
Como se ha dicho, la memoria de datos se divide en dos bancos que contienen los RPG y los SFR:
- El banco 0 se selecciona por el aclarado (puesta a 0) del bit RP0 (STATUS<5>).
- El banco 1 se selecciona al poner a 1 (Set) el bit RP0.
Cada Banco se extiende hasta 7Fh (128 bytes). Las doce primeras posiciones de cada Banco son reservadas para los Registros de Función Especial, el resto son Registros de Propósito General, implementados en la práctica como RAM estática.
Los Registros de Función Especial se usan por la CPU y funciones periféricas para controlar la operación del dispositivo. Estos registros son la RAM estática. Los registros de función especial pueden ser clasificados en dos juegos, central y periférico. Aquellos asociados con las funciones principales son descritos en esta sección. Aquellos relacionados con la operación de los rasgos periféricos son descritos en la sección para aquel rasgo específico.
EMPEZAMOS
Resumiendo, cuando se pone a correr el micro, la primera posición a la que llega es la 0000h, lo que se conoce por Vector de Reset, esto puede ocurrir por cualquier causa externa o interna como, inicio, reinicio, reset, despertado por cambio en los pines, timer0, etc. como ya describirá en otros artículos.
Luego en la posición 0004h, se encuentra el Vector de Interrupción, a esta posición llega el programa cuando esta habilitada la interrupción y ocurre un evento bien sea interno del micro o por una interrupción externa. Ver la imagen de la izquierda.
Hay un espacio de memoria destinada al programa del usuario, puede apreciarse que sólo se han implementado 1k (hasta 03FFh). A partir de las últimas posiciones hay un espacio de memoria reservado, este espacio está en la posición 2007h y se conoce como Palabra de Configuración, en el que se configura el oscilador, se habilita el Temporizador Perro Guardián y otros. A esta parte sólo se accede para escribirla mediante el interfaz de usuario y grabador en el quemado del chip.
La otra clase es la memoria RAM, que está compuesta por dos partes similares llamadas bancos, cada banco dispone de 80 bytes (00h a 4Fh). El ancho de palabra de estos bancos es de 8 bit. En los 12 primeros registros del 00h al 0Bh de cada banco se encuentran los registros de función especial SFR que se usan permanentemente por el programa, en los que se configuran los puertos y demás opciones ya descritas. Los siguientes 68 registros desde 0Ch a 4Fh, estos son los registros de propósito general GPR, usados por el usuario. Ver imagen de la derecha.
Al conectar la energía al micro, el micro empieza a correr con el contenido por defecto del valor de los registros FSR y empieza a correr nuestro programa. El contenido tanto de los registros SFR como GPR con los que hemos cargado el programa, estarán cambiando continuamente al ritmo de ejecución de las líneas del propio programa, por lo que en el momento de desconectar la energía, los valores contenidos en los registros SFR y GPR definitivamente se pierden. Los registros con el mismo nombre en ambos bancos, indican que el contenido es el mismo en ambos, esto se conoce como mapeado.
Existe otro tipo de memoria de 8 bits de ancho, muy utilizada la EEPROM, que se usa como memoria permanente de datos. El diferente ancho de palabra de estas memorias la RAM-EEPROM de 8 bits y la FLASH de 14 bits están conectadas a la CPU con buses diferentes. Esta arquitectura tiene la ventaja de que el tamaño de las instrucciones no está relacionada con los datos de la RAM lo que permite ser optimizada para que cualquier instrucción ocupe una sola posición de la memoria permitiendo una mayor velocidad y menor longitud de programa.
El cometido de los principales registros SFR, está descrito en el artículo ‘descripción de instrucciones’ de esta serie de artículos.
Este artículo continua en la segunda parte. En próximos artículos seguiremos con descripciones y prácticas para adquirir la practica y experiencia en programación.