Control para dimer de 8 canales individuales con el micro controlador PIC16f877a
“Un buen día” recordé que en un video del youtube presentaban un proyecto el cual consistía en un juego de luces tipo auto fantástico, es decir que el led encendido iba de izquierda a derecha dejando una estela como la de un cometa, en ese momento solo me llamo la atención como algo curioso, también leí por ahí que debería estar hecho en base a salidas PWM (esto para generar la impresión de la estela dejada al paso del led principal). Ahora que “no sé qué hacer (me estoy aburriendo de mí mismo)… jajajajajajaj”, me dije “que tal si haces uno de esos, así te distraes un poco”, fue así que empecé con este pequeño proyecto.
************************************************** ****************************
1 Condiciones base del proyecto.
El proyecto constara de 8 salidas PWM (modulación por ancho de pulso) para el control de potencia para aplicaciones DC (corriente directa) que pueden ser manipuladas independientemente una de otra.
El proyecto costara de 8 salidas PPM (modulación por posición de pulso) para el disparo de triac, esto para el control de potencia por fase para aplicaciones de AC (corriente alterna) que puedan ser manipuladas independientemente una de otra.
Tanto las señales PWM y PPM serán controladas simultáneamente por los 8 canales conversores analógicos a digitales (ADC) disponibles en un PIC 16f877a.
El proyecto deberá ser flexible en el sentido de poder modificarlo fácilmente en caso de usar otro medio de control de las señales PWM y PPM distinto de los canales ADC del microcontrolador, adicionalmente poder cambiar los pines de las salidas PWM y PPM a gusto.
2 Tips para el diseño del proyecto.
2.1 Modulación por ancho de pulso (PWM).
La modulación por ancho de pulso consiste en un tren de pulsos de onda rectangular con frecuencia constante cuyo parámetro a variar es el ancho de pulso o ciclo de servicio.
El ciclo de servicio es está definido por la relación entre el tiempo de nivel alto y el periodo de la onda rectangular.

“Un buen día” recordé que en un video del youtube presentaban un proyecto el cual consistía en un juego de luces tipo auto fantástico, es decir que el led encendido iba de izquierda a derecha dejando una estela como la de un cometa, en ese momento solo me llamo la atención como algo curioso, también leí por ahí que debería estar hecho en base a salidas PWM (esto para generar la impresión de la estela dejada al paso del led principal). Ahora que “no sé qué hacer (me estoy aburriendo de mí mismo)… jajajajajajaj”, me dije “que tal si haces uno de esos, así te distraes un poco”, fue así que empecé con este pequeño proyecto.
************************************************** ****************************
1 Condiciones base del proyecto.
El proyecto constara de 8 salidas PWM (modulación por ancho de pulso) para el control de potencia para aplicaciones DC (corriente directa) que pueden ser manipuladas independientemente una de otra.
El proyecto costara de 8 salidas PPM (modulación por posición de pulso) para el disparo de triac, esto para el control de potencia por fase para aplicaciones de AC (corriente alterna) que puedan ser manipuladas independientemente una de otra.
Tanto las señales PWM y PPM serán controladas simultáneamente por los 8 canales conversores analógicos a digitales (ADC) disponibles en un PIC 16f877a.
El proyecto deberá ser flexible en el sentido de poder modificarlo fácilmente en caso de usar otro medio de control de las señales PWM y PPM distinto de los canales ADC del microcontrolador, adicionalmente poder cambiar los pines de las salidas PWM y PPM a gusto.
2 Tips para el diseño del proyecto.
2.1 Modulación por ancho de pulso (PWM).
La modulación por ancho de pulso consiste en un tren de pulsos de onda rectangular con frecuencia constante cuyo parámetro a variar es el ancho de pulso o ciclo de servicio.
El ciclo de servicio es está definido por la relación entre el tiempo de nivel alto y el periodo de la onda rectangular.

Para generar la onda rectangular se definirá una frecuencia de 100 Hz (T=10ms), para el cual se empleara el temporizador 0 del microcontrolador.
La interrupción temporizada se disparara cada 100us para obtener una resolución del 1%
La variable ciclo guardara el valor del ciclo de servicio de la señal PWM y la variable n hará de contador para verificar si se llegó al valor del ciclo de servicio.
2.2 Modulación por posición de pulso (PPM).
La modulación por posición de pulso conste en un tren de pulsos de onda rectangular con frecuencia constante y ancho de pulso constante, el parámetro a variar es posición de pulso.
Para generar la señal PPM (modulación por ancho de pulso) se utilizara el temporizador 1, su interrupción se disparara cada 100us para obtener una resolución de 1%.
La variable ángulo es la encargada de guardar el momento en el que se generara el pulso. El pulso tendrá una duración de 100us.
Para sincronizarlo con la red eléctrica se utilizara la interrupción externa disparada por flancos.
3 Código y esquema básico.
El programa está realizado en CCS PIC
La interrupción temporizada se disparara cada 100us para obtener una resolución del 1%
La variable ciclo guardara el valor del ciclo de servicio de la señal PWM y la variable n hará de contador para verificar si se llegó al valor del ciclo de servicio.
2.2 Modulación por posición de pulso (PPM).
La modulación por posición de pulso conste en un tren de pulsos de onda rectangular con frecuencia constante y ancho de pulso constante, el parámetro a variar es posición de pulso.
Para generar la señal PPM (modulación por ancho de pulso) se utilizara el temporizador 1, su interrupción se disparara cada 100us para obtener una resolución de 1%.
La variable ángulo es la encargada de guardar el momento en el que se generara el pulso. El pulso tendrá una duración de 100us.
Para sincronizarlo con la red eléctrica se utilizara la interrupción externa disparada por flancos.
3 Código y esquema básico.
El programa está realizado en CCS PIC
Código:
/*********************************************************************
Este programa hace la lectura de los 8 canales del ADC del pic, según
el valor de cada canal y mediante un factor de escala genera 8 señales
PWM(pensado para dimer DC) individuales por el puerto D y 8 señales
PPM(pensado para dimer AC) individuales por el puerto C, cada salida
PWM y PPM están en función del valor capturado por cada canal del ADC.
La frecuencia del PWM es 100Hz
*********************************************************************/
#include <16f877a.h>
#fuses xt,nowdt
#device adc=10
#use delay(clock=20M)
/****************************************************/
#define ppm0 pin_c0
#define ppm1 pin_c1
#define ppm2 pin_c2
#define ppm3 pin_c3
#define ppm4 pin_c4
#define ppm5 pin_c5
#define ppm6 pin_c6
#define ppm7 pin_c7
/****************************************************/
#define pwm0 pin_d0
#define pwm1 pin_d1
#define pwm2 pin_d2
#define pwm3 pin_d3
#define pwm4 pin_d4
#define pwm5 pin_d5
#define pwm6 pin_d6
#define pwm7 pin_d7
/*****************************************************
Variables para guardar los valores leídos por el ADC
/****************************************************/
unsigned int16 dato_adc0;
unsigned int16 dato_adc1;
unsigned int16 dato_adc2;
unsigned int16 dato_adc3;
unsigned int16 dato_adc4;
unsigned int16 dato_adc5;
unsigned int16 dato_adc6;
unsigned int16 dato_adc7;
/*****************************************************
Variables para el ciclo de servicio del PWM (0-100%)
/****************************************************/
unsigned int8 ciclo0=0;
unsigned int8 ciclo1=0;
unsigned int8 ciclo2=0;
unsigned int8 ciclo3=0;
unsigned int8 ciclo4=0;
unsigned int8 ciclo5=0;
unsigned int8 ciclo6=0;
unsigned int8 ciclo7=0;
/*****************************************************
Variables para el posición de pulso de PPM (Angulo de disparo para el TRIAC de 0-97%)
*****************************************************/
unsigned int8 angulo0=97;
unsigned int8 angulo1=97;
unsigned int8 angulo2=97;
unsigned int8 angulo3=97;
unsigned int8 angulo4=97;
unsigned int8 angulo5=97;
unsigned int8 angulo6=97;
unsigned int8 angulo7=97;
/***************************************************/
unsigned int8 n=0; //contador para la señal PWM
unsigned int8 m; //contador para la señal PPM
/***************************************************/
#int_ext
void detector_cruce_por_cero()
{
if(input_state(pin_b0))
{
ext_int_edge(h_to_l);
}
else
{
ext_int_edge(l_to_h);
}
set_timer1(65085);
setup_timer_1(t1_internal|t1_div_by_1);
m=0;
if(angulo0==0)
{
output_high(ppm0);
}
if(angulo1==0)
{
output_high(ppm1);
}
if(angulo2==0)
{
output_high(ppm2);
}
if(angulo3==0)
{
output_high(ppm3);
}
if(angulo4==0)
{
output_high(ppm4);
}
if(angulo5==0)
{
output_high(ppm5);
}
if(angulo6==0)
{
output_high(ppm6);
}
if(angulo7==0)
{
output_high(ppm7);
}
}
#int_timer1
void ppm()
{
set_timer1(65077);
if(input_state(ppm0))
{
output_low(ppm0);
}
else
{
if(m==angulo0)
{
output_high(ppm0);
}
}
if(input_state(ppm1))
{
output_low(ppm1);
}
else
{
if(m==angulo1)
{
output_high(ppm1);
}
}
if(input_state(ppm2))
{
output_low(ppm2);
}
else
{
if(m==angulo2)
{
output_high(ppm2);
}
}
if(input_state(ppm3))
{
output_low(ppm3);
}
else
{
if(m==angulo3)
{
output_high(ppm3);
}
}
if(input_state(ppm4))
{
output_low(ppm4);
}
else
{
if(m==angulo4)
{
output_high(ppm4);
}
}
if(input_state(ppm5))
{
output_low(ppm5);
}
else
{
if(m==angulo5)
{
output_high(ppm5);
}
}
if(input_state(ppm6))
{
output_low(ppm6);
}
else
{
if(m==angulo6)
{
output_high(ppm6);
}
}
if(input_state(ppm7))
{
output_low(ppm7);
}
else
{
if(m==angulo7)
{
output_high(ppm7);
}
}
m++;
}
#int_timer0
void generar_pwm()
{
delay_cycles(1);
set_timer0(28);
if(n>=ciclo0)
{
output_low(pwm0);
}
else
{
output_high(pwm0);
}
if(n>=ciclo1)
{
output_low(pwm1);
}
else
{
output_high(pwm1);
}
if(n>=ciclo2)
{
output_low(pwm2);
}
else
{
output_high(pwm2);
}
if(n>=ciclo3)
{
output_low(pwm3);
}
else
{
output_high(pwm3);
}
if(n>=ciclo4)
{
output_low(pwm4);
}
else
{
output_high(pwm4);
}
if(n>=ciclo5)
{
output_low(pwm5);
}
else
{
output_high(pwm5);
}
if(n>=ciclo6)
{
output_low(pwm6);
}
else
{
output_high(pwm6);
}
if(n>=ciclo7)
{
output_low(pwm7);
}
else
{
output_high(pwm7);
}
if(n==100)
{
n=0;
}
else
{
n++;
}
}
void main()
{
setup_adc(adc_clock_internal);
setup_adc_ports(all_analog);
output_d(0);
enable_interrupts(global);
enable_interrupts(int_ext_l2h);
enable_interrupts(int_timer1);
enable_interrupts(int_timer0);
setup_timer_0(t0_internal|t0_div_2);
while(true)
{
set_adc_channel(0);
delay_ms(1);
dato_adc0=read_adc(adc_start_and_read);
set_adc_channel(1);
delay_ms(1);
dato_adc1=read_adc(adc_start_and_read);
set_adc_channel(2);
delay_ms(1);
dato_adc2=read_adc(adc_start_and_read);
set_adc_channel(3);
delay_ms(1);
dato_adc3=read_adc(adc_start_and_read);
set_adc_channel(4);
delay_ms(1);
dato_adc4=read_adc(adc_start_and_read);
set_adc_channel(5);
delay_ms(1);
dato_adc5=read_adc(adc_start_and_read);
set_adc_channel(6);
delay_ms(1);
dato_adc6=read_adc(adc_start_and_read);
set_adc_channel(7);
delay_ms(1);
dato_adc7=read_adc(adc_start_and_read);
ciclo0=dato_adc0/10;
ciclo1=dato_adc1/10;
ciclo2=dato_adc2/10;
ciclo3=dato_adc3/10;
ciclo4=dato_adc4/10;
ciclo5=dato_adc5/10;
ciclo6=dato_adc6/10;
ciclo7=dato_adc7/10;
angulo0=102-ciclo0;
angulo1=102-ciclo1;
angulo2=102-ciclo2;
angulo3=102-ciclo3;
angulo4=102-ciclo4;
angulo5=102-ciclo5;
angulo6=102-ciclo6;
angulo7=102-ciclo7;
if(angulo0>97)
{
angulo0=97;
}
if(angulo1>97)
{
angulo1=97;
}
if(angulo2>97)
{
angulo2=97;
}
if(angulo3>97)
{
angulo3=97;
}
if(angulo4>97)
{
angulo4=97;
}
if(angulo5>97)
{
angulo5=97;
}
if(angulo6>97)
{
angulo6=97;
}
if(angulo7>97)
{
angulo7=97;
}
}
}
Adjuntos
Última edición por un moderador: