#include <16f819.h>
//#device ADC=8;
#FUSES INTRC_IO, NOCPD, PROTECT, NOMCLR, NOPUT,nowdt,nolvp
#use delay(clock=8000000)//relog para el 12f1822
#define moc pin_b3
//#byte apfcon = 0x11D//se define el registro apfcon debido a que ccs no lo tiene configurado
//#include "dimer_16.h"
int1 zero_c=0;
int16 trigger=0;
int1 re_f=0;
void init()
{
setup_adc(adc_off);
setup_adc_ports(no_analogs);
set_tris_a(0b00000000);
set_tris_b(0b00000101);
output_low(moc);
setup_ccp1(ccp_capture_fe);//se configura el modulo ccp1 en modo captura en flanco descendente para leer el sensor
setup_timer_1(t1_internal|t1_div_by_2); //se configura el timer uno para que se incremente cada 1us (4*div/osc) (4MHz)
//setup_timer_0(t0_internal|t0_div_64);//se configura el timer para que se desborde cada 8.192ms(4*div/osc) (4MHz)
re_f=0;
ext_int_edge(h_to_l);//interrupcion externa para el cruce por cero
enable_interrupts(int_ext);
set_timer0(0);
// enable_interrupts(int_ccp1);
enable_interrupts(global);
}
void main()
{
init();
trigger=6;
while(true)
{
if(zero_c==1)
{
zero_c=0;
}
}
}
#int_ext //interrupcion para detectar el cruce por cero de la linea de AC
void cruce_0()
{
if(re_f)
{
ext_int_edge(h_to_l);
re_f=0;
}
else
{
ext_int_edge(l_to_h);
re_f=1;
}
delay_ms(7);
output_high(moc);//si es menor a 10 entonces el triac nunca se prende
delay_us(150);
output_low(moc);
zero_c=1;
clear_interrupt(int_ext);
}
#include <16f819.h>
//#device ADC=8;
#FUSES INTRC_IO, NOCPD, PROTECT, NOMCLR, NOPUT,nowdt,nolvp
#use delay(clock=8000000)//relog para el 12f1822
#define moc pin_b3
//#byte apfcon = 0x11D//se define el registro apfcon debido a que ccs no lo tiene configurado
//#include "dimer_16.h"
int1 zero_c=0;
int16 trigger=0;
int1 re_f=0;
void init()
{
setup_adc(adc_off);
setup_adc_ports(no_analogs);
set_tris_a(0b00000000);
set_tris_b(0b00000101);
output_low(moc);
setup_ccp1(ccp_capture_fe);//se configura el modulo ccp1 en modo captura en flanco descendente para leer el sensor
setup_timer_1(t1_internal|t1_div_by_2); //se configura el timer uno para que se incremente cada 1us (4*div/osc) (4MHz)
//setup_timer_0(t0_internal|t0_div_64);//se configura el timer para que se desborde cada 8.192ms(4*div/osc) (4MHz)
re_f=0;
ext_int_edge(h_to_l);//interrupcion externa para el cruce por cero
enable_interrupts(int_ext);
set_timer0(0);
// enable_interrupts(int_ccp1);
enable_interrupts(global);
}
void main()
{
init();
trigger=6;
while(true)
{
if(zero_c==1)
{
zero_c=0;
delay_ms(7);
output_high(moc);//si es menor a 10 entonces el triac nunca se prende
delay_us(150);
output_low(moc);
}
}
}
#int_ext //interrupcion para detectar el cruce por cero de la linea de AC
void cruce_0()
{
if(re_f)
{
ext_int_edge(h_to_l);
re_f=0;
}
else
{
ext_int_edge(l_to_h);
re_f=1;
}
zero_c=1;
clear_interrupt(int_ext);
}
y porque usa el cruce por cero? para dimmer Led basta con un Transistor Mosfet o un CI , o me imagino que esta dimmando la alimentacion del Led. puede poner el circuito como lo hace ?
Será que tu circuito para el cruce por cero te esta metiendo pulsos indeseados que hace que la interrupción se ejecute varias veces mientras intenta ejecutar lo que hace en el while.
Ademas, falta la configuración de la frecuencia del oscilador interno a 8Mhz: setup_oscillator.
Uy! si habré renegado hace unos años con esto...
Te doy una posible respuesta al problema. Si lo soluciona te explico la teoría que me llevó a pensar que puede ser eso. :mrgreen:
modificá el segundo código a:Código: C
if(zero_c==1) { disable_interrupts(global); zero_c=0; delay_ms(7); output_high(moc);//si es menor a 10 entonces el triac nunca se prende delay_us(150); output_low(moc); clear_interrupts(int_ext); enable_interrupts(global); }
Aunque puede que te des cuenta en base al código. Los tiempos "muertos" son distintos entre el cambio de flanco de L_TO_H y de H_TO_L. Si marcas en la senoidal los momentos de cambio vas a podés apreciarlo.
Coloca como configuras el timer porque en el código que colocas.
La interrupción por timer, puede ser que no te este funcionando porque no has activado la interrupción por timer:
enable_interrupts(int_timer0)
ademas de que configuras timer1 y usas el timer0.
En cada interrupción externa por cruce por cero tienes que setear al valor que quieres del timer para que vuelva a contar: set_timer0(...)
y por lo del segundo, seria como dice stk500, que coloques el circuito.
Creo que la rutina del Timer va a implementarla luego. En este momento no está logrando siquiera poder encender de forma pareja la carga lo mas cercana al 100% mediante disparos acertados del MOC, que es el primer paso para luego mover el punto de disparo y poder dimmerizar (ahi sí usando un Timer).
Saludos.
#include <16f819.h>
//#device ADC=8;
#FUSES INTRC_IO, NOCPD, PROTECT, NOMCLR, NOPUT,nowdt,nolvp
#use delay(clock=8000000)//relog para el 12f1822
#define moc pin_b3
#define led pin_a1
//#byte apfcon = 0x11D//se define el registro apfcon debido a que ccs no lo tiene configurado
//#include "dimer_16.h"
int16 cnt=0;
int1 zero_c=1;
char trigger=0;
int1 re_f=0;
char vals[11]={25,26,27,28,29,30,31,32,33,34,35};
void init()
{
setup_adc(adc_off);
setup_adc_ports(no_analogs);
set_tris_a(0b00000000);
set_tris_b(0b00000101);
setup_oscillator( OSC_8MHZ );
output_low(moc);
setup_ccp1(ccp_capture_fe);//se configura el modulo ccp1 en modo captura en flanco descendente para leer el sensor
setup_timer_1(t1_internal|t1_div_by_2); //se configura el timer uno para que se incremente cada 1us (4*div/osc) (4MHz)
setup_timer_0(t0_internal|t0_div_64);//se configura el timer para que se desborde cada 8.192ms(4*div/osc) (4MHz)
re_f=0;
ext_int_edge(h_to_l);//interrupcion externa para el cruce por cero
enable_interrupts(int_ext);
set_timer0(0);
// enable_interrupts(int_ccp1);
enable_interrupts(global);
}
void main()
{
init();
trigger=0;
while(true)
{
}
}
int1 on_moc=0;
int cc=0;
#int_ext //interrupcion para detectar el cruce por cero de la linea de AC
void cruce_0()
{
if(zero_c)
{
enable_interrupts(int_timer0);
set_timer0(trigger);
on_moc=0;
}
zero_c=0;
cnt++;
if(cnt==240)
{
output_toggle(led);
trigger=vals[cc];
cc++;
if(cc==11)cc=0;
//if(trigger>250)trigger=0;
cnt=0;
}
if(re_f)
{
ext_int_edge(h_to_l);
re_f=0;
}
else
{
ext_int_edge(l_to_h);
re_f=1;
}
disable_interrupts(int_ext);
}
#int_timer0
void activar()//interrupcion por timer0, se desborda maximo cada 8.19 ms, si se le da un valor al regitro del timer0 se desbordada antes, y en ese momento se prendera el triac, entre mayor sea el valor del tmr0 el triac estara prendido mayor tiempo
{
if(trigger>10)output_high(moc);//si es menor a 10 entonces el triac nunca se prende
else output_low(moc);
set_timer0(0);//se reinicia el contador
delay_us(100);
output_low(moc);
clear_interrupt(int_timer0);
disable_interrupts(int_timer0);
enable_interrupts(int_ext);
set_timer0(0);
zero_c=1;
}
Es muy raro porque cuando falla, lo hace en un punto de mayor potencia dentro de la senoidal que en el resto de los valores, lo que no debería ser problema alguno para dispararlo correctamente.
Apuntaría hacia la lámpara esa, sí. Seguramente con una lámpara común no se comporte así, excepto se haya dañado algún componente del circuito...
Esperaremos a ver las pruebas.
Saludos