Saltar al contenido
Control Automático Educación

Configuración de Clock y Oscilador en PIC con CCS C

Hola controleros y controleras, hoy vamos a aprender sobre los Tipos de Clock del PIC, el ciclo de máquina, la velocidad de trabajo del microcontrolador PIC y la configuración de los distintos osciladores que el microcontrolador nos ofrece utilizando el compilador PIC C Compiler CCS C.

En esta entrada vas a ver que el compilador PIC C Compiler CCS C nos ofrece diversas alternativas para la configuración del reloj del microcontrolador, es decir que existen varias formas de configurar el clock del PIC y tú podrás escoger la que mejor te convenga.

Antes de comenzar te invito a que veas nuestro CURSO GRATUITO DE MICROCONTROLADORES PIC.

Y que te suscribas al canal de YouTube para continuar recibiendo entrenamiento en la programación de estos dispositivos embebidos.

Ciclo de Máquina por Instrucción

Inicialmente entendamos que nuestro microcontrolador, deberá recibir una señal de sincronia por medio de un oscilador para poder ejecutar sus instrucciones, dependiendo de el tipo de reloj seleccionado nuestro microcontrolador conseguira rodar más rápido o más lento el programa y al mismo tiempo tendremos más o menos capacidad de precisión en el tiempo.

La arquitectura del microcontrolador PIC está configurada para trabajar siempre con una frecuencia de reloj dividido por 4, el cual corresponde a la frecuencia de procesamiento interno del microcontrolador.

\dfrac{F_{clock}}{4}

Cristal 4MHz para Microcontrolador PIC
Cristal de 4 MHz que puede ser usado como fuente de reloj externa para el microcontrolador PIC

Eso significa que si colocamos a trabajar nuestro microcontrolador con una velocidad de 4MHz (internos o externos) realmente el ciclo de máquina interno del microcontrolador va a trabajar a 1MHz.

\dfrac{4MHz}{4}=1MHz

Lo que significa que cada ciclo de maquina (Cada instrucción de código dentro del PIC en Assembler) va a tomar 1 micro-segundo.

\dfrac{1}{1MHz}=1\mu s

Función del oscilador de un microcontrolador

El oscilador del microcontrolador es el encargado de producir una señal de sincronismo para que el dispositivo embebido consiga ejecutar la tarea para la cual está programado. Sin este oscilador el PIC no conseguiria trabajar adecuadamente.

Existen diferentes fuentes de clock para el microcontrolador como el cristal externo, el clock interno propio del pic, realizar un circuito RC (resistencia-Condensador) o proporcionarle una señal periódica a través de un generador de señales o otro circuito externo.

Instrucciones de delay del compilador

Como vimos en la entrada pasada sobre los delay en el microcontrolador PIC, ya sabemos como poner a nuestro microcontrolador a perder tiempo. Más adelante con la introducción de las interrupciones por timer con PIC, veremos que las funciones delay no son muy adecuadas en procesos que requieran una buena medida de tiempo.

Este tiempo de delays va a depender de la configuración del reloj que coloquemos en nuestro microcontrolador

Configuración del Clock con CCS

Las configuraciones del microcontrolador van muy relacionado con los #FUSES, para el caso del reloj bien sea interno o externo debemos configurar adecuadamente estos #FUSES.

Configurando los Fuses

Dependiendo del tipo de velocidad a ser empleado y siempre apoyándonos del datasheet debemos configurar los siguientes fuses:

fuses pic

Los cristales de cuarzo deben ser conectados en los pins CLKI y CLKO, el cual podrás buscar en el datasheet de cada componente.

clock pic
Cristal de Cuarzo en PIC16F887 y PIC18F4550

Si deseamos configurar el clock interno adicionalmente debemos colocar lo siguiente, en caso de usar la función setup oscillator que está explicado en la parte final de este post

#fuses INTRC_IO 
#use delay(clock=500000) 
void main()
{
   setup_oscillator(OSC_500KHZ|OSC_INTRC); //Cristal interno de 500KHz
}

Sin embargo, la siguiente directiva es utilizada en el compilador para poder especificarle a nuestro dispositivo la velocidad con la cual va a trabajar y también el tipo de reloj a emplear en nuestro proyecto.

Configurando el #use_delay

Sintaxis:

#use_delay (opciones)

Opciones:

puede ser cualquiera de las siguientes opciones todas separadas por comas:

  • clock=speed; la constante speed es la velocidad a la que queremos que trabaje el microcontrolador y puede ser de 1-100000000 (1 hz a 100 mhz).

Este número puede contiener comas. Este número también admite las siguientes denominaciones: M, MHZ, K, KHZ.

Esto especifica el reloj con el cual va a trabajar el CPU del microcontrolador. Dependiendo del PIC esta velocidad es 2 o 4 veces la tasa de instrucción.

Esta directiva no es necesaria colocarla si se usa type = speed y no hay multiplicación o división de frecuencia.

  • type = speed la instrucción del compilador ccs C de type define qué tipo de reloj está utilizando y los siguientes valores son válidos:
  1. oscillator, osc (cuando se usa un oscilador);
  2. crystal, xtal (cuando se usa un cristal);
  3. internal, int (Cuando se usa el cristal interno del pic)
  4. rc (Cuando se usa un circuito RC).

El compilador establecerá automáticamente los bits de configuración del oscilador basado en su tipo definido. Si se especificó el cristal interno, el compilador también configura automáticamente el oscilador interno a la velocidad definida. Los fusibles de configuración son modificados cuando se usa esta opción.

La constante speed es la velocidad establecida en frecuencia.


El oscilador interno del PIC 16F887 al igual que el PIC16F877A  o el 18F4550 puede ser configurado con frecuencias desde 8MHz hasta 32KHz, para eso solo basta configurar en la directiva de la función setup_oscillator como:

  • 8MHZ
  • 4MHZ
  • 2MHZ
  • 1MHZ
  • 500KHZ
  • 250KHZ
  • 125KHZ
  • 32KHZ

  • restart_wdt reiniciará el temporizador de vigilancia del perro guardian en cada uso de las funciones delay_us () y delay_ms ().
  • clock_out cuando se usa con los tipos internos u osciladores, esto permite que el pin de clockout muestre la salida del reloj.
  • fast_start algunos chips permiten que el chip comience a ejecutarse usando un reloj interno hasta que el reloj primario se estabilice.
  • lock algunos chips puede evitar que el tipo de oscilador se cambie mientras se está ejecutando el software.
  • USB o USB_FULL para dispositivos con un periférico USB incorporado. Cuando se usa con el type=speed, el compilador establecerá los bits de configuración correctos para el periférico USB para operar a toda velocidad.
  • USB_LOW para dispositivos con un periférico USB incorporado. Cuando se usa con la opción type = speed, el compilador establecerá los bits de configuración correctos para que el periférico USB funcione a baja velocidad.

Descripción:

Le dice al compilador la velocidad del procesador y permite el uso de las funciones integradas:

delay_ms() y delay_us(). También establecerá los bits de configuración adecuados y, si es necesario, configurará el oscilador interno, la velocidad es en ciclos por segundo.

Ejemplos de Configuración

Algunos ejemplos de configuración del Reloj los podemos ver a continuación:

// Configurar el tiempo a 32KHz, se usa los fuses
// en delay_us() y en delay_ms()
#use delay (clock=32000, RESTART_WDT)
//4 Ejemplos que muestran la configuración del tiempo:
//Para usar un reloj de 20Mhz, donde la fuente es un cristal de cuarzo
#use delay (crystal=20000000)
#use delay (xtal=20,000,000)
#use delay(crystal=20Mhz)
#use delay(clock=20M, crystal)
//Para configurar un reloj  a 10Mhz con un oscillator, 
//pero usando el multiplicador PLL por 4 para aumentar la velocidad
//a 40MHz. El compilador configurará los bits si se usa:
#use delay(oscillator=10Mhz, clock=40Mhz)
//Para utilizar un Reloj Interno a 8MHz usamos la siguiente directiva
//donde el compilador configurará los bits para habilitar
//el oscilador a 8MHz.
#use delay(internal=8Mhz)
// si se desea ver la salida del reloj interno por el pin CLKO
#use delay(internal=8Mhz,clock_out)

setup_oscillator( )

Esta es otra directiva opcional para configurar el oscilador dentro del compilador. Si quieres ver un ejemplo de su uso, eso se hará en un video más avanzado del curso, cuando implementemos el código de un Servo Motor con PIC.

Sintaxis:

setup_oscillator(mode, finetune)

Parametros

mode: Depende del chip. Por ejemplo, algunos chips permiten la configuración de velocidad como OSC_8MHZ o OSC_32KHZ. Otros chips permiten cambiar la fuente como OSC_TIMER1.

finetune – (solo permitido en ciertas partes) es un int con signo, con un rango de -31 a +31.

Retorna

Algunos dispositivos devuelven un estado como OSC_STATE_STABLE para indicar que el oscilador es estable.

Función:

Esta función controla y devuelve el estado del oscilador RC interno en algunas partes. Consulte el archivo .h del dispositivo para ver las opciones válidas para un PIC en particular.

Tenga en cuenta que si se especifica INTRC o INTRC_IO en #fuses y se usa un #USE DELAY para una opción de velocidad válida, entonces el compilador realizará esta configuración automáticamente al inicio de main().

Advertencia

Si se cambia la velocidad en tiempo de ejecución, el compilador puede no generar los retrasos correctos para algunas funciones integradas. El último #USE DELAY encontrado en el código va a ser tomado como la velocidad correcta. Puede tener varias líneas #USE DELAY para controlar el conocimiento del compilador sobre la velocidad.

Sintaxis 2

setup_oscillator(mode, target ,source ,divide )

Parametros:
mode – puede ser:

  • OSC_INTERNAL
  • OSC_CRYSTAL
  • OSC_CLOCK
  • OSC_RC
  • OSC_SECONDARY

target – es la frecuencia a la que va a correr el PIC.

source – es opcional. Especifica la frecuencia externa del cristal / oscilador. Si se omite, se utiliza el valor del último #USE DELAY. Si el modo es OSC_INTERNAL, la fuente es un valor de sintonía opcional para el oscilador interno para los dispositivos que lo admiten. Si se omite, un valor de sintonización se usa entonces cero.

divide in – es opcional. Para los dispositivos que lo admiten, especifica la relación de división para el reloj de interfaz del módulo de pantalla. Un número de 0 a 64 divide el reloj de 1 a 17 aumentando en incrementos de 0.25, un número de 64 a 96 divide el reloj de 17 a 33 aumentando en incrementos de 0.5, y un número de 96 a 127 divide el reloj de 33 a 64 aumentando en incrementos de 1. Si se omite, se usará cero para dividir por 1.

Función – Configura el oscilador con configuraciones de fuente interna y externa preestablecidas. Si los fusibles del dispositivo están configurados y se especifica #use delay(), el compilador configurará el oscilador. Utilice esta función para la configuración explícita o la programación de interrupciones de reloj dinámico. Consulte las hojas de datos de destino para obtener configuraciones válidas, especialmente cuando utilice el multiplicador PLL, ya que se especifican muchas restricciones de rango de frecuencia.

Tipos de circuitos generadores de reloj para un microcontrolador

Como hemos visto anteriormente podemos utilizar diferentes fuentes de reloj para dar los sincronismos a nuestro microcontrolador. Aquí mostramos brevemente algunos tipos de osciladores externos que pueden ser usados con el microcontrolador.

Circuito RC

Se puede usar la carga y descarga de un condensador como un tipo de clock para el PIC y configurarlo en el CCS. Sin embargo recuerda que esta configuración solo es adecuada para cuando el tiempo no sea fundamental para el proyecto.

En esta configuración es recomendable ver la frecuencia de carga y descarga del capacitor con un osciloscópio, para posteriormente re-grabar el microcontrolador con la frecuencia correcta.

Clock RC para microcontrolador PIC
Clock RC para microcontrolador PIC
#INCLUDE <16f887.h>
#fuses RC, NOWDT, PUT, NOMCLR,BROWNOUT,NOLVP
#use delay(clock=4MHz)

Oscilador Externo via 555

Podemos tener una fuente de oscilador externo que llegue al PIN CLKI para dar los sincronismos de clock en el PIC.

Si usamos el integrado 555 en modo Astable puedes configurar el oscilador externo del pic16f877a, pic16f887 , pic18f4550 o cualquier otro PIC.

El circuito mostrado a continuación está configurado para otorgar una frecuencia aproximada de 100KHz, con un duty cicle próximo al 50% en la salida Q.

Note que en esta configuración el PIN RA6 puede se utilizado en el programa como un I/O (Pin de entrada o salida) en nuestro proyecto.

Oscilador Externo 555 con PIC
Oscilador Externo 555 con PIC
#INCLUDE <16f887.h>
#fuses EC, NOWDT, PUT, NOMCLR,BROWNOUT,NOLVP
#use delay(clock=101700)

Cristal de Cuarzo

Otro tipo de clock del PIC es el cristal de cuarzo el cual como vimos en el video es uno de los más precisos junto con el oscilador externo visto anteriormente.

Este cristal realmente es otro tipo de oscilador externo disponibles para nuestro microcontrolador. A continuación mostramos el ejemplo para uno de 4MHz.

clock PIC Cristal de Cuarzo de 4MHz
Cristal de Cuarzo de 4MHz en PIC16F887
#INCLUDE <16f887.h>
#fuses XT, NOWDT, PUT, NOMCLR,BROWNOUT,NOLVP
#use delay(clock=4000000,crystal)

Oscilador Interno PIC

Hay várias formas de configurar el oscilador interno en PIC16F877a, 16F887, 18F4550, etc. Y es porque el compilador CCS nos ofrece las diferentes opciones que vimos anteriormente.

Clock Interno del PIC a 4MHz
Oscilador Interno del PIC a 4MHz

Forma 1

#INCLUDE <16f887.h>
#fuses XT, NOWDT, PUT, NOMCLR,BROWNOUT,NOLVP
#use delay(internal=4000000)

Forma 2

#INCLUDE <16f887.h>
#fuses INTRC_IO, NOWDT, PUT, NOMCLR,BROWNOUT,NOLVP
#use delay(clock=4MHZ) 
void main(){
   setup_oscillator(OSC_4MHZ|OSC_INTRC); //Cristal interno de 4MHz
}

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.