Hola controleros y controleras, en esta entrada aprenderemos a usar el PWM con PIC (Modulación por Ancho de Pulso), la cual es una de las señales más utilizadas para realizar control con nuestros microcontroladores. Con lo que vamos a ver aqui aprenderás a configurar las velocidades del PWM PIC y al final del post te dejaré un código de implementación de ejemplo que puedes usarlo en cualquier microcontrolador PIC que tu uses. El código se encuentra en PIC C Compiler.
Antes que nada te hago la invitación para ver: CURSO GRATIS PIC
y para ver: LISTA DE REPORDUCCIÓN YOUTUBE.
PWM PIC
Para poder generar esta señal con nuestro PIC, se hace uso de los módulos CCP (Comparador, Captura y PWM). Dicho módulo permite realizar tres funciones básicas.
Comparar: Compara el valor del temporizador con el valor de un registro y provoca una acción en el PIC.
Captura: Obtiene el valor del temporizador en un momento dado, fijado por la acción de un terminal del PIC.
PWM: Genera una señal modulada por ancho de pulso.
En esta entrada, nos vamos a centrar en esta ultima, en el PWM. Para nuestro caso en especifico, como estamos usando el PIC16F887, dicho microcontrolador tiene 2 modulos CCP como se puede apreciar en la siguiente figura, los cuales corresponden a los PINES 16 y 17 (Correspondientes al puerto C, RC1 y RC2).
El módulo PWM (Pulse Width Modulation), permite obtener de los pines CCP1 (Pin 17) y CCP2 (Pin 16) una señal periódica (Es decir que se repite en el tiempo) la cual podemos modificar su ciclo de trabajo (Duty Cycle en ingles). Dicho PWM o Modulación por Ancho de Pulso, puede tener una resolución máxima de 10 BITS. En otras palabras. Como sabemos que el PIC trabaja con voltajes binarios (0V o +5V), podemos configurar el PWM para que trabaje un determinado tiempo en +5V (Ton) frente al tiempo que está en nivel bajo 0V (Toff), tal y como lo podemos apreciar en la siguiente figura.
De esta manera, la tensión media aplicada a la carga, es proporcional al tiempo en que la señal estuvo en +5V (Ton) y asi podemos por ejemplo controlar la luminosidad de lamparas, o la velocidad de un motor.
La resolución de salida del modulo CCP es de 10 bits, y para que funcione correctamente, no debemos olvidar configurarlo como salida en el TRIS C.
Esta señal PWM funcina igual en cualquier microcontrolador, lo único que cambia es la forma como se configura en cada plataforma. Por ejemplo si te interesa, puedes darle un vistazo a como configurar el PWM con Arduino.
MODULO CCP EN C PARA PWM PIC – Modulación por Ancho de Pulso
El compilador nos suministra dos instrucciones basicas para el manejo del PWM.
Para configurar el módulo CCP:
setup_ccpx(modo);
Donde modo hace referencia a los bits CCPxM3:CPxM0 del registro CCPxCON y en PIC C puede ser configurado según la siguiente tabal:
El ciclo de trabajo para el PWM se define como:
set_pwmx_duty(valor);
donde el x hace alusión al modulo CCP a utilizar, en el caso del PIC16F887 solo tiene CCP1 y CCP2, así que si queremos usar el PWM del PIN 17 ponemos set_pwm1_duty(valor); y si queremos usar el PWM del PIN 16 ponemos set_pwm2_duty(valor);
Valor es un dato de 10 bits (int16) que determina el ciclo de trabajo o ancho de pulso, es decir ese valor va a determinar el porcentaje en que la señal de PWM se va a mantener encendida. Este valor junto con el valor del preescaler del TMR2 definen el ciclo de trabajo. En la configuración del TIMER 2 el postcaler debe valer 1.
- Prescaler determina el tiempo de interrupción. Con este podemos disminuir el clock interno del timer, puede tomar valores de 1, 4, o 16.
- El Postcaler es un número de 1-16 que dice cuántas veces el Timer2 tiene que desbordarse para llamar a la interrupción (1 es una vez, 2 es 2 veces, y así sucesivamente).
Por ejemplo, si se determina con el Prescaler y el Periodo del Timer2 un tiempo de 1s para el desbordamiento, pero realmente se quieren 2s, entonces se coloca el Postcaler en 2.
Como comenté anteriormente el ancho de Pulso ó Ciclo de trabajo para el modulo CCP del PIC puede tener como máximo un valor de 10 bits, eso si, ésta resolución depende exclusivamente del periodo del PWM que nosotros queramos implementar.
Como uso estas instrucciones?
Para generar una señal de Modulación por Ancho de Pulso con el PIC, tenemos que utilizar el TIMER 2, el cual es un Timer de 8 Bits.
Internamente el PIC, usa el TIMER 2 como base de tiempo para la Modulación por Ancho de Pulso (PWM) utilizando el módulo CCP.
Con la siguiente formula podemos calcular la frecuencia de salida
donde: El Prescaler del TIMER 2 Puede ser 1, 4 o 16, es la frecuencia del PWM y
La carga del Timer 2 (conocido como PR2), también podría ser llamada como el Periodo de la Señal y puede tomar valores entre 0 y 255, debido a que es un registro de 8 bits.
Considerando que vamos a utilizar un cristal de cuarzo de 4Mhz, calculemos cual seria la frecuencia mínima para dicho cristal.
Valor mínimo:
Valor Máximo:
Recordando claro, que estos son valores teóricos.
Listo, ya sabemos que lo primero que debemos encontrar es el valor de carga del timer 2 (PR2) y que éste depende del tipo de cristal que estamos usando y depende de los valores de preescaler que nosotros seleccionemos (1,4 o 16).
Resolución del PWM
La resolución determina el número de ciclos de trabajo (duty cicle) disponibles para un período determinado. Por ejemplo, una resolución de 10 bits dará como resultado 1024 ciclos de trabajo discretos, mientras que una resolución de 8 bits dará como resultado 256 ciclos de trabajo discretos.
La resolución máxima de PWM es de 10 bits cuando PR2 es 255. La resolución es una función del valor del registro PR2.
Si observamos la ecuación de frecuencia del PWM,
Note que si la carga del timer 2 (PR2) fuera su valor máximo (255) el resultado de esa operación nos daría 1024
4 (255 + 1) = 1024
Entonces para saber cuantos bits tenemos en una señal PWM a la frecuencia que nosotros deseamos, podriamos representar ese termino como [4 (PR2 + 1)] =
Así, podriamos reescribir la ecuación de la frecuencia del PWM como:
Y como lo que queremos es determinar la resolución, simplemente despejamos n de la ecuación anterior aplicando logaritmos a ambos lados de la igualdad:
Este valor es equivalente a la ecuación mostrada en el datasheet del 16F887:
Con ese valor de resolución de ancho de pulso (n) sabremos cuanto es el Duty Cicle que debemos colocar.
Duty Cicle
Como vimos anteriormente el ancho de pulso del pwm es configurado por:
set_pwmx_duty(valor);
Dado que previamente se tuvo que calcular el valor de la carga del timer 2 (PR2), es importante destacar que el valor de la Carga del Timer 2 NUNCA puede ser mayor que el ancho de pulso (Variable valor).
En este punto somos capaces de determinar el máximo número que puede tomar el duty cicle (int16) que se coloca en el parámetro de entrada de la función set_pwmx_duty(valor);
valor=4(PR2 +1)=2^n
Vamos ahora a configurar el PIC utilizando un ejemplo Práctico.
Ejemplo 1 del uso del PWM PIC – Modulación por Ancho de Pulso
Vamos a generar una señal cuadrada de 1Khz utilizando el TIMER 2 y el módulo CCP1 del PIC usando nuestro compilador CCS C. Con un cristal de cuarzo de 4MHz.
Solución:
Para generar una señal cuadrada de 1Khz es necesario calcular primero el periodo (Inverso de la frecuencia) f=1Khz=1000hz.
Periodo de 1ms (mili-segundo) o 0,001 segundos donde T=Periodo.
El periodo del oscilador del PIC (en este caso usando un cristal de cuarzo externo de 4MHz como oscilador) viene dado por:
Ahora necesitamos calcular el desbordamiento del TIMER 2 con la siguiente formula.
T_{PWM}=(PR2+1)*4*(Preescaler\ del\ TIMER\ 2)*T_{Osc}
Reemplzando valores tenemos que:
Obtenemos que el valor de PR2=249. (Recordando que PR2 tiene que estar entre 0-255, por eso se escoge un preescaler de 4)
El Timer 2 quedaría así:
setup_timer_2(T2_DIV_BY_4,249,1);
Ahora solo nos falta determinar el valor de resolución para saber cuanto es lo máximo que podremos variar el ancho de pulso (duty cicle), aplicando cualquiera de las 2 formula para el cálculo de la resolución tenemos:
Vemos que con ambas ecuaciones llegamos al mismo resultado.
El máximo ancho de pulso (duty cicle) lo voy a obtener colocando la variable valor:
valor=2^n=2^{9.9657} = 1000
O también puedo calcularlo como:
valor=(249+1)*4 = 1000
El duty cycle es configurado entonces por la siguiente instrucción:
set_pwm1_duty(valor);
Donde si valor vale 0, tendre un ciclo de trabajo del 0%, si valor vale 1000, tendré un ciclo de trabajo de 100%, si valor vale 500, tendré un ciclo de trabajo de 50%
Si se ingresa un número directamente en la función, se recomienda ingresarla por medio de un cast para forzar que ese número sea un int16. Por ejemplo, quiero tener un 25% del ciclo de trabajo:
set_pwm1_duty((int16)250);
PWM PIC – Ejemplo 2
Si se necesita una frecuencia de la señal PWM de 4Khz, y se utiliza con el microcontrolador PIC con un oscilador o cristal de 4Mhz, se tendrían que realizar los siguientes cálculos:
Para generar una señal cuadrada de 4Khz es necesario calcular primero el periodo (Inverso de la frecuencia) f=4Khz=4000hz.
Periodo de 0,250ms (mili segundos) donde T=Periodo.
Ahora necesitamos calcular el desbordamiento del TIMER 2 (PR2) con la siguiente formula.
T_{PWM}=(PR2+1)*4*(Preescaler\ del\ TIMER\ 2)*T_{Osc}
El PR2 debe estar entre 0 – 255. Para conseguir esto el preescaler puede ser 1, 4 o 16, con cualquiera va a cumplir. Se selecciona para este ejemplo un preescaler de 16, para estudiar como esto va a afectar enormemente la resolución. Reemplzando valores tenemos que:
Obtenemos que el valor de PR2=14,625. Así como necesitamos un valor entero, redondeamos PR2=15.
El Timer 2 quedaría así, empleando un postcaler de 1:
setup_timer_2(T2_DIV_BY_16,15,1);
El máximo ancho de pulso (duty cicle) lo voy a obtener colocando la variable valor:
valor=(PR2+1)*4=(15+1)*4 = 64
Una resolución de 64 es muy baja y pobre, si comparamos con su máxima resolución que sería 1024. El duty cycle es configurado entonces por la siguiente instrucción:
set_pwm1_duty(valor);
Donde si valor vale 0, tendre un ciclo de trabajo del 0%, si valor vale 64, tendré un ciclo de trabajo de 100%, si valor vale 32, tendré un ciclo de trabajo de 50%
Si se ingresa un número directamente en la función, se recomienda ingresarla por medio de un cast para forzar que ese número sea un int16. Por ejemplo, quiero tener un 25% del ciclo de trabajo:
set_pwm1_duty((int16)16);
Código de Implementación del PWM PIC
Vamos a llevar a la practica el concepto del PWM del PIC:
EJEMPLO
Existen muchos procesos electrónicos o industriales donde necesitamos controlar la velocidad de un Motor DC. Una manera simple de lograr este objetivo es utilizar un control por PWM. Para esto vamos a diseñar el siguiente circuito y el código del microcontrolador por medio del compilador CCS C con el fin de poder regular la velocidad de un Motor DC por medio de un potenciometro conectado al Terminal RA0 (Para esto sera necesario utilizar el concepto de conversión análogo digital visto en el Post anterior).
En el post de interrupciones PIC encontrarás una mejora de esta práctica donde además de regular la velocidad del motor, se mide la velocidad del mismo a través de un encoder. (Click aqui para ir al post de Interrupciones PIC).
Para poder controlar el motor de 12 V necesitamos utilizar un Mosfet.
Los mosfets de potencia (power mosfets) son componentes electrónicos que nos permiten de controlar corrientes muy elevadas. Como en el caso del los mosfets comunes, tienen tres terminales de salida que se llaman: Drain, Source y Gate (D, S y G). La corriente principal pasa entre Source y Drain (ISD) mientras que el control de esta corriente se obtiene aplicando una tensión sobre el terminal Gate (respecto al terminal Source), conocida como VGS.
Código – PWM PIC C Compiler:
A continuación se presenta el código de uso del PWM PIC (Modulación por Ancho de Pulso) para que lo copies y lo pegues en tu compilador y puedas reproducirlo. Recuerda que para ver el código debes compartir o darle me gusta al contenido de este post para que más personas se beneficien de esta información.
El ejemplo esta en PWM PIC16f887, sin embargo te muestro como usar el programa PWM PIC 16F877A e incluso como usar el programa en el PIC18F4550. En conclusión te sirve para cualquier PIC.
// Por: Sergio Andres Castaño // https://controlautomaticoeducacion.com/ //___________________________________________________________________________ #include <16f887.h> #device ADC=10 #fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT,INTRC_IO #use delay(clock=4000000) int16 duty=0; int Timer2,Poscaler; void main() { // Generemos una Señal cuadrada de 1 Khz Timer2=249; //Se carga timer 2 con 249 como lo vimos en la pagina //Preescaler=4; //Preescaler solo puede tomar valores de: 1 - 4 - 16 //Para el preescaler colocamos "t2_div_by_4" Poscaler=1; //Preescaler solo puede tomar valores de: 1 setup_timer_2(t2_div_by_4,Timer2,Poscaler); //Configuracion de Timer 2 para establecer frec. PWM a 1kHz setup_ccp1(ccp_pwm); //Configurar modulo CCP1 en modo PWM setup_adc_ports(all_analog); //Configurar ADC setup_adc(adc_clock_internal); while(1) { set_adc_channel(0); delay_us(100); duty=read_adc(); set_pwm1_duty(duty); } }
Si desean utilizar el PWM PIC 18F4550 CCS o cualquier otro de la familia 18, debes cambiar el encabezado por:
#include <18f4550.h> #byte porta = 0xf80 // Identificador para el puerto A. #byte portb = 0xf81 // Identificador para el puerto B. #byte portc = 0xf82 // Identificador para el puerto C. #byte portd = 0xf83 // Identificador para el puerto D. #byte porte = 0xf84 // Identificador para el puerto E.
Si desean utilizar el PWM PIC 16F877A o cualquier otro de la familia 16, debes cambiar el encabezado por:
#include <16f877A.h>
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.
Mi nombre es Sergio Andres Castaño Giraldo, y en este sitio web voy a compartir una de las cosas que mas me gusta en la vida y es sobre la Ingeniería de Control y Automatización. El sitio web estará en constante crecimiento, voy a ir publicando material sobre el asunto desde temas básicos hasta temas un poco más complejos. Suscríbete al sitio web, dale me gusta a la página en Facebook y únete al canal de youtube. Espero de corazón que la información que comparto en este sitio, te pueda ser de utilidad. Y nuevamente te doy las gracias y la bienvenida a control automático educación.