Primero que nada, yo pienso que ese 7805 va a desaparecer de la faz del planeta tierra cuando conectes eso., de la salida de 12V a los 5V de salida hacen que caigan 7V en el 7805. Por otro lado no se con que vas a alimentar los leds, son 3W e imagino una caida de tension de 2 a 2.5V cada uno, asi que seguro que de la alimentacion de 12V, si llegas a sacarlo del regulador va a estallar tambien, ya que a este podes sacarle solo 1A caso extremo con muchisima disipacion/minima caida de tension. Si los alimenta con los 24V ahi puede sobrevivir ambos tal ves, todo va a depende de cuanto consuma tu circuito, acordate que en tu 7812 caen 12V, asi que un poco de corriente y ya estarias cerca del limite de potencia.
Bue dejando eso a un lado... Y volviendo a la programacion
Nunca he hecho un codigo PWM para PIC, asi que por eso pdio ayuda.
aqui creo que es donde se podria hacer eso
setup_timer_2(T2_DIV_BY_16, 255, 1);
Tenes que entender como funciona el PWM, te voy a dar 2 opciones PWM por HW y por SW, fijate que hay un diagrama en el datasheet. Basicamente funciona de esta forma.
Se carga el registro del CCP con un valor, suponete 200.
Se carga el registro PR indicando el periodo, 100.
Se configura el timer para saber cada cuanto cuenta. ( Aunque esa funcion que pasaste hace 2 de estas)
Entonces el TMR2 comienza de 0,salida en 1, el TMR aumenta y esta comparandose continuamente con PR y CCPRxH/L , cuando es igual a PR, pone 0 la salida. Entonces sigue aumentando hasta que es igual a CCPRxH/L ahi es cuadno se completo nuestro periodo, entonces solo el modulo CCP pone a 1 la salida y pone a 0 el TMR, para comenzar todo de nuevo.
Si podes hacer uso de estas salidas de PWM es genial, ya que te ahorra mucho codigo y trabajo del micro.
Pero a veces es complicado hacer periodos de PWM mas grandes, entonces tenes que usar un PWM por soft,
El PWM por soft basicamente intenta imitar eso. Si por ejemplo yo quisiera un periodo de 20ms, entonces mi TMR deberia interrumpir cada 20ms/x ( donde x son los pasos) si son por ejemplo 8 bits, es decir 255 , lo cual te quedaria que deberia producir una interrupcion cada 20ms/255 = 78uS, cada ves que interrumpe sumas 1 a un contador, y comparas con tus periodos de cada PWM, en codigo algo asi:
Int_TMR {
uint8_t i;
if(pwm1>i){salida_pwm1=0;}else{salida_pwm1=1;}
if(pwm2>i){salida_pwm2=0;}else{salida_pwm2=1;}
if(pwm3>i){salida_pwm3=0;}else{salida_pwm3=1;}
i++;
}
(observa que asumi que al ser de 8 bits va a pasar de 255 a 0, cuando sume 1 mas)
Cambiando los valores de pwm1 ,pwm2, pwm3 ya estarias cambiando el valor de cada uno.
Hay muchisimos ejemplos de PWM con CCS por internet.
Si yo queiro que la subida de 0 a 100% (0 a 255) sean 5 segundos como deberia hacerlo?
Bueno aqui entra tu manejo de las matematicas y usar un timer. basicamente deberias crear una recta. la ecuacion de la recta que pasa en 2 puntos
x1= tiempo inicial
x2= tiempo final
y1= valor inicial
y2= valor final
Supongamos entonces que vas de 0 a 255 (y1=0 y2=255), en 10 segundos ( x1=0 x2=10 )
pwm = 255/10 * (X-0) + 0
pwm =
Ax +
BA y B son los valores que debes encontrar. En este ejemplo A= 255/10 y B=0
Ahora si yo utilizo un timer para actualizar mi valor de pwm cada 1 segundo tengo:
para cuando pasaron 0 segundos => pwm=0
1 seg => pwm=255/10 o 25
2 seg => pwm=255/5 o 51
3 seg => pwm=765/10 o 76
Se observa un poco grande los pasos no?, si se quisiera algo mas suave en el cambio del birillo de los leds, podramos actualizarlo cada 0.5s
0s -> pwm=0
0.5s -> pwm=12
1s -> pwm=25
1.5s -> pwm=38
etc, ahora hay pasos mas chiquitos.
Yo utilize un timer por que queria que los cambios esten espaciados uno de otro de forma igual, pero si tu programa por ejemplo no tiene nada que hacer podria hacerlo de ahi, y loso deberias calcular el valor de cada uno de los PWM y actualizar sin necesidad de un timer.
Una cosa mas, en la ecuacion x1 puede ser siempre 0, si es que haces X2=(tiempo final - tiempo inicial) , es decir la diferencia, aqui vas a tener que trabajar con float.
Esa formula te permite calcular cualquier pendiente, asi que cuando termine una pendiente, calculas la otra y no calculas los valroes de pendiente y ordenada, y luego para sacar el pwm simplemente usas la ecuacion de pwm = A*tiempo transcurrido + B
Cuando usar segundos/minutos/horas? eso va a depender de que tan rapido actualizes tus leds, si tus rampas duran minutos hasta horas, entonces tal ves te conviene hacerlo con una base de tiempo de minutos y actualizar cada 30seg o 15 segundos.
Ahora si tus rampas duran segundos podes utilizar tambien minutos para X, pero se hace mas facil usando segundos, hay valores mas grandes. Ej:
de (x1,y1) a (x2,y2)
de (0,10) a (1,255) si tomo x como minutos
y= 245x + 10
Si mi timer interrumpe cada 1 segundos para actualizar los pwm, entonces cada ves que entra mi timer deberia multiplicar la cantidad de entradas por 1/60 , por ejemplo para el segundo 5 deberia hacer esta operacion:
y= 245*(5/60) + 10
de (0,10) a (60,255) usando x como segundos
y= 49/12 * X + 10
La diferencia aca es que si interrumpe cada 1 segundo mi timer para el segundo 5 solo reemplazaria el valor de 5 en X (o 5ta ves que entra), entonces se vuelve mas facil el trabajo de llevar las cuentas aca.
y= 49/12 * (5) + 10
Lo que elijas depende de tu programa y lo que intentas hacer.
Finalmente seguro que me vas a decir que tu rampa peude NO comenzar desde 0.. entonces por ejemplo si tenes una ramap del segundo 23 al 58 , de 50 a 100 pwm , entonces quedaria asi:
x1=23 ; x2=58 ; y1=50 ; y2=100
Y te queda una recta de :
y = 10/7 * X + 120/7
Si lees del DS1302 solo tomas los segundos y lo reemplazas ahi por la X, entonces cuando sean 23segundos esa formula da 0, para 33 segundos te da 64 y asi hasta los 58 que da 100, pero actualizas a cada segundo