TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Cryn en 20 de Mayo de 2007, 02:47:03

Título: Dimmer con TMR0
Publicado por: Cryn en 20 de Mayo de 2007, 02:47:03
saludos acabo de hacer este codigo para controlar un dimmer (10 pasos) usando el TMR0 e INT EXT para el paso por cero; el detector produce un cambio de estado en su salida cada vez qeu cruza por cero, qeudo asi:

Código: [Seleccionar]
#include <16f88.h>
#fuses HS,NOWDT,NOLVP,PUT,MCLR,NOBROWNOUT
#use delay(clock=8000000)

int j=0,count=0;
signed int disparo=0;

#INT_EXT
void CrucePor0()
{
   set_timer0(5);
   if (j==0){
   j=1;
   ext_int_edge(H_TO_L); // Cambio la detección del flanco, para que la proxima sea de bajada
   }
   else {
   j=0;
   ext_int_edge(L_TO_H); // La próxima interrupción será de subida
   }
}

#INT_TIMER0
void tmr_handler()
{
   count++;
   set_timer0(5);
   if(count==10)
   count=0;
   if(count==disparo)
   {
      output_high(PIN_B4);
      delay_us(300);
      output_low(PIN_B4);
   }
}

void main()
{
   set_tris_a(0xff);
   set_tris_b(0xef);
   setup_adc_ports(NO_ANALOGS);
   setup_timer_0(RTCC_DIV_8|RTCC_INTERNAL);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_EXT);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   do
   {
      if(input(PIN_A0))
      {
         delay_ms(20);
         while(input(PIN_A0))
            delay_ms(20);
         disparo++;
         if(disparo==10)
            disparo=9;
      }
      if(input(PIN_A1))
      {
         delay_ms(20);
         while(input(PIN_A1))
            delay_ms(20);
         disparo--;
         if(disparo==-1)
         disparo=0;
      }
   }while(true);
}

lo que hago es incrementar y decrementar un contador de disparo con pulsadores en A0 y A1 respectivamente; el timer genera interrupcion cada 1ms, si el disparo (variable modificada por A0 y A1) es igual al contador de interrupciones (count), entonces se genera un pulso para disparar el triac, y asi sucesivamente, en el programa principal se controla los pulsadores. Hago esto porque quisiera incluirle un mando IR, y el buen amigo nocturno me mencionó alguna vez que para usar el mado debop usar el timer y sus interrupciones, voy por buen camino? algo para corregir? o es qeu escribi codigo malo talvez? no puedo ver una simulación precisa.

Talvez me ocupo todo el tiempo para ver las interrupciones del timer0 y no pueda ver al mando IR, puedo apagar TMR0 despues de disparar el triac y encender en INT EXT (cuando detecte cruce por cero), talvez sea mas efectivo, o como le hago? alguna sugerencia??

gracias. adios.
Título: Re: Dimmer con TMR0
Publicado por: Nocturno en 20 de Mayo de 2007, 03:10:28
Yo creo que vas bien Cryn.
Y no temas no poder simularlo; este tipo de aplicaciones no se pueden hacer con un simulador, sino con un circuito real.
Ánimo.
Título: Re: Dimmer con TMR0
Publicado por: Cryn en 20 de Mayo de 2007, 13:21:03
holas, gracias por la respuesta, me das animos, jeje, pero mira nose si recuerdas qeu hace unos meses hice un dimmer sin mando IR y con retardos ciclicos (osea usando delay_ms(xxx)), ahi si podia simular, porque observaba la señal AC en un puerto del osciloscopio, y la señal de disparo en el otro puerto, y se lograba ver que cuando aumentaba o disminuía el disparo (con pulsadores) el tren de disparo se desfazaba, hasta llegar al limite de ida y vuelta, y pues llevandolo a la practica fue un regalo, jeje, y ahora no puedo ver el desface qeu te menciono, pues es algo raro, nose, pienso que deberia lograr ver lo mismo, weno, pero no importa lo probare con circuito real despues, pues me he quedado sin tiempo ahora por examenes pero despues vuelvo a la marcha.

Pero por ahora que te parece la idea que mencione?:
Talvez me ocupo todo el tiempo para ver las interrupciones del timer0 y no pueda ver al mando IR, puedo apagar TMR0 despues de disparar el triac y encender el tmr0 en INT EXT (cuando detecte cruce por cero), talvez sea mas efectivo, o como le hago?

y que te parece hasta ahora el codigo, lo leiste?? crees que funcione???

muchas gracias, adios, os comentare los resultados en cuanto lo pruebe
Título: Re: Dimmer con TMR0
Publicado por: Nocturno en 20 de Mayo de 2007, 15:32:09
Me refiero a que es imposible simular la captura de tramas IR, pero no al dimmer.
Yo no he mirado tu código en profundidad, pero aunque podría ser depurado, parece que vas bien. No te preocupes demasiado por interferencias entre ambas interrupciones; se producen muy de cuando en cuando y no ocupan mucho tiempo de proceso, por lo que no deberían interferirse.
Título: Re: Dimmer con TMR0
Publicado por: maunix en 21 de Mayo de 2007, 08:29:30
Tengo una duda, desde mi ignorancia.  ¿que sería el "mando IR"?  Pregunto porque tal vez pueda aportar alguna forma de simularlo.
Título: Re: Dimmer con TMR0
Publicado por: Cryn en 21 de Mayo de 2007, 10:06:23
me referia a un mando IR, por un control remoto de la TV o Radio, cualquiera, que usan un LED IR para transmisión del boton pulsado

ok mocturno, seguire trabajando en ello, espero funcione, aunque como te mencione no vi muchos cambios en los pulsos de disparo en mi simulación; weno hay les aviso, adios!
Título: Re: Dimmer con TMR0
Publicado por: maunix en 21 de Mayo de 2007, 12:37:37
me referia a un mando IR, por un control remoto de la TV o Radio, cualquiera, que usan un LED IR para transmisión del boton pulsado

¿Pero porqué dicen que no se puede simular? yo he simulado recepciones de usart por software completas con el MPSIM simulando cada bit de la trama.
Título: Re: Dimmer con TMR0
Publicado por: Nocturno en 21 de Mayo de 2007, 13:43:02
Bueno, quizás más que "no se puede simular" debería haber dicho "yo no sé cómo simularlo" porque no lo he hecho nunca, Mauricio.
Título: Re: Dimmer con TMR0
Publicado por: maunix en 21 de Mayo de 2007, 14:49:14
Bueno, quizás más que "no se puede simular" debería haber dicho "yo no sé cómo simularlo" porque no lo he hecho nunca, Mauricio.

Bueno, por eso pregunté de qué hablaban , hay cosas que son muy complicadas de simular o imposibles y otras que no lo son tanto.

En el mpsim por ejemplo, se le pueden agregar estímulos de pin, hechos con timings , y con eso se pueden simular entradas muy muy complejas.  Cosas que con proteus por ejemplo no se puede y esa es la principal razón por la cual lo usé un par de horas y lo tuve que descartar (al menos para estas cosas).  :?

El MPSIM mejoró y mucho solo que está muy muy mal documentado.
Título: Re: Dimmer con TMR0
Publicado por: Cryn en 25 de Mayo de 2007, 00:27:48
saludos maunix, pues muy interesado he quedado con lo que mencionas sobre el estimulus MPSIM, y presisamente necesitare un estimulo para comenzar, un reloj, para el dimmer, sera el qeu emule al detector de cruce de cero, que cambia de estado cada vez qeu detecta un cruce por cero, entonces el estimulo que necesito es un reloj constante de un periodo de 10 ms a 50% de ciclo de trabajo, que irá al Pin RB0 (int EXT), he intentado y no lo he logrado, me podrias ayudar porfavor con ello?? o nose si supieras de algun manual donde se expliqeu ello, pues seria muy interesante tb hacer el estimulo para el mando IR. Bueno espero tu respuesta adios, y gracias.
Título: Re: Dimmer con TMR0
Publicado por: PalitroqueZ en 25 de Mayo de 2007, 15:09:39
Bueno, quizás más que "no se puede simular" debería haber dicho "yo no sé cómo simularlo" porque no lo he hecho nunca, Mauricio.

Bueno, por eso pregunté de qué hablaban , hay cosas que son muy complicadas de simular o imposibles y otras que no lo son tanto.

En el mpsim por ejemplo, se le pueden agregar estímulos de pin, hechos con timings , y con eso se pueden simular entradas muy muy complejas.  Cosas que con proteus por ejemplo no se puede y esa es la principal razón por la cual lo usé un par de horas y lo tuve que descartar (al menos para estas cosas).  :?

El MPSIM mejoró y mucho solo que está muy muy mal documentado.

yo luché un rato tratando de hacer funcionar unos estimulos para el CAD y que va, incluso leyendo unas guias del foro de microchip, me venció.. de momento  :(
Título: Re: Dimmer con TMR0
Publicado por: jhozate en 14 de Julio de 2009, 14:35:11
saludos..he venido tratando de asimilar el codigo q postearon...entonces disculpen si me equivoco:
en cada cruce por cero se activa el TIMER0 para q genere una interrupcion cada 1mS, en cada interrupcion del TIMER0 se incrementa la variable "count", entonces "count" es como un contador de mS y "disparo" será la variable que determine el tiempo de disparo al ser comparada con "count", es decir si count=5=5mS y si disparo=5=nivel de intensidad 5, y detectado el cruce por cero entonces se le da un disparo al triac 5mS despues de el cruce por cero.....estoy en lo cierto??
Título: Re: Dimmer con TMR0
Publicado por: Cryn en 14 de Julio de 2009, 16:17:13
paso tiempo de esto :mrgreen:

mmm a ver deja y recuerdo un poco:

la frecuencia de la energía eléctrica suministrada en mi país es de 50Hz, entonces el periodo es de 20ms, de los cuales 10ms son para la señal senoidal positiva, y los otros 10m son para la senoidal negativa, y nuestro triac encenderá la lampará (de 15W que usé aquella vez) según el disparo que se le de en su gate, entonces el disparo se lo debe hacer cada 10ms, para darle siempre el semiciclo positivo o negativo a la lámapara, mediante el triac.

si por ejemplo, disparo al inicio del primer semiclo, debo esperar 10ms y volver a disparar, para el siguiente semiciclo, y así sucesivamente.

ahora, para saber cuando disparar usé unos pulsadores que incrementaban y decrementaban una variable llamada disparo, ya que retardaba el disparo, es decir me movía a lo largo de todo el semiciclo, nose esperaba 5ms y recien disparaba, y pasado los 10ms del semiciclo volvía a disparar, de esta manera solo tendría medio semiciclo entregado a la lámapara, por tanto se veía la atenuación de la lampara correspondiente al 50% del total.

y si, la variable count cuenta cada 1ms, en los desbordes del tmr0, y la interrupción por el cruce por cero le re-establecía la cuenta el tmr0.

Creo que era eso, espero no haberte confundido, y si no lo comprendiste, me avisas

saludos.
Título: Re: Dimmer con TMR0
Publicado por: jhozate en 14 de Julio de 2009, 17:22:55
gracias....ya tengo un poco mas claro esto...me tome el atrevimiento de copiar tu codigo y tratar de ajustarlo a lo que quiero para realizar una prueba, basicamente y por disposicion de hardware el cruce por cero lo detecto activando la interrupcion por cambio de nibble en B4 y el pulso de disparo lo saco por B0, aqui en colombia la frecuencia es 60Hz, asi q hice lo siguientes cambios...corrigeme por favor si tengo algo malo sobre todo en la carga del timer0, tambien debe estar a 1mS con reloj de 4Mhz

Citar
#byte port_b=6

int j=0,count=0;
signed int disparo=0;



//#############################INTERRUPCION CAMBIO NIBBLE##################################
#int_RB
void  RB_isr(void)
{
   #asm movf port_b,0
   #endasm
   set_timer0(128);
}
//######################################################################################


//#############################INTERRUPCION EXTERNA##################################
#int_RTCC
void  RTCC_isr(void)
{
   count++;
   set_timer0(128);
   if(count==10)
   count=0;
   if(count==disparo)
   {
      output_high(PIN_B0);
      delay_us(300);
      output_low(PIN_B0);
   }
   
}
//######################################################################################


void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_RB);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   do
   {
      if(input(PIN_A0))
      {
         delay_ms(16);
         while(input(PIN_A0))
            delay_ms(16);
         disparo++;
         if(disparo==10)
            disparo=9;
      }
      if(input(PIN_A1))
      {
         delay_ms(16);
         while(input(PIN_A1))
            delay_ms(16);
         disparo--;
         if(disparo==-1)
         disparo=0;
      }
   }while(true);

}
Título: Re: Dimmer con TMR0
Publicado por: Cryn en 14 de Julio de 2009, 18:21:18
como la frecuencia acá es 50Hz, mi semiciclo es de 10ms, e hice posible disparos cada 1ms dentro del semiciclo, lo que me daba 10 tonalidades desde encendido completo a apagado, aunque recuerdo que este de apagado no me salía como debería, pero era cuestión de ajustar, por escaso tiempo para la presentación no pude mejorarlo, jeje.

en tu caso tu semiciclo son de aprox 8.33ms lo que daría quizá una nueva forma de verlo, para tratar de dividir tu semiciclo en partes iguales en alumbramiento, quedaría entonces en 0.833ms para dividir en 10 tonalidades, que al menos según recuerdo se veía bien las atenuaciones.

eso ya dependerá de ti, si trabajas a 1ms en los disparos solo tendrás 8 estado posibles.

tu rutina del timer0 esta bien, asi como tu precarga en el timer.

La que no me convence es tu rutina de interrupción por cambio de estado en el puerto B, para qeu usas esa instrucción en asm? si no me equivoco mueve el contenido del puerto b al registro acumulador W del micro, pero nose porque si en ningún otro momento lo usas... quizá en otra parte de tu codigo que no esta a la vista verdad?

Cual es tu detector de cruce por cero?

espero te sirva de ayuda, un saludo
Título: Re: Dimmer con TMR0
Publicado por: jhozate en 14 de Julio de 2009, 19:47:50
psss el cruce por cero lo detecto con resistencia de 5M (asi como pone la nota de microchip) pero yo pongo la resistencia en RB4 y no tengo q fijarme por cambiar el flanco si sera ascendente o descendente y el codigo en asm es para poder salir de la interrupcion por cambio de nibble, se debe escribir o leer el portb(cosa q hay q hacerlo por soft) y de la abandera se encarga el ccs.

saludos
Título: Re: Dimmer con TMR0
Publicado por: Cryn en 15 de Julio de 2009, 11:15:30
muy interesante solución...

y queda muy bien, te ha funcionado el dimmer??

puedes cambiar la instrucción que colocaste en asm por:

output_b(input_b());

solo para mantener la estructura en C, jeje, soy muy aficionado de tener o todo en C o todo en ASM

saludos
Título: Re: Dimmer con TMR0
Publicado por: hamiltontodopic en 07 de Noviembre de 2009, 03:40:45
Amigos me podrian ayudar a adaptar este codigo a mplab para el pic16f88,mil gracias saludos

Título: Re: Dimmer con TMR0
Publicado por: jhozate en 07 de Noviembre de 2009, 13:34:02
busca el plug-in para vincular ccs con mplab y listo..aqui mismo en el foro esta
Título: Re: Dimmer con TMR0
Publicado por: hamiltontodopic en 07 de Noviembre de 2009, 14:00:39
Gracias por responder ahorita lo busco

saludos!!
Título: Re: Dimmer con TMR0
Publicado por: MexaTronko en 06 de Enero de 2014, 02:14:36
hola vi este tema y tome su idea solo que puse un potenciometro en lugar de botones y el disparo esta dado por la lectura del adc, pero no tengo una sincronia por lo que se dispara el triac en cualquier momento y no puedo regular la intesidad de mi carga (foco), espero que me puedan hechar la mano dejo mi codigo de antemano gracias.

#include <16F886.H>   //LIbreria del PIC Implementado.
#device ADC = 8
#fuses HS, MCLR, NOWDT, PUT, NOIESO, NOFCMEN //Deshabilita el Doggy, Oscilador Externo.
#use delay( clock = 12000000 )   //Crystal de 20MHz.INTRC_IO
#use standard_io( B )
#use standard_io( C )   //Direccion del Puerto B.

#define LCD_E     PIN_C0
#define LCD_CK    PIN_C1   
#define LCD_DAT   PIN_C2

#include <flex_lcd_3pins.c>

int f = 0, Cont0 = 0, leer;

#INT_EXT
void ext( void )
   { 
      if( f == 0 )         //Deteccion de Flanco de Subida.
         {
           set_timer0( 160 );
           f = 1;         //Cambio de Bandera de FLag.
           ext_int_edge( 0, H_TO_L );   //Cambio a Flag de Bajada.
           enable_interrupts( INT_TIMER0 );
         }   
      else         //Deteccion de Flanco de Bajada.
         {
            set_timer0( 160 );
            f = 0;              //Cambio de Bandera de FLag.
            ext_int_edge( 0, L_TO_H );   //Cambio a Flag de Subida.
            disable_interrupts( INT_TIMER0 );
         }
   }

#INT_TIMER0
void timer0 ( void )
   {
      Cont0++;
      set_timer0( 160 );
      if( Cont0 == 255 )
         {
            Cont0 = 0;
         }
      if( Cont0 == leer )
         {
            output_high( PIN_B1 );
         }
       else
         {
            output_low( PIN_B1 );
         }
   }

void main( void )
   { 
      //setup_oscillator( OSC_8MHZ );208
      lcd_init();
      //lcd_setcursor_vb(1,1);
     
      ext_int_edge( 0, L_TO_H );   //Inicia en Flag de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
     
      setup_adc_ports( SAN0 );   //Seleccion del Canal 0 Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Reloj Interno RC.
      set_adc_channel( 0 );    //Habilita el Canal 0;
     
      //set_timer0( 208 );
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 );  //Prescaler de 1.
      disable_interrupts( INT_TIMER0 );      //Deshabilita la Interrupcion del Timer1.         
      enable_interrupts( GLOBAL );    //Habilita la Interrupcion Global.
     
      while( 1 )
         {     
            leer = read_adc();
            delay_us( 10 );
            printf( lcd_putc, "\fADC =  %4u\n", leer );   //Muestra el Valor del Dato Leido por el ADC.
            printf( lcd_putc, "Cont0 =  %4u", Cont0 );   //Muestra elVoltaje Correspondiente al Dato.
            delay_ms( 500 ); 
         }
   }
Título: Re: Dimmer con TMR0
Publicado por: rivale en 06 de Enero de 2014, 14:00:29
Veo algunos errores en tu codigo,
-no necesitas apagar la interrupcion del timer0 cuando cambias de flanco, recuerda que el triac tiene que activarse en ambos sentidos de la senoidal, -tambien debes verificar que la frecuencia de tu activacion del timer sea acorde a la frecuancia de tu liena de AC
- el valor que leas directamente de tu pot no necesariamente puedes aplicarlo directamente al tiempo de activacion del triac
-no es necesario que leas continuamente el valor de tu potenciometro, puedes leerlo cada que recibas el cruce por cero, que es cuando utilizaras el valor


Saludos
Título: Re: Dimmer con TMR0
Publicado por: MexaTronko en 06 de Enero de 2014, 20:39:43
hola gracias por corregirme, modifique el codigo cambie el cristalexterno por el inerno del micro de 8MHz y ahora tomo elvalor del adc en el flanco de subida, solo que ahora el pulsito de disparo esta dado por un intervalo, hice la simulacion y elpulsito se "mueve solito"y no realiza un buen disparo en el triac no se si sea un error de sincronia o este utilizando mal el timer0 el calculo para cargar el timer0 lo hice asi

x = 256 - 32*10^-6*8*10^6 / 4 * 1
x = 192

el 32*10^-6 sale de dividir 120^-1/256 que seria el periodo del cruce por cero (la frecuencia de la linea es de 60Hz) entre los 256 valores del adc y un prescaler de 1, para que el timer0 realice una interrupcion cada 32usegundos, no se si de esta manera de cargar el timer0 es buena o hay otra forma de ajustarlo, porque yo creo que no hay sincronia.

#include <16F886.H>   //LIbreria del PIC Implementado.
#device ADC = 8
#fuses INTRC_IO, MCLR, NOWDT, PUT, NOIESO, NOFCMEN //Deshabilita el Doggy, Oscilador Interno.
#use delay( clock = 8000000 )
#use standard_io( B )
#use standard_io( C )   //Direccion del Puerto B.

#define LCD_E     PIN_C0
#define LCD_CK    PIN_C1   
#define LCD_DAT   PIN_C2

#include <flex_lcd_3pins.c>

int f = 0, Cont0 = 0, leer;

#INT_EXT
void ext( void )
   { 
      if( f == 0 )         //Deteccion de Flanco de Subida.208
         {
           leer = read_adc();
           set_timer0( 192 ); //carga el timer0
           f = 1;         //Cambio de Bandera de FLag.
           ext_int_edge( 0, H_TO_L );   //Cambio a Flag de Bajada.
         }   
      else         //Deteccion de Flanco de Bajada.
         {
            set_timer0( 192 );
            f = 0;              //Cambio de Bandera de FLag.
            ext_int_edge( 0, L_TO_H );   //Cambio a Flag de Subida.
         }
   }

#INT_TIMER0
void timer0 ( void )
   {
      Cont0++;
      set_timer0( 192 );
      if( Cont0 == 256 )
         {
            Cont0 = 0;
         }
      if( Cont0 < leer )
         {
            output_low( PIN_B1 );
         }
      if( Cont0 >= leer && Cont0 <= leer + 5  )
         {
            output_high( PIN_B1 );
         }
      if( Cont0 > leer + 5 )
         {
            output_low( PIN_B1 );
         }
   }

void main( void )
   {
      setup_oscillator( OSC_8MHZ );
     
      lcd_init();
     
      ext_int_edge( 0, L_TO_H );   //Inicia en Flag de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
     
      setup_adc_ports( SAN0 );   //Seleccion del Canal 0 Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Reloj Interno RC.
      set_adc_channel( 0 );    //Habilita el Canal 0;
     
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 );  //Prescaler de 1.
      enable_interrupts( INT_TIMER0 );      //habilita la Interrupcion del Timer0.         
      enable_interrupts( GLOBAL );    //Habilita la Interrupcion Global.
     
      while( 1 )
         {     
            printf( lcd_putc, "\fADC =  %4u\n", leer );   //Muestra el Valor del Dato Leido por el ADC.
            printf( lcd_putc, "Cont0 =  %4u", Cont0 );   
            delay_ms( 500 ); 
         }
   }
Título: Re: Dimmer con TMR0
Publicado por: rivale en 07 de Enero de 2014, 11:28:38
tus cálculos estan bien, el periodo de interrupción es de 8.3 [ms] y tu timer se desborda cada 32 [us], creo que el problema esta en tu condicion dentro del timer0

tu estas esperando que tu variable cont0 llegue a 256, pero como la declaraste como un entero (en CCS los int son de 8 bits) esta no puede pasar de 255 (o de 127 si es signado) y el siguiente numero es 0, entonces nunca se cumple tu condicion

Otra forma para configurar tu timer podria ser con un multiplicador de 64, asi tu timer interrumpe cada 8.19 [ms], que es cercano a tu interrupcion, y de esta forma podrias utilizar tu lectura del ADC para cargarla al registro del timer0 (set_timer0(leer)) y en tu interrupción solo activas el triac, espero te sirva

Saludos
Título: Re: Dimmer con TMR0
Publicado por: MexaTronko en 07 de Enero de 2014, 20:56:44
rivale tienes razon la condicion no se cumplira nunca, ya correji la condicion la cambie por 255 y el pulsito se sigue moviendo osea que dispara o no el triac en un tiempo que no le corresponde,  pero no entiedo una cosa lo del multiplicador de 64, entedi que cada valor del adc tomado hara un retardo, dejo una imagen poe si no me explique
Título: Re: Dimmer con TMR0
Publicado por: rivale en 08 de Enero de 2014, 11:16:08
creo que el problema es que tu timer y tu interrupcion no estan sincronizadas, es decir, cada que detectes un cruce por cero debes reiniciar tu contador "CONT0" para que asi tu timer comience a contar a partir de ese momento.

otra cosa que tienes que considerar es que  en esta condición
 if( Cont0 >= leer && Cont0 <= leer + 5  )

si tu variable de leer vale mas de 250 entonces tu valor (leer+5) excede el maximo de tu variable tipo entero



En cuanto a lo del divisor de 64 me referia a que puedes configurar tu timer0 de la siguiente manera

setup_timer_0( RTCC_INTERNAL | RTCC_DIV_64 ); 

entonces tu tiempo de interrupción será 4/8000000 * 64 * (256-tmr0).

donde tmr0 es el valor de tu registro del timer0, cuando este valga 0, tu interrupcion será cada 8.19 ms, si incrementas el valor entonces tu interrupcion será cada menos tiempo.

y puedes usar el tiempo de tu interrupcion para activar tu triac, cuando quieras que se prenda al maximo le das un valor de set_timer0(255) y cuando quieras un valor medio lo seteas con 120 por ejemplo, entre menor sea el numero que cargues en el registro menos sera la parte de la senoidal que dejarás pasar
Título: Re: Dimmer con TMR0
Publicado por: MexaTronko en 08 de Enero de 2014, 16:57:29
Gracias rivale ya ha quedado, reinicie el contador del timer0 en cada cruce por cero y agrege dos condiciones para que no se salga de los limetes

leer = read_adc();
if( leer == 0 )
{
  leer = 1; 
}
if( leer == 255 )
{
leer = 254;
}

y en la condicion del timer0 solo le sume uno y con la condicion de arriba no se pasara del limite
if( Cont0 >= leer && Cont0 <= leer + 1  )
{
  output_high( PIN_B1 );
 }

dejo el codigo por si alguien lo quiere utilizar, de nuevo gracias.

#include <16F886.H>   //LIbreria del PIC Implementado.
#device ADC = 8
#fuses INTRC_IO, MCLR, NOWDT, PUT, NOIESO, NOFCMEN //Deshabilita el Doggy, Oscilador Externo.
#use delay( clock = 8000000 )   //Crystal de 20MHz.
#use standard_io( B )
#use standard_io( C )

#define LCD_E     PIN_C0
#define LCD_CK    PIN_C1   
#define LCD_DAT   PIN_C2

#include <flex_lcd_3pins.c>

int f = 0, Cont0 = 0, leer;

#INT_EXT
void ext( void )
   { 
      if( f == 0 )         //Deteccion de Flanco de Subida.208
         {
           leer = read_adc();
           if( leer == 0 )
             {
               leer = 1; 
             }
           if( leer == 255 )
              {
               leer = 254;
              }
           Cont0 = 0;
           set_timer0( 192 );
           f = 1;         //Cambio de Bandera de FLag.
           ext_int_edge( 0, H_TO_L );   //Cambio a Flag de Bajad
         }   
      else         //Deteccion de Flanco de Bajada.
         {
            Cont0 = 0;
            set_timer0( 192 );
            f = 0;              //Cambio de Bandera de FLag.
            ext_int_edge( 0, L_TO_H );   //Cambio a Flag de Subida.
         }
   }

#INT_TIMER0
void timer0 ( void )
   {
      Cont0++;
      set_timer0( 192 );
      if( Cont0 < leer )
         {
            output_low( PIN_B1 );
         }
      if( Cont0 >= leer && Cont0 <= leer + 1  )
         {
            output_high( PIN_B1 );
         }
      if( Cont0 > leer + 1 )
         {
            output_low( PIN_B1 );
         }
   }

void main( void )
   {
      setup_oscillator( OSC_8MHZ );
     
      lcd_init();
     
      ext_int_edge( 0, L_TO_H );   //Inicia en Flag de Subida.
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa.
     
      setup_adc_ports( SAN0 );   //Seleccion del Canal 0 Analogico.
      setup_adc( ADC_CLOCK_INTERNAL );   //Reloj Interno
      set_adc_channel( 0 );    //Habilita el Canal 0;
   
      //set_timer0( 192 );//16 131
      setup_timer_0( RTCC_INTERNAL | RTCC_DIV_1 );  //Prescaler de 1.
      enable_interrupts( INT_TIMER0 );      //habilita la Interrupcion del Timer1.         
      enable_interrupts( GLOBAL );   
     
      while( 1 )
         {     
            printf( lcd_putc, "\fADC =  %4u\n", leer );   //Muestra el Valor del Dato Leido por el ADC.
            printf( lcd_putc, "Cont0 =  %4u", Cont0 );   //Muestra elVoltaje Correspondiente al Dato.
            delay_ms( 300 );   
         }
   }
Título: Re: Dimmer con TMR0
Publicado por: rivale en 08 de Enero de 2014, 17:18:01
 ((:-)) ((:-))

que bien que ya quedó solucionado