Se un escritor de Circuitos Electrónicos.


Queridos lectores, si visitan regularmente mi blog se habrán dado cuenta de que casi no lo he actualizado. La razón o mejor dicho la excusa =) de eso es que ciertas actividades absorben todo mi tiempo.

No me gustaría tener abandonado este sitio por lo que les hago una atenta invitación para unirse al equipo de circuitos electrónicos, escribiendo artículos, noticias, proyectos y esquemas relacionados con la electrónica, la robótica, la programación y las matemáticas.

Para incentivar la colaboración se hará un muy pequeño pago por cada nota escrita (que posiblemente aumentará después). Para participar debes mandar dos muestras de tu redacción (de 200 a 250 palabras, no serán publicadas si no eres seleccionado) a la ficha de contacto del blog, junto a una lista de los temas sobre los que te gustaría escribir. Si eres elegido, yo me contactaré contigo.

Espero que se animen a participar, recuerden, hagamos juntos el espacio de los electrónicos.

Introducción a los microcontroladores


Este tutorial ha sido escrito por el técnico en electrónica César Antonio Saldías Caro, de Valparaíso, Chile. Quien nos ha otorgado el permiso para publicarlo en nuestro blog. Puedes encontrar más información en su sitio ingenieropic.wordpress.com.

Microprocesador y microcontrolador.

Los microprocesadores y los microcontroladores son dispositivos electrónicos que tienen la capacidad de llevar a cabo procesos lógicos.

El microprocesador (CPU), tiene la característica de que sus unidades están físicamente separadas, esto significa que interactúa con una memoria RAM, una memoria ROM y con dispositivos de entrada y salida por medio de buses de comunicación. Los primeros microprocesadores fueron el Z-80 y el 8085.

El microcontrolador, por su parte, es un solo dispositivo que internamente contiene todo lo necesario para poder llevar a cabo sus acciones. Este contiene su propio CPU, memorias RAM y ROM y dispositivos de entrada y salida. Por lo tanto es superior al microprocesador debido a su reducido tamaño y capacidad de ser implementado en circuitos electrónicos. Sin embargo, los microprocesadores continúan empleándose en equipos como los computadores.

Estructura del microcontrolador y el microprocesador
I / O= Input / Output - En español= Entrada / Salida.

En las imágenes de arriba podemos apreciar la diferencia entre ambos. El microcontrolador es la mezcla entre un microprocesador, una memoria RAM, una memoria ROM y dispositivos de entrada y salida.

Antes de la aparición de los microprocesadores y posteriormente de los microcontroladores, los diseños de los circuitos electrónicos eran enormes y requerían gran cantidad de cálculos matemáticos y la implementación de muchos componentes, tales como resistencias, transistores, etc.

El microcontrolador.

Como se dijo al comienzo, el microcontrolador realiza procesos lógicos. Estos procesos son programados en un computador utilizando un lenguaje de programación, generalmente lenguaje Assembler, y se insertan o graban en la memoria del microcontrolador mediante un “programador de PIC”.

Tipos de arquitecturas de los microcontroladores:

a) Arquitectura Von Neumann.

En este tipo de arquitectura, el CPU (Unidad Central de Proceso) está conectado a una única memoria en donde se guardan las instrucciones del programa y los datos. En otras palabras, el CPU está conectado a una ROM y una RAM por medio de un solo bus de comunicación.

El tener un único bus de comunicación, hace que el microcontrolador sea más lento, puesto que no puede acceder a la memoria a buscar una nueva instrucción mientras no finalice la transferencia de datos de la instrucción anterior.

Las limitaciones de esta arquitectura son la siguientes:

1) Por tener un único bus de datos, hace que el CPU tenga que hacer varios accesos a la memoria para buscar instrucciones complejas.

2) A causa del único bus de datos, se reduce el tiempo en realizar las operaciones, impidiendo superponer los tiempos de acceso.

Diagrama de la arquitectura de Von Neumann

b) Arquitectura Harvard.

A diferencia de la arquitectura Von Neumann, la arquitectura Harvard tiene el CPU conectado a dos memorias por medio de dos buses diferentes. Una de las memorias contiene solamente las instrucciones del programa y la otra solo almacena datos.

Ambos buses son diferentes, y pueden ser de distinto acho.

Tiene las siguientes ventajas:

1) Mayor velocidad, ya que puede acceder a la memoria de datos para completar la instrucción en curso y al mismo tiempo puede acceder a buscar una nueva instrucción.

2) El tiempo de acceso a ambas memorias puede superponerse, logrando mayor velocidad.

Una pequeña desventaja de los microcontroladores con arquitectura Harvard, es que deben poseer instrucciones especiales para acceder a tablas de valores constantes que pueda ser necesario incluir en los programas.

Diagrama de la arquitectura Harvard

Orientaciones del procesador.

Orientaciones del procesador

El procesador (CPU): Es el elemento más importante dentro del microcontrolador, este determina sus principales características, tanto a nivel de hardware como de software.

El CPU se encarga de direccionar la memoria de instrucción, recibir el código de la instrucción en curso, decodificar y ejecutar la operación que implica la instrucción, así como la búsqueda de los operandos y el almacenamiento del resultado.

Existen tres orientaciones en cuanto a la arquitectura y funcionalidad de los procesadores actuales.

CISC: “Computadores de juego de instrucciones complejo”. Un gran número de procesadores utilizados en microcontroladores, posee orientación CISC.

Disponen de más de 80 instrucciones maquina en su repertorio, algunas de ellas son muy sofisticadas y potentes y requieren varios ciclos para su ejecución. Una ventaja de los procesadores CISC es que ofrecen al programador instrucciones complejas.

RISC: “Computadores de juego de instrucciones reducido”. En los procesadores RISC, el juego de instrucciones maquina en muy reducido, suelen ser instrucciones simples y se ejecutan normalmente en un ciclo.

La sencillez y rapidez de las instrucciones permiten optimizar el hardware y el software del procesador.

SISC: “Computadores de juego de instrucciones específico”. El juego de instrucciones de los procesadores SISC es reducido y además es específico, esto significa que las instrucciones se adaptan a las necesidades de la aplicación prevista.

Área de memoria de un microcontrolador.

En los microcontroladores, las memorias de instrucciones y datos están integradas en el propio chip, por lo cual no se pueden utilizar memorias externas de implicación.

La memoria que contiene las instrucciones del programa es “no volátil” y se denomina ROM (Read Only Memory). La memoria que contiene los datos del programa es “volátil” y se denomina RAM (Random Access Memory).

La memoria RAM es de poca capacidad ya que solo debe contener las variables y los cambios de información en el transcurso del programa. A esta memoria se le denomina volátil ya que al apagarse o resetearse el microcontrolador, esta memoria pierde todos los datos que tenía almacenados previamente. Los datos que se manejan varían continuamente, lo que exige una memoria de lectura y escritura, por lo que una RAM estática (SRAM) sería la más adecuada.

La memoria ROM contiene el programa propiamente tal, y este no requiere ser almacenado en la RAM, ya que como solo es “un programa” el que se ejecuta en el microcontrolador, el CPU puede leerlo directamente de la ROM. Se denomina memoria “no volátil” puesto que el programa que contiene permanece almacenado aún después de apagar o resetear el microcontrolador.

Tipos de memoria ROM.

Los tipos de memoria ROM son lo siguientes:

ROM con máscara: En este tipo de memoria el programa se graba en el chip durante el proceso de fabricación mediante máscaras. Se fabrican en obleas que contienen varias decenas de chips. Esas obleas se fabrican a partir de procesos fotoquímicos. Los altos costos de diseño e instrumental solo aconsejan utilizar este tipo de memoria cuando se precisen lotes de chips muy grandes.

OTP: Este tipo de memoria solo puede ser grabada una vez por parte del usuario. Posteriormente no se puede borrar. Su bajo precio y la sencillez de la grabación aconsejan a este tipo de memoria para prototipos finales y series de producción de tamaño reducido. Este tipo de memoria encripta su trabajo por medio de fusibles para proteger el código contenido.

EPROM: “Erasable Programmable Read Only Memory”. Esta memoria es borrable y puede grabarse varias veces. La grabación se hace a través del PC. Para borrar su contenido, ellas disponen de una ventana de cristal en su superficie para que dejen pasar rayos UV y de esta manera limpiar la memoria.

EEPROM: “Electrical Erasable Programmable Read Only Memory”. Se puede grabar muchas veces y se puede borrar utilizando el mismo grabador, de manera que no tiene una ventana en su superficie. Su número de grabaciones es finito. Se trata de un tipo relativamente lento, o sea, el tiempo de escritura es grande.

FLASH: Se puede grabar y borrar en circuito, funciona como ROM y RAM pero es más pequeña y consume menos. A diferencia de la ROM, esta se puede programar en el circuito y es más densa que La EEPROM.

Secciones del microcontrolador.

Dispositivos de entrada y salida: Permiten comunicar al microcontrolador con el mundo exterior. A excepción de dos pines destinados a la alimentación, otros dos para el cristal de cuarzo que regula la frecuencia de trabajo, y otro para provocar el reset, los restantes son pines de entrada y salida.

Reloj principal (cristal de cuarzo): Todos los microcontroladores disponen de un circuito oscilador que genera una onda de alta frecuencia que configura los impulsos de reloj usados en la sincronización de todas las operaciones del sistema. Esta señal de reloj es el motor del sistema y la que hace que el programa y los contadores avancen.

Aumentar la frecuencia de reloj supone disminuir el tiempo en que se ejecutan las instrucciones, pero implica un incremento en el consumo de energía y calor generado.

Generalmente el circuito de reloj está incorporado en el microcontrolador y solo se necesitan unos pocos componentes externos para seleccionar la frecuencia de trabajo. Dichos componentes suelen consistir en un cristal de cuarzo junto a elementos pasivos, o bien un resonador cerámico o una red R-C.

La familia de los PIC.

Una de las marcas de microcontroladores más utilizada es la marca PIC de la compañía Microchip. La familia de microcontroladores PIC está dividida en cuatro gamas: enana, baja, media y alta.

La diferencia entre estas gamas radica en la longitud de las instrucciones, la aplicación y el número de puertos y funciones.

Los microcontroladores PIC sobresalen entre otras cosas porque:

- Su costo es bajo en comparación con microcontroladores de otras marcas.
- Tienen una elevada velocidad de funcionamiento.
- Tiene un set de alrededor de 35 instrucciones.
- Los programas son compactos.
- Presentan un bajo consumo de potencia y un amplio rango de niveles de voltaje.


Fabricación de circuitos impresos con hojas de transferencia.


En anteriores tutoriales les hemos enseñado a hacer circuitos impresos con diversas técnicas, entre las que destacan la del planchado de acetato y el de papel fotográfico, que se caracterizan por su sencillez y bajo costo. No obstante puede haber personas que por ciertas circunstancias aún no hayan podido fabricar sus propios PCB’s.

Pues para ellos está dedicada la siguiente técnica, muy similar a la del planchado de acetato, pero en la que se usan hojas de transferencia para circuitos impresos. Estas hojas son algo caras pero al parecer prometen resultados muy buenos y con pocas complicaciones.


Puedes encontrar estás hojas en cualquier tienda grande de electrónica, como Steren de México.

Usando macros.


El uso de subrutinas lo vimos por primera vez en el tutorial Encendiendo y apagando LED's... ahora con retardo! Ahí se vio la manera en la que se llama y se regresa de las subrutinas. También se dijo que el empleo de subrutinas hacía el código más entendible, otra forma de hacer el código entendible es mediante el uso de Macros.

Las macros son de alguna forma similares a las subrutinas ya que son conjuntos de intrucciones que se ejecutan de manera secuencial mediante una llamada a una orden de ejecución, sin embargo tiene diferencias muy significativas. Mientras que una subrutina aparece una sola vez en el código, cada vez que se "invoca" una macro se inserta el código de esta en el programa. Otra diferencia es que a una macro se le pueden especificar parámetros de entrada y a una subrutina no.

Una macro se define con la directiva macro especificando el nombre de la macro y los parámetros de entrada, si existieran, de la siguiente manera:
nombre_macro macro par1, par2,...
instrucción
instrucción
...

             endm


En el programa la definición de la macro debe aparecer antes de la línea en la que se llama la macro. Cuanto mientras se ejecuta el programa se encuentra una macro esta es reemplazada por el conjunto de instrucciones que aparecen en la definición de la macro. Una manera de asegurar eso es escribiendo las macros en un archivo include (.INC) y llamando a este include al momento de llamar el include de las definiciones del micro.

Las macros pueden ahorrar mucho tiempo de escritura ya que si hay partes del código que se repiten mucho se pueden escribir en una macro y ese código se insertaría de manera automática al llamar la macro. Veamos esto con un ejemplo. Los cambios de banco pueden ser muy repetitivos asi que si se quiere cambiar de banco se podrían definir unas macros de la siguiente manera:

banco0 macro             ; Definición de macro banco0
       bcf    STATUS,RP0 ; Bit RP0=0 = Banco 0
       endm              ; Termina definición de macro


banco1 macro             ; Definición de macro banco1
       bsf    STATUS,RP0 ; Bit RP0=1 = Banco 1
       endm             
; Termina definición de macro

Así si en el programa aparece el macro banco1 este será sustituido por el código bcf STATUS,RP0.

Con ese ejemplo tal vez no queda muy claro la ventaja de usar una macro ya que la macro solo contiene una instrucción y no utiliza parámetros, pero ahora que definimos esos macros definamos otro que designe un bit de un puerto como salida:

SALIDA macro    par1, par2 ; Definición de macro
       banco1              ; Macro para cambiar al banco 1
       bcf      par1, par2 ; Bit dado como salida
       banco0              ; Macro para cambiar al banco 0
       endm               
; Termina definición de macro

Para utilizar ese macro que contiene parámetros simplemente se llama de la siguiente manera:

       SALIDA   TRISA,3

Al llamara esa macro el primer parámetro dado TRISA toma el lugar de par1 mientras que el parámetro 3, el lugar de par2 generando el siguiente código:

    bsf STATUS,RP0 ; RP0 = 1 = Banco 1
    bcf TRISA,3    ; Bit 3 de Puerto A como entrada
    bcf STATUS,RP0 ; RP0 = 0 = Banco 0


Como se puede ver las macros hacen muy la escritura del código y al poder manejar parámetros proveen un medio para simplificar muchas operaciones.

Utilizando esos macros supongamos que realizamos un programa que ponga el alto el valor del bit 3 del puerto B. El código completo del programa sería:

    list    p=16f628a
    include p16f628a.inc
    include macros.inc ; Archivo con la definición de las macros


    org 0x00
    goto INICIO


    org 0x05
INICIO
    SALIDA  TRISB,3 ; Llamada a macro salida
    bsf     PORTB,3 ; Bit 3 del puerto B en alto


    goto    $       ; Ciclo infinito

    end

El programa principal es muy sencillo y legible. El archivo macros.inc donde se definen las macros quedaría así:

banco0 macro             ; Definición de macro banco0
       bcf    STATUS,RP0 ; Bit RP0=0 = Banco 0
       endm              ; Termina definición de macro


banco1 macro             ; Definición de macro banco1
       bsf    STATUS,RP0 ; Bit RP0=1 = Banco 1
       endm
             ; Termina definición de macro

SALIDA macro  par1, par2 ; Definición de macro SALIDA
       banco1            ; Llamada a macro banco1
       bcf    par1, par2 ; Bit dado como salida
       banco0            ; Llamada a macro banco0
       endm              ; Termina definición de macro


Teniendo en cuenta las dos diferencias mencionadas podemos entonces preguntarnos ¿son mejores las macros o las subrutinas?. La respuesta final la debe dar cada quien ya que dependiendo del caso se debería usar una o la otra.

Más información sobre macros se puede encontrar en el quinto capítulo de PIC microcontrollers, for beginners too, de Nebojsa Matic.


Multiplicación mediante el algoritmo de Booth.


El algoritmo de booth es un algoritmo que sirve para multiplicar (y dividir) números binarios con signo de manera rápida y sencilla en complemento a dos. Aqui explico de manera detallada el funcionamiento de ese algoritmo y muestro una implementacion del mismo para microcontroladores PIC.

La manera en que se representan los números binarios negativos es mediante su complemento a dos. El complemento a uno consiste en invertir el valor de cada bit, esto es que si se tiene el número 5 binario b'00000101' su complemento a uno sería b'11111010'. Una vez teniendo el complemento a 1 para obtener el complemento a dos simplemente se le debe sumar un 1, asi que se tiene b'11111010 + 1' de modo que el complemento a dos del número 5 binario es b'11111011'.

Ese es un dato muy importante ya que de ese modo se representan los números binarios negativos y el complemento a dos es parte del algoritmo de multiplicación de Booth. También es importante explicar que utilizando números de 8 bits el número mayor que se puede representar en complemento a dos es 127 y -127 que en binario son b'01111111' y b'1000001' respectivamente.

En ensamblador MPASM la manera de obtener el complemento a dos de un número es:
comf NUM,f
incf NUM,w
movwf NUMC2


donde NUM es el registro en el que se encuentra el número que se quiere pasar a complemento a dos y NUMC2 es el registro donde se guarda el complemento a dos del número. Hasta ahí todo bien, ahora pasemos al algorítmo.

Supongamos que queremos multiplicar dos números de 8 bits, digamos que queremos multiplicar 5*(-6) donde 5 es el multiplicando y -6 es el multiplicador, con esos datos se forman 3 arreglos distintos de la siguiente manera:

A=0000 0101 0000 0000 0
S=1111 1010 0000 0000 0
P=0000 0000 1111 1010 0


El byte superior de A está formado por el multiplicando, el siguiente byte se forma con ceros y se agrega un bit extra que también es 0.

El byte superior de S está formado por el complemento a dos del multiplicando, el siguiente byte al igual que el caso anterior se forma con ceros y al final se agrega un bit extra que es 0.

El byte superior de P está formado por ceros, el siguiente byte es el valor del multiplicador y por ultimo se tiene el bit extra.

Se puede observar que los tres números formados son de 17 bits cuando los números que se van a multiplicar son de 8 de modo que los números formados siempre serán de N+1 bits, siendo N el número de bits de los factores.

Sigamos entonces. Este algorítmo consiste en comparar los últimos dos digitos del número P y dependiendo de el caso que sea realizar un suma o no realizar ninguna acción. Luego de evaluar cada caso se debe realizar un corrimiento a la derecha, manteniendo el valor del bit más significativo y desechando el valor del bit menos significativo. Los cuatro casos que se tienen se pueden ver en la siguiente tabla:

0 0 -> No realizar ninguna acción
0 1 -> P = P + A
1 0 -> P = P + S
1 1 -> No realizar ninguna acción


Veamos el algoritmo paso a paso usando los numeros A, S y P de arriba. Primero tenemos el numero P original:

0000 0000 1111 101[0 0] P

Se comparan los ultimos dos digitos [0 0] con los cuatro casos posibles y se ve que no se debe realizar ninguna accion por lo que en la primer iteracion simplemente se realiza un corrimiento a la derecha:

1.
0000 0000 0111 110[1 0] ->


Ahora los ultimos dos digitos [1 0] indican que se debe realizar la suma P=P+S y despues el corrimiento a la derecha:

2.
1111 1011 0111 110[1 0] P=P+S

1111 1101 1011 111[0 1] ->

Despues del corrimiento los ultimos dos digitos son [0 1] por lo que se debe realizar la suma P=P+A y despues el corrimiento a la derecha:

3.
0000 0010 1011 111[0 1] P=P+A

0000 0001 0101 111[1 0] ->


Ahora los ultimos dos digitos son [1 0], se realiza la suma P=P+S y despues el corrimiento a la derecha:


4.
1111 1100 0101 111[1 0] P=P+S
1111 1110 0010 111[1 1] ->


Los ultimos dos digitos [1 1] al igual que cuando fueron [0 0] indican que solo se debe realizar el corrimiento a la derecha:

5.
1111 1111 0001 011[1 1] ->


De nuevo se tiene [1 1] por lo que se realiza unicamente el corrimiento y en lo sucesivo se tendra siempre el mismo caso:

6. 1111 1111 1000 101[1 1] ->
7. 1111 1111 1100 010[1 1] ->
8. 1111 1111 1110 0010 [1] ->


Despues de 8 iteraciones termina el algoritmo, se desecha el bit menos significativo (el bit extra) y se obtiene el producto de la multiplicacion:
5*(-6) = 1111 1111 1110 0010 = -30

Cabe mencionar que el numero de iteraciones que realiza el algoritmo es igual N, que es el numero de bits de los factores y el resultado final es igual a 2N, en este caso se multiplican factores de 8 bits por lo que el resultado final es de 16.

Esta es la manera en la que funciona el algoritmo. Solamente hay que tener en cuenta que al realizar los corrimientos a la derecha se debe mantener siempre el bit mas significativo, esto es que si se tiene '1101' y se realiza el corrimiento el resultado sera '1110' y no '0110'.

Implementacion del algoritmo de Booth en MPASM

Aplicando los pasos que acabo de explicar realice una implementacion del algoritmo de Booth para la multiplicacion en MPASM para realizar multiplicaciones de numeros signados de 8 bits en microcontroladores PIC 16F.

El algoritmo implementado sigue los mismos pasos descritos, compara los ultimos dos digitos del factor P y realiza alguna de las acciones posibles para despues llevar acabo el corrimiento. Como mencione en un principio el algoritmo solo puede multiplicar numeros que van del -127 al 127 y el resultado lo da a traves de los registros RESULTADOH:RESULTADOL.

Para poder utilizar esta rutina (multibooth) se deben declarar los registros A1, A2, A3, S1, S2, S3, P1, P2, P3, MULTIPLICANDO, MULTIPLICADOR, RESULTADOH, RESULTADOL y CONT.

En los registros RESULTADOH:RESULTADOL se muestra el valor positivo del resultado y si este fuera negativo se activa la bandera SIGNO (bit 0 del registro A3) para indicar que se trata de un numero negativo.

Una vez explicado el algoritmo creo que no hay necesidad de explicar la implementacion de la rutina aunque si asi fuera siempre estan los comentarios para exponer y aclarar las dudas.

Espero que esto les sirva.

Descargar codigo: Multiplicacion mediante el algoritmo de Booth