martes, 2 de octubre de 2012

Distintas configuraciones del Oscilador con el PIC

Vamos a ver las distintas configuraciones del oscilador que puede tener el PIC16F88

En el Post anterior (Primer proyecto en XC8) utilicé el oscilador interno del PIC16F88 a 8Mhz con los siguientes fragmentos de código:

/*
 * File:   system.h
 */
#define _XTAL_FREQ       8000000
 
/**
 * File:        configuration_bits.c
 */
 
__CONFIG(MCLRE_ON & CP_OFF & CPD_OFF & LVP_OFF & BOREN_OFF &
         WDTE_OFF & FOSC_INTOSCIO & PWRTE_OFF);
__CONFIG(IESO_OFF & FCMEN_OFF);

/**
 * File:        system.c
 */
void ConfigureOscillator(void) {
    // Configura el Oscilador interno a 8Mhz
    OSCCONbits.IRCF = 0b111;
}


Con los mismos bits de configuración del código anterior, para cambiar la frecuencia del oscilador interno lo que debemos hacer es cambiar el valor de OSCCONbits.IRCF (Internal RC Oscillator Frequency) por uno de los siguientes:

0b000 = 31.25 kHz
0b001 = 125 kHz
0b010 = 250 kHz
0b011 = 500 kHz
0b100 = 1 MHz
0b101 = 2 MHz
0b110 = 4 MHz
0b111 = 8 MHz

El "0b" que aparece adelante de cada valor le indica al compilador que lo que le estamos pasando es un número binario. También podríamos pasarle el valor en hexadecimal pero queda más claro de esta manera. IRCF ocupa 3 bits del registro OSCCON (bits 6,5 y 4).

Por ejemplo, si al programa del Post anterior le queremos cambiar la frecuencia del oscilador interno a 4 Mhz, debemos setear en IRCF el valor 0b110 y actualizar el macro _XTAL_FREQ para que la rutina de delay funcione correctamente:

/*
 * File:   system.h
 */
#define _XTAL_FREQ       4000000     // Necesario para la rutina de Delay


/**
 * File:        system.c
 */
void ConfigureOscillator(void) {
    // Configura el Oscilador interno a 4Mhz
    OSCCONbits.IRCF = 0b110;
}

Una de las ventajas que trae el seteo del oscilador interno es que podemos disponer de 2 pines más para utilizarlos como Entrada/Salida, pero trae como desventaja que no es del todo preciso.

Utilización de un Cristal externo

Si utilizamos un cristal externo, vamos a tener mucha más precisión que si utilizásemos el oscilador interno. Aparte de esto, podemos llegar a frecuencias mayores lo que permite que nuestro pic realice muchas más acciones en la misma cantidad de tiempo.

Por ejemplo, si queremos utilizar un cristal externo de 20 MHz debemos hacer los siguientes cambios en el código:

/*
 * File:   system.h
 */
#define _XTAL_FREQ       20000000 // Necesario para la rutina de Delay
 
/**
 * File:        configuration_bits.c
 */
 
__CONFIG(MCLRE_ON & CP_OFF & CPD_OFF & LVP_OFF & BOREN_OFF &
         WDTE_OFF & FOSC_HS & PWRTE_OFF);
__CONFIG(IESO_OFF & FCMEN_OFF);

/**
 * File:        system.c
 */
void ConfigureOscillator(void) {
    // No se setea ninguna configuración
}


Ahora el circuito nos quedará de la siguiente manera:

Circuito agregando el cristal externo de 20 Mhz y 2 capacitores de 0,15pF:
Imagen 1 - Cristal externo


El valor de los capacitores va a depender del cristal como podemos leerlo en la ficha técnica del PIC16F88:

Imagen 2


Se pueden agregar capacitores de más tamaño para aumentar la estabilidad del clock con la contra de que se retrasa unos milisegundos más el inicio. En mi caso utilicé 2 capacitores de 22pF.

Hay que tener en cuenta que tanto el cristal como los capacitores deben estar lo más cerca posible del PIC para evitar interferencias.

Cómo queda el circuito en mi protoboard:

Imagen 3

Imagen 4

Hasta la próxima!
Saludos.

miércoles, 26 de septiembre de 2012

Primer proyecto en XC8 (Parte 3) - Probando el código

Continúa de Primer proyecto en XC8 (Parte 2).

Ya vimos como hacer funcionar nuestro primer proyecto, ahora vamos a verlo en funcionamiento.

Algo que olvidé de mencionar en la entrada anterior fue que el resultado de la compilación es un archivo con extensión ".hex". Este archivo es el que debemos utilizar tanto para grabar nuestro pic como para hacer simulaciones con él. Este archivo lo encontramos dentro de la carpeta en la que guardamos nuestro proyecto, en la subcarpeta : "dist\default\production".

Por ej. en mi caso se encuentra en:
C:\pics\MPLABX\PIC16F88_01_Led_Intermitente.X\dist\default\production\

y el archivo generado es:
PIC16F88_01_Led_Intermitente.X.production.hex

MPLABX nos permite debuggear el programa y así ver que valores tienen los registros en un momento en particular. De esta forma nos damos cuenta que el programa está haciendo lo que le dijimos que haga. Sin embargo, no se lleva bien con las rutinas de delay ya que un retardo de 500 milisegundos puede durar unos 15 segundos o más.

Para ver en tiempo real cómo actuaría mi programa utilicé un simulador más sencillo, el PICSimlabhttp://sourceforge.net/projects/picsim/


En lugar de utilizar un PIC16F88 este programa simula un PIC16F628 que es bastante similar y tiene la misma disposición de pines que es lo que realmente nos importa.

El programa se ve así:

Figura 1


Lo que debemos hacer es seleccionar en File/Load Hex y seleccionar el archivo ".hex" que compilamos anteriormente. Luego seteamos el clock en 8 Mhz y podremos ver nuestro programa corriendo. Este simulador tiene conectado todo el Puerto B de nuestro pic a 8 leds con sus respectivas resistencias. Si creamos correctamente nuestro programa, deberíamos ver que el LED en RB0 se enciende y se apaga cada 1 segundo:

Figura 2

Ahora que sabemos como se comporta nuestro programa en el simulador, podemos grabarlo en nuestro PIC y probar su funcionamiento:

Primero conecto mi grabador de PICs JDM con el PIC 16F88 al puerto serie.

Figura 3
Luego abro el programa grabador (En mi caso el PICPgm):

Figura 4


Este programa detectó automáticamente que tengo conectado mi PIC al puerto COM1 de la PC.
Luego selecciono el archivo ".hex" compilado anteriormente y reviso que la configuración sea la correcta:

Figura 5


Vemos que la configuración está Ok. Utilizará el oscilador interno y utilizará el pin 4 como RESET.

Hacemos click en el botón "Program PIC" y comenzará a pasar nuestro programa al PIC:

Figura 6
Este proceso tarda apenas unos segundos.

Figura 7

Aprovecharemos el mismo protoboard del post Fuente de alimentación de 5 Volts y colocaremos los componentes de la siguiente manera:

Para hacer el esquema anterior utilicé Eagle que tiene una versión freeware con algunas limitaciones.

Por último, les muestro cómo me quedó el circuito en el protoboard:

Figura 9

FIgura 10

Esta fue un post bastante extenso pero era necesario contar paso a paso cómo es que estoy trabajando con los pics. Para lo próximo que explique solamente voy a postear el código, el esquema del circuito y alguna foto del circuito armado.

Gracias por visitarme, Saludos!

viernes, 21 de septiembre de 2012

Primer proyecto en XC8 (Parte 2) - Código para el Led intermitente

Continúa de Primer proyecto en XC8 (Parte 1) - Creación de proyecto

Agregando código a nuestro proyecto

En la parte 1 quedamos con la siguiente pantalla que muestra nuestro proyecto vacío recién creado:

Figura 1
A este proyecto le agregaremos la siguiente estructura de archivos de base:

Header Files:

  • system.h : Macros y funciones para configurar el sistema.
  • user.h: Macros y funciones específicas de la aplicación.
Source Files:
  • configuration_bits.c: Programación de los bits de configuración del sistema.
  • system.c: Funciones que configuran el sistema (Por ejemplo el Oscilador)
  • main.c: Programa principal
  • user.c: Algoritmos de la aplicación.


Para agregar un archivo ".h" hacemos click derecho en Header Files y seleccionamos "New/ C Header File...". En la siguiente pantalla escribimos el nombre del archivo y luego finalizar:

Ej.: system.h:

Figura 2
Figura 3

Para agregar un archivo ".c" hacemos click derecho en Source Files y seleccionamos "New/ C Source File...". En la siguiente pantalla escribimos el nombre del archivo y luego finalizar:

Figura 4

Figura 5
En system.h escribimos lo siguiente:

/* 
 * File:   system.h
 * Author: Julián Quiroga
 */
/*******************************************************/
/* System Level #define Macros                         */
/*******************************************************/
/**
 * Indica que el pic funcionará a 8MHz.
 * Este macro es necesario para las funciones de delay.
 */
#define _XTAL_FREQ       8000000

/*******************************************************/
/* System Function Prototypes                          */
/*******************************************************/
/**
 * Función que debe configurar el Oscilador
 */
void ConfigureOscillator(void);

En user.h por ahora lo dejaremos vacío:

/* 
 * File:   user.h
 * Author: Julián Quiroga
 */
/*******************************************************/
/* System Level #define Macros                         */
/*******************************************************/

/*******************************************************/
/* System Function Prototypes                          */
/*******************************************************/

En "configuration_bits.c" agregaremos lo que hablé en esta entrada "Configuración básica del PIC en XC8":
/**
 * File:        configuration_bits.c
 * PIC:         PIC16F88
 * Author:      Julián Quiroga
 *
 * Descripción: Configura el pic para que utilice
 *              el oscilador interno y el pin 4
 *              como Reset
 */
#include <xc.h>

__CONFIG(MCLRE_ON & CP_OFF & CPD_OFF & LVP_OFF & BOREN_OFF &
         WDTE_OFF & FOSC_INTOSCIO & PWRTE_OFF);
__CONFIG(IESO_OFF & FCMEN_OFF);

En "system.c" escribiremos lo siguiente:

/**
 * File:        system.c
 * PIC:         PIC16F88
 * Author:      Julián Quiroga
 *
 * Descripción: Funciones base del sistema
 */
#include <xc.h>
#include <stdint.h>        /* For uint8_t definition */
#include <stdbool.h>       /* For true/false definition */

#include "system.h"

/**
 * Configurar todo lo necesario para que funcione el oscilador interno 
 * a 8Mhz.
 */
void ConfigureOscillator(void) {
    // Configura el Oscilador interno a 8Mhz
    OSCCONbits.IRCF = 0b111;
}

Ahora sólo nos queda crear main.c:

/* 
 * File:        main.c
 * PIC:         PIC16F88
 * Author:      Julián Quiroga
 *
 * Descripción: Programa que enciende y apaga un LED de forma
 *              intermitente en RB0.
 */
#include <xc.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#include "system.h"
#include "user.h"


#define LED     PORTBbits.RB0 // El Led se encuentra conectado en RB0
#define posLED  0             // Posición en la que se encuentra el Led

/**
 * Programa principal
 */
void main(void) {

    // Configura el oscilador
    ConfigureOscillator();
    
    // Configura un 0 en la posición que le corresponde al LED
    // y un 1 a todas las demás.
    // 0 = Salida, 1 = entrada
    TRISB = ~(1 << posLED);
    // La línea anterior es equivalente a 
    // TRISB = 0b11111110;

    // Bucle principal
    while(true) {

        LED = 1;    // Setea en estado alto (High) el LED
        
        __delay_ms(500); // Se queda esperando 500 milisegundos
        
        LED = 0;    // Setea en estado bajo (Low) el LED
        
        __delay_ms(500);

    }
}

El código anterior define 2 macros: LED y posLED. Estos macros permiten que podamos cambiar de lugar en led haciendo mínimos cambios en el código.

LED indica el lugar en el que se seteará un 1.
posLed indica la posición del LED en el puerto B.

La instrucción: "1 << posLED" hace que el "1" de la izquierda se mueva tantos lugares a la izquierda como los que indica posLED. En este caso, como es "0", el resultado es un "1" que no se movió de lugar.

Luego, la instrucción "~" hace que todo lo que esté dentro del paréntesis quede negado, es decir, en bits, con el valor opuesto. Entonces en lugar de quedar todos ceros y un uno, ahora quedan todos unos y un cero: "0b11111110".

Ahora sólo nos queda compilar nuestro proyecto y ver que no tenga errores. Para hacer eso, hacemos click en el ícono que muestra un martillo, llamado "Build Main Proyect".


Si no hubo errores, el resultado de la compilación nos dirá algo similar a esto:

BUILD SUCCESSFUL (total time: 5s)

Ahora que ya tenemos nuestro primer proyecto compilado correctamente tenemos 2 opciones para probarlo, ejecutarlo en modo simulador o grabarlo en el PIC y probarlo en nuestro circuito.

En la parte 3 (Primer proyecto en XC8 (Parte 3) - Probando el código) de este tutorial les enseñaré como hacer esto.

Saludos!

Primer proyecto en XC8 (Parte 1) - Creación de proyecto


La mayoría de los ejemplos que voy a hacer están en el siguiente tutorial: http://www.gooligum.com.au/tut_baseline_C.html

Si seguimos los pasos que les indiqué aquí "Como configurar MPLABX para compilar con XC8 y MPASM", ya estamos listos para crear nuestro primer proyecto.

Lo que vamos a hacer será encender y apagar un led de forma intermitente. Para esto, vamos a necesitar de lo siguiente:

1 Fuente de alimentación de 5 Volts
1 Led de cualquier color
1 resistencia acorde al led anterior. (Cálculo de la resistencia para un LED)
1 protoboard + cables tipo alambre para poder conectar y desconectar todo fácilmente.
1 Pic: PIC16F88 (el código se puede adaptar para cualquier otro).
1 Grabador de pics: en mi caso, un simple grabador de pics JDM por puerto serial.

Creación de un proyecto en MPLABX


Lo primero que tenemos que hacer es crear un proyecto en MPLABX. Para esto, se debe seleccionar la opción "New Proyect":

Figura 1

Se nos abre un diálogo que nos permite seleccionar el proyecto que queremos crear.

Figura 2

Tenemos varias opciones:
a) Creamos nuestro proyecto desde 0.
b) Importamos el proyecto desde una versión anterior de MPLAB.
c) Utilizamos un Template.


Si seleccionamos un Template, por ejemplo "PIC16 Template" en la rama "Samples/Microchip Embedded" tendremos creado un proyecyo inicial con una configuración estándar.

En mi caso, prefiero crear el proyecto desde 0, o a lo sumo, copiar la estructura de un proyecto anterior.

Para crear un proyecto desde 0 se debe seleccionar la opción Standalone Proyect. En la siguiente pantalla debemos seleccionar el pic a programar, en mi caso es el PIC16F88.

Figura 3

Hacemos click en "Next". Ahora se nos pide que elijamos la herramienta que utilizaremos para hacer debug de nuestro programa. Como yo no dispongo de ninguna de las que aparecen en la lista, selecciono "Simulator" y luego Next:

Figura 4

Ahora debemos indicarle a MPLABX que compilador utilizar.

Figura 5
Como podemos observar, aparecen los 2 compiladores que agregamos en el post anterior. Vamos a seleccionar XC8 y luego Next.

Por último, debemos indicarle en qué lugar se guardará el proyecto y con qué nombre:
Figura 6

En mi caso, decidí nombrar los proyectos de la siguiente forma:
"PIC16F88_01_Led_Intermitente": [Modelo del Pic]_[Nro de proyecto]_[Descripción]

Luego de finalizar la creación del proyecto, la izquierda de la pantalla nos quedaría así:

Figura 7

Lo que muestra la imagen anterior es nuestro proyecto con todos los lugares en los que se agregará código. Los más importantes, para nosotros, son:

Header Files: Se agregan los archivos ".h" que contendrán la definición de macros, configuraciones y la cabecera de las funciones que crearemos.

Source Files: Se agregan los archivos ".c" que contendrán la funciones que se compilarán. La única función que no puede faltar es la llamada "main" que es el punto de entrada de toda aplicación ( a menos que se esté creando una librería).

Continúa en la siguiente entrada: "Primer proyecto en XC8 (Parte 2) - Código".

miércoles, 19 de septiembre de 2012

Cómo configurar MPLABX para compilar con XC8 y MPASM


Una de las cosas que me olvidé de mencionar en los posts anteriores era cómo configurar MPLABX para que nos permita compilar nuestros proyectos.

MPLAB X

Los pasos a seguir serían los siguientes:


1) Instalar MPLABX (http://www.microchip.com/pagehandler/en-us/family/mplabx/#downloads) siguiendo las instrucciones del instalador.

2) Instalar XC8 (http://www.microchip.com/pagehandler/en-us/family/mplabx/#downloads) también siguiendo las instrucciones del instalador.

Haciendo la instalación en este orden, el compilador ya se agrega a MPLABX. Si se instaló al revés no hay problema, el compilador se debe agregar manualmente.

Pasos para agregar XC8 a la lista de compiladores de MPLABX de forma manual:


Abrir MPLABX y hacer click en Tool/Options:


Figura 1
Hacer click en la la pestaña Embedded:

Figura 2


Ahora tenemos 2 opciones:

  1. Hacemos click en Scan for build Tools y seleccionamos el compilador si es que aparece.
  2. Hacemos click en Add y escribimos primero el directorio y luego el ejecutable principal.

Luego de esto hacemos click en Ok y ya estará todo configurado.

Con estos pasos es posible agregar cualquier otro compilador que se quiera probar.

Por ejemplo, además de XC8, también agregué MPASM para poder escribir código instrucción por instrucción en Assembler. (Más adelante lo voy a usar para compilar un bootloader).

Para que este post quede bastante acotado, voy a explicar como hacer nuestro primer proyecto XC8 en la siguiente entrada.

Hasta pronto.
Saludos!

Fuente de alimentación de 5 Volts

Para poder correr todos los ejemplos que voy a mostrarles, tenemos que tener una fuente regulada de +5V que es el voltaje estándar (TTL o transistor-transistor logic) para la comunicación entre componentes electrónicos lógicos.

Con estos 5V tenemos asegurada la velocidad máxima de instrucciones por segundo que nos indica la especificación de cada microcontrolador.


Por ejemplo, para el PIC16F88, si utilizamos el oscilador interno, la frecuencia máxima es de 8Mhz. Si utilizamos un cristal externo, el máximo es de 20MHz.

Nota: la cantidad de instrucciones por segundo se calcula dividiendo la frecuencia del procesador por 4 ya que internamente el pic hace esta división, por lo que, con 8 MHz tendremos 2 millones de instrucciones por segundo.

Si queremos que nuestro circuito gaste la menor cantidad de electricidad posible, podemos alimentarlo con menos voltaje ( según lo que especifica cada manual) y reducir la cantidad de instrucciones por segundo.

Por ejemplo, para el PIC16F88, el voltaje mínimo es de 2V y la frecuencia mínima es de 32kHz

Lo más común para obtener estos 5V es mediante el componente regulador de voltaje "7805" el cual nos permite conseguirlo a partir de 6 o 9V aproximadamente.

El circuito que seguí lo copié del siguiente enlace: Tutorial: Fuente de alimentación de 5V (Neo Teo), sólo que en lugar de utilizar un transformador y diodos para la entrada utilicé una batería de 9V.

Diagrama:

Diagrama de la fuente de alimentación de 5V


La salida de esta fuente es la que se utilizará para conectar nuestro pic y todos los circuitos accesorios que queramos agregarle.

Acá les adjunto una foto de cómo me quedó el circuito anterior con la diferencia que en lugar de utilizar los capacitores de 470uF utilicé unos de 100uF porque eran los de mayor capacidad que tenía disponibles:



Bueno, eso es todo por hoy. Al no pertenecer a  la rama de la electrónica, puede que no haya explicado bien algunos conceptos así que si ven que algo está mal escriben un comentario y lo corrijo.


Hasta la próxima.
Saludos,

lunes, 17 de septiembre de 2012

Configuración básica del PIC en XC8

Para que un pic funcione correctamente el mismo debe tener configuradas 1 o más "palabras" de configuración. Los bits de estas palabras permiten seleccionar, por ej.:, el tipo de oscilador a utilizar o si una patita del pic se usará como Reset.

En XC8 la configuración se setea mediante un Macro en el archivo "pic.h" y se escribe así "__CONFIG( bitsDeConfiguración )".

Cada línea "__CONFIG" representa una palabra de configuración. Para que funcione correctamente se deben escribir en el orden en el que aparecen en el PIC.

Ejemplo para el PIC16F88:


__CONFIG(MCLRE_ON & CP_OFF & CPD_OFF & LVP_OFF & BOREN_OFF & 
         WDTE_OFF & FOSC_INTOSCIO & PWRTE_OFF);
__CONFIG(IESO_OFF & FCMEN_OFF);



Las distintos bytes de configuración se concatenan mediante el caracter "&". Estos van a ser propios de cada pic. Por ejemplo, en la configuración anterior estamos indicando que el pin 4 actuará de Reset cuando no reciba corriente (MCLRE_ON) y utilizará el oscilador interno (FOSC_INTOSCIO).

Si en lugar de querer utilizar el oscilador interno se quisiera utilizar uno externo de 20Mhz la configuración cambiaría a:


__CONFIG(MCLRE_ON & CP_OFF & CPD_OFF & LVP_OFF & BOREN_OFF & 
         WDTE_OFF & FOSC_HS & PWRTE_OFF);
__CONFIG(IESO_OFF & FCMEN_OFF);


Como recomendación, estas configuraciones las coloco en un archivo de código separado. Esto me permite poder cambiar las diferentes configuraciones o generar archivos Template para crear nuevos proyectos. Ej.:

       "configuration_bits.c".

Aparte de la configuración hay 2 librerías extra que siempre agrego a mis proyectos:
- stdint.h: define los distintos tipos de datos de forma precisa y sin importar la arquitectura del procesador/controlador: Ej.: uint8_t : este tipo define que la variable es un entero de 8 bits sin signo

-stdbool.h: define tipos de datos boolean, por ej.:bool


ej.: bool inputValid = true;

Con la sintaxis anterior, el siguiente código queda más fácil de seguir:

bool inputValid = false;

while(!inputValid) {

     // Leer un valor desde el pin 0 del puerto B
     if (PORTBbits.RB0) {
          inputValid = true;
     }
}

Si no utilizamos stdbool.h quedaría así, por ejemplo:

uint8_t inputValid = 0;

while(!inputValid) {

     // Leer un valor desde el pin 0 del puerto B
     if (PORTBbits.RB0) {
          inputValid = 1;
     }
}




Saludos,
Related Posts Plugin for WordPress, Blogger...