TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Cossworth en 13 de Noviembre de 2008, 00:34:22
-
Hola, ya que pude hacer andar el pwm, pasamos al siguiente problema. Tengo ganas de conseguir un efecto RGB con 3 focos de distintos colores (corriente alterna).
La idea es hacerlo como si fueran 3 dimmers y mediante la variacion del brillo de cada uno conseguir toda la escala cromatica.
Hasta ahora hice un código sin probar, es para que me digan que opinan:
#include <16F628a.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#byte port_a=0x05
#byte port_b=0x06
#bit luzroja = port_b.0
#bit luzverde = port_b.1
#bit luzazul = port_b.2
#bit pin = port_a.4
#define delay 5
int8 paso, rojo, azul, verde;
#int_Timer0
void color() {
paso++;
if (paso==rojo) { // Si se cumple el delay deseado prendo la lampara
luzroja=1;
};
if (paso==verde) {
luzverde=1;
};
if (paso==azul) {
luzazul=1;
};
if (pin==estado) { //Si no hubo cambio de estado (semiciclo positivo/negativo)
set_timer0(39) //cargo timer
};
else { //si hubo cambio apago todo y vuelvo a 0 el contador de pasos
luzroja=0;
luzverde=0;
luzazul=0;
paso=0;
estado=!estado; //si era semiciclo positivo ahora es negativo
set_timer0(39); // Medio Ciclo de alterna dura 10ms, 256 valores en 10ms, el calculo da 39 aprox
};
}
void demo(){ //esto muestra toda la escala cromatica como en el ejemplo de PWM
rojo=0;
azul=250;
verde=250;
for (verde=250;verde>0;verde--)
delay_ms(delay);
for (rojo=0;rojo<250;rojo++)
delay_ms(delay);
for (azul=250;azul>0;azul--)
delay_ms(delay);
for (verde=0;verde<250;verde++)
delay_ms(delay);
for (rojo=250;rojo>0;rojo--)
delay_ms(delay);
for (azul=0;azul<250;azul++)
delay_ms(delay);
rojo=250;
}
void main()
{
set_tris_b(0b00000000);
set_tris_a(0b11111111);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
if (pin==0) //si estoy en semiciclo negativo...
estado=0; //...guardo el estado en una variable
else // si estoy en semiciclo positivo lo mismo
estado=1;
while(pin==estado){}; //ciclo vacio hasta que haya cambio de estado (se puede hacer?)
set_timer0(39) //una vez que hubo cambio de estado cargo el timer
while (true) {
demo(); //luego ejecuto la demo siempre
};
}
Bueno, como verán el codigo debe estar plagado de imperfecciones porque ni siquiera lo compile todavia.
Tengo una duda con respecto a ese ciclo vacio, no se si se puede utilizar de esa forma.
Espero sus comentarios a ver si con su ayuda logro hacer andar ésto, si anda prometo videito de la lampara que estoy armando jajaja
Muchas gracias de antemano :)
-
Lo suyo es que lo compiles y veas qué tal funciona. Sabiendo los síntomas es más fácil depurar los errores.
-
Lo suyo es que lo compiles y veas qué tal funciona. Sabiendo los síntomas es más fácil depurar los errores.
Luego de solucionar algunos errores de sintaxis, ya lo compile. El codigo final es éste:
#include <16F628a.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#byte port_a=0x05
#byte port_b=0x06
#bit luzroja = port_b.0
#bit luzverde = port_b.1
#bit luzazul = port_b.2
#bit pin = port_a.4
#define delay 5
int8 paso, rojo, azul, verde;
#int_Timer0
void color() {
paso++;
if (paso==rojo) {
luzroja=1;
};
if (paso==verde) {
luzverde=1;
};
if (paso==azul) {
luzazul=1;
};
if (pin==estado) {
set_timer0(39)
};
else {
luzroja=0;
luzverde=0;
luzazul=0;
paso=0;
estado=!estado;
set_timer0(39);
};
}
void demo(){
rojo=0;
azul=250;
verde=250;
for (verde=250;verde>0;verde--)
delay_ms(delay);
for (rojo=0;rojo<250;rojo++)
delay_ms(delay);
for (azul=250;azul>0;azul--)
delay_ms(delay);
for (verde=0;verde<250;verde++)
delay_ms(delay);
for (rojo=250;rojo>0;rojo--)
delay_ms(delay);
for (azul=0;azul<250;azul++)
delay_ms(delay);
rojo=250;
}
void main()
{
set_tris_b(0b00000000);
set_tris_a(0b11111111);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
if (pin==0)
estado=0;
else
estado=1;
while(pin==estado){};
set_timer0(39)
while (true) {
demo();
};
}
Quisiera saber como se puede simular en Proteus este circuito, tendria que generar una onda senoidal de 50hz como la corriente alterna y hacerla pasar por el circuito, no? se puede realizar esto?
Saludos!
-
Puedes conectar un generador, que hay entre las herramientas.
Entre las propiedades tiene la tension y la frecuencia a la que quieres trabajar... :mrgreen:
-
Gracias por el tip del generador, estuve un rato hasta encontrarlo, es que nunca habia simulado nada con proteus.
Estoy hace unos dias buscandole la vuelta y no pasa nada, simplemente las salidas no se activan, ni se si detecta cruce por cero, por esto recurro a ustedes, a ver si alguien puede verlo y darme algun consejo, no pretendo que me solucionen el problema, pero alguna pista para ver donde puede estar el error.
Aca adjunto el codigo, el hex, y el archivo de la simulacion.
Desde ya muchas gracias, saludos!
-
Alguna idea sobre que puede ser mi problema? cargué la simulacion con un programa en ASM que hace justamente lo que yo quiero hacer, y tampoco se observa nada, puede ser que se ejecute demasiado rapido para el proteus y por eso no se vea nada?