martes, 10 de marzo de 2015

Microchip PIC: PWM + ADC + MOTOR + PIC12F683

En este capítulo, vamos a mostrar como configurar el módulo CAPTURE/COMPARE/PWM (CCP) en modo PWM, y para ello, hemos escogido al microcontrolador PIC12F683.

La idea de este programa es leer la señal analógica ofrecida por un potenciómetro y dependiendo de dicho valor, actualizar la anchura de pulso del PWM. Y para verlo de manera visual, hemos elegido el ejemplo clásico por excelencia, controlar la velocidad de un motor mediante la anchura de pulso PWM.


Pero antes de enseñar el firmware, vamos a pararnos brevemente en el funcionamiento del módulo CCP en su configuración de PWM. Para empezar, prestaremos especial atención al documento: Mid-Range Reference Manual, en el apartado:   14. Compare/Capture/PWM (CCP), concretamente en el subapartado 14.5  PWM Mode, donde viene explicado el funcionamiento de éste módulo.

Hay un dicho que dice que vale más una imagen que mil palabras, pues bien, dentro de dicho subapartado, nos encontraremos con la siguiente imagen:



Pues bien, en esta imagen, se explica los elementos necesarios que intervienen cuando queremos configurar el módulo CCP en modo PWM. Pero antes de seguir, ¿qué es PWM?

Sencillo, dichas siglas vienen del inglés: Pulse-Width Modulation (modulación de anchura de pulso), dicho en cristiano, con éste módulo podremos cambiar la anchura de un pulso a una frecuencia determinada, donde dicho pulso, estará presente en un pin de nuestro microcontrolador.


Por lo tanto, lo primero que deberemos determinar es la frecuencia/periodo a la que queremos trabajar, para ello, disponemos de la siguiente expresión:


PWM_Periodo = ( PR2 + 1 )·4·T_OSC·( TMR2 Prescale Value )


Donde:


· PR2  ≡  Carga del Timer 2
· T_OSC ≡ Periodo del reloj principal
· TMR2 Prescale Value ≡ Prescale del Timer 2


Por ejemplo, imaginemos que queremos un periodo de 1ms ( 1 kHz ), el reloj principal es de 8 MHz y el TMR2 Prescale va a ser de 16, calculemos el valor de carga del Timer 2 para que satisfaga dichas condiciones:


( 1000 )^( -1 )  = ( PR2  + 1 )·4·[  ( 8·10^6  )^( -1 )  ]·( 16 )

Despejamos:


· PR2 = 124


En estos momentos, ya tendremos configurado nuestro PWM a una frecuencia de 1 kHz.



Otro de los datos que necesitamos configurar va a ser la anchura del pulso, para ello, disponemos de la siguiente expresión:


Anchura del Pulso = ( CCPR1L:CCP1CON< 5:4 > )·T_OSC·( TMR2 Prescale Value )


Donde:


· CCPR1L:CCP1CON< 5:4 > ≡  Carga del registro CCP para determinar la anchura del pulso
· T_OSC ≡ Periodo del reloj principal
· TMR2 Prescale Value ≡ Prescale del Timer 2


¿Qué quiere decir: CCPR1L:CCP1CON< 5:4 >? Pues es simple, teóricamente disponemos de 10-bits para el módulo CCP:

· CCPR1L dispone de 8-bits.
· CCP1CON< 5:4 >, dos bits más, concretamente el bit 5 y 4 del registro CCP1CON.

Siguiendo con el ejemplo anterior, tenemos configurado un pulso a una frecuencia de 1 kHz, vamos a calcular que valor cargar para que la anchura del pulso sea la mitad, es decir al 50%:


[ ( 1000 )^( -1 ) ]/2  = ( CCPR1L:CCP1CON< 5:4 > )·[  ( 8·10^6  )^( -1 )  ]·( 16 )


Despejamos:


· CCPR1L:CCP1CON< 5:4 > = 250 ( 0xFA, 0b11111010 )


Por lo tanto, si queremos una anchura de pulso del 50% a una frecuencia de 1 kHz, deberemos cargar los registros tal y como se muestra a continuación:


· CCP1CON < 4 > = 0b0 
· CCP1CON < 5 > = 0b1


Al haberse usado los dos bits menos significativos, el resultado que tenemos es el siguiente:  0b111110 ( 0x3E ), y dicho valor se cargará al registro que nos queda:


· CCPR1L = 0x3E


En este momento, ya tenemos una anchura de pulso al 50%, ¿y qué quiere decir esto? Pues que en un ciclo de 1 kHz, la mitad estará en alta y la otra mitad en baja.



Y el último dato que nos queda por saber es la resolución, no siempre vamos a tener disponibles los 10-bits del módulo CCP, esto dependerá de a qué frecuencia queremos que funcione nuestro PWM, para saber la resolución, disponemos de la siguiente expresión:



Resolución = [ ln ( 4·( PR2 + 1 ) ) ]/ln ( 2 ) bits



Y siguiendo con nuestro ejemplo, vamos a calcular nuestra resolución:



· Resolución = [ ln ( 4·( 124 + 1 ) ) ]/ln ( 2 ) ≈ 8.97 = 8 bits


A la configuración deseada, tenemos una resolución de PWM de 8-bits.



Y ya sin más dilación, vamos a presentar nuestro programa, éste consistirá en leer por el pin GP4/AN3 la señal analógica procedente de un potenciómetro que, dependiendo de su valor, actualizará la anchura de pulso del módulo PWM, esto se verá reflejado en la velocidad de un motor conectado al pin GP2/COUT.


El material que vamos a necesitar y su función, es la que se muestra a continuación:

· PIC12F683: Microcontrolador para este programa.

· Protoboard: Donde insertaremos nuestros componentes.

· PICKIT 3: Programador y depurador necesario para programar el código.

· Transistor NPN: Un transistor NPN de propósito general, en nuestro caso C9013.

· Resistor 1 KΩ: Se conectará al pin GP4/COUT ( señal PWM ) y a la base del transistor NPN.

· Resistor 4.7 kΩ: Un resistor que irá conectado entre los pins #MCLR y VDD.

· Potenciómetro: Del menor valor posible, en nuestro caso, hemos usado uno de 1 kΩ, que irá conectado al pin GP4/AN3.

· Motor: Un motor DC, en nuestro caso hemos usado uno obtenido de una antigua impresora.



El firmware es el que se muestra a continuación:

/**
* @file     main.c
* @author   Manuel Caballero
* @date     3/3/2015
* @brief    Archivo principal.
* \copyright
*      AqueronteBlog@gmail.com
*
* Este archivo es propiedad intelectual del blog Aqueronte,
* cuya direccion web, es la siguiente:
*
*   http://unbarquero.blogspot.com/
*
* Se permite cualquier modificacion del archivo siempre y cuando
* se mantenga la autoria del autor.
*/
#include < xc.h >
#include < stdint.h >
#include "variables.h"
#include "functions.h"
#include "interrupts.h"

/**
 *  \brief     void main( void )
 *  \details   Este programa consiste en mostrar como funciona el módulo CCP en
 *             modo PWM.
 *
 *             En este caso, el programa consiste en leer una señal analógica
 *             mediante el módulo ADC 10-bits, y dependiendo de su valor,
 *             la señal PWM cambiará haciendo que un motor gire a más o menos
 *             velocidad.
 *
 *             Se usará el módulo Timer1, 16-bits, para gestionar tanto la
 *             lectura del módulo ADC 10-bits como actuaizar el PWM.
 *
 *
 *  \author    Manuel Caballero
 *  \version   0.0
 *  \date      3/3/2015
 *  \pre       Este firmware está probado para el PIC12F683.
 *
 *  \pre       MPLAB X IDE v2.30.
 *  \pre       Compiler XC8 v1.33.
 */
void main( void ) {

   conf_CLK    ();     // Configura Relojes
   conf_ADC10  ();     // Configura ADC10
   conf_PWM    ();     // Configura PWM ( módulo CCP )
   conf_TA1    ();     // Configura Timer1

        
   INTCONbits.PEIE     =   1;      // Peripheral Interrupt Enable
   ei  ();                         // enable interrupts
    
   while ( 1 );        // Todo se realiza en las interrupciones
}

Como vemos, el ejemplo es bastante simple, se recomienda bajar los archivos disponibles más abajo para indagar entre sus librerías y leer sus funciones de manera más detallada.

Un vídeo que demuestra lo explicado anteriormente se presenta a continuación:



Os pongo a vuestra disposición el programa en lenguaje C (XC8 y CCS) para que lo podáis descargar y probar:

Microchip PIC: PIC12F683  + ADC10 + MOTOR + PWM
Compilador XC8Compilador CCS
CC
PIC12F683: PWM + MOTOR 
PIC12F683: PWM + MOTOR
PIC12F683: PWM + MOTOR
PIC12F683: PWM + MOTOR

· NOTA 1Lo comentarios están en formato doxygen. Aunque no se entrega dicha documentación ya que el MPLAB X no tiene ningún pulgin capaz de trabajar con dicho formato.

· NOTA 2: Se incluye la simulación en PROTEUS del programa. La versión entregada de PROTEUS es v7.10 SP0.

2 comentarios:

Unknown dijo...

No me deja descargar el codigo del compilador CCS

Unknown dijo...

Buenas Sebastian:

Sólo está disponible el código para el compilador de Microchip XC8.

Un saludo.