Mostrando entradas con la etiqueta __CONFIG. Mostrar todas las entradas
Mostrando entradas con la etiqueta __CONFIG. Mostrar todas las entradas

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.

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...