terça-feira, 8 de junho de 2010

Dimmer microcontrolador com PIC12F675

Montei diversos dimmers com controle "analógico", sempre no entanto, tendo interesse por algo microcontrolado. Após diversas buscas e teste em simulações, encontrei um circuito no fórum TODOPIC. Efetuei algumas alterações (substituição de microcontrolador, adição de chaves) e também mexi um pouco no código. Com isto, tenho o seguinte circuito:
Com a adição de 02 chaves, posso aumentar ou reduzir o ângulo de disparo. Havia conseguido algo similar, efetuando um delay dentro da interrupção externa, porém não ficou a contento o funcionamento. Abaixo, segue uma imagem no simulador, com ângulo de disparo bem reduzido:

Já na próxima figura, um ângulo de disparo bem alto:

O programa feito em CCS não está totalmente correto, uma vez que não dispara exatamente em 0º e nem em 180º, porém basta um pequeno ajuste no valor da variável "fase". Segue abaixo o programa utilizado no PIC. Mantive os comentários do programa original, facilitando seu entendimento:
#include <12f675.h>
#use delay(clock=4000000)
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOCPD,NOMCLR
int pasada=0;
unsigned int fase = 51;
long int muestra=0;
int j=0;
int intervalador=1;

// Interrupción del TIMER1, encargado de calcular el tiempo de un semiciclo constantemente.
#INT_TIMER1
void temporizador() {
set_timer1(0);
}
// Interrupción del TIMER0, provoca el retardo deseado antes de la excitación
#INT_TIMER0
void tempo() {
output_high(PIN_A1); // Ha transcurrido el tiempo, activo la salida
}

// Interrupción Externa, provocada por el paso por 0V de la señal de entrada
#INT_EXT
void externa() {
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
}

if (pasada==0){
enable_interrupts(INT_TIMER1); // Activo la cuenta
set_timer1(0); // Comenzando desde cero
pasada=1;
}
else if (pasada==1){
muestra=get_timer1(); // Tiempo medido entre dos pasos por 0 sucesivos
set_timer1(0); // Inicio el Timer1 para una nueva cuenta
//intervalador = (muestra/8); // Equiparo los preescaler, y por tanto las unidades de tiempo de TIMER1 y TIMER0.
// 8 unidades de TIMER1 equivalen a 1 de TIMER0
intervalador = 256 - fase; // Este es el valor final a cargar el el TIMER0, con esto retardo la señal 1/4 de su semiperido
enable_interrupts(INT_TIMER0);
set_timer0(intervalador);
output_low(PIN_A1); // Pongo a 0 la salida, y comienza el retardo
}
}

void main() {
enable_interrupts(INT_EXT);
ext_int_edge(L_TO_H);
setup_comparator(NC_NC_NC_NC);
setup_adc_ports( NO_ANALOGS );
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64);
enable_interrupts(GLOBAL);
output_low(PIN_A1);
delay_ms(100);

for(;;) {

if (!input(pin_a4)) if (fase < fase =" fase"> 10) fase = fase - 5;
delay_ms(100);
}
}

2 comentários:

  1. eu não entendi o main, principalmente a parte do:

    if (!input(pin_a4)) if (fase < fase =" fase"> 10) fase = fase - 5;

    qual o seu email? gostaria de conversar com vc a respeito do circuito

    ResponderExcluir
  2. Ola! eu tambem tentei compilar esse algoritimo mas essa linha
    if (!input(pin_a4)) if (fase < fase =" fase"> 10) fase = fase - 5;
    tem um errinho!
    Se voce tiver a solucao poderia postar pra galera?
    Obrigado!

    ResponderExcluir