Autor Tema: PWM con SCR sincronizado a la red de corriente alterna con 16F877  (Leído 11019 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Héctor Patricio

  • PIC10
  • *
  • Mensajes: 5
PWM con SCR sincronizado a la red de corriente alterna con 16F877
« en: 15 de Octubre de 2008, 16:30:05 »
Saludos!

Mi nombre es Héctor Patricio soy de Chile y éste es mi primer post :)

Mi problema es el siguiente:
Estoy haciendo un PWM sincronizado con la red y el ángulo de disparo lo varío con una señal de tensión continua de 0 a 10 volt (para 0 volt=0° y para 10 volt=180°)

Entonces usé un circuito de cruze que conecto a la red y obtengo una señal TTL en fase con la red, como se muestra en la figura




La señal TTL la ingreso por un pin del PIC, en principio usé el pin RB0/INT para aprovecharme de su interrución y me funcionó muy bien.
Entonces lo que hago es ingresar la señal TTL por el pin RB0/INT y hacer una rutina de servicio a la interrupción que me genere el retardo de disparo del SCR. La señal de disparo del SCR la saco por el pin RD0.

Este programa implementé y me funcionó.

Código: [Seleccionar]
#include <16f877.h>
#device adc=8
#use delay(clock=4000000)
#byte port_b = 0x06
#byte port_c = 0x07
#byte port_d = 8
#byte adresl = 0x9e
#byte adresh = 0x1e
#bit RB0 = 0x06.0                  // puerto b está en la 0x06
#bit RB1 = 0x06.1
#ORG 0x1F00,0x1FFF {} /* reserva de memoria para el bootloader*/

int valor;

#int_EXT   
void  EXT_isr(void) /*Rutina de servicio a la interrupción para antender a la señal TTL en fase con la red*/
{
int n;
valor=read_adc(); /*Lee Canal 0 */
n=valor/2; /*dividimos por 2 valor para que el barrido de alfa sea sólo por el semiciclo positivo*/
for (n; n!=0; n--)
{
delay_us( 10 ); // ajustar
}
while (RB0)
{

output_high(PIN_D0); /*generación del "pulsito" para disparar el SCR*/
}
output_low(PIN_D0);
}


/* programa principal*/
main()
{
ext_int_edge(L_TO_H);         // interrupción en RB0 por flanco de subida
    enable_interrupts(INT_EXT);   // habilita interrupción externa en RB0
    enable_interrupts(GLOBAL);   // GIE = HIGH
set_tris_a(0xff); /*todo el puerto a como entrada*/
set_tris_b(0xff); /*RB0/Int entrada*/
set_tris_c(0x00); /*todo el puerto c como salida*/
set_tris_d(0xf0);
port_b = 0x00;
port_c = 0x00;
setup_adc_ports(AN0_AN1_VSS_VREF); /* A0 A1 VRefh=A3*/
setup_adc(ADC_CLOCK_DIV_8); /*Para Clock de 4MHZ => Tconv = 24us */
set_adc_channel(0); /* Elige canal 0 del ADC */
while(1)
{
valor=read_adc(); /*Lee Canal 0 */
}
}

EL PROBLEMA ES QUE AHORA QUIERO HACER LO MISMO PERO USANDO LA INTERRUPCIÓN DE LA PUERTA B (interrupción por cambio de estado en las 4 lineas más significativas de la puerta B).

Entonces ahora conecto la señal TTL al pin RB4, activo la interrupción de la puerta b y modifico el programa para consegui el mismo efecto que con el programa anterior pero el problema es que no lo consigo.

las moficaciones que hago son:
/*dentro del main, habilo la INT_RB admeas del GLOBAL*/

Código: [Seleccionar]
...
main()
{
enable_interrupts(INT_RB);   // habilita interrupción de las lineas de mas peso de puerto B
    enable_interrupts(GLOBAL);   // GIE = HIGH
...

y modifico completamente la rutina de servicio a la interrupción, pongo esta:

Código: [Seleccionar]
#int_EXT   
void  RB_isr(void) /*Rutina de servicio a la interrupción para antender a la señal TTL en fase con la red*/
{
valor=read_adc(); /*Lee Canal 0 */
if (RB0)
{

n=valor/2; /*dividimos por 2 valor para que el barrido de alfa sea sólo por el semiciclo positivo*/
for (n; n!=0; n--)
{
delay_us( 10 ); // ajustar
}
output_high(PIN_D0); /*generación del "pulsito" para disparar el SCR*/
delay_us(100); /*duración del "pulsito" de disparo del SCR*/
output_low(PIN_D0);
}
else
{return;}
}

Entonces en este caso cuando el pin RB4 está en alto se genera el disparo del SCR y cuando está en bajo sólo se retorna al main pero por más que trato de hacerlo con la interrupción del puerto B no me funciona, SÓLO ME FUNCIONA CON LA INTERRUPCIÓN RB0/INT.

Necesito hacer funcionar el programa con la Interrupción del puerto B porque tengo que extenderlo para un sistema trifasico en donde tengo que controlar las tres fases y con el primer programa sólo puedo controlar una fase ya que el PIC sólo tiene un RB0/INT

AYUDA POR FAVOR


Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: PWM con SCR sincronizado a la red de corriente alterna con 16F877
« Respuesta #1 en: 15 de Octubre de 2008, 16:46:07 »
Hola, por lo que veo, el error es por despistado seguramente :) .Dentro de la subrutina RB_isr, deberías hacer el if con el RB4, no con el RB0...

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: PWM con SCR sincronizado a la red de corriente alterna con 16F877
« Respuesta #2 en: 15 de Octubre de 2008, 16:47:55 »
Hola.

Ojo con el bug del CCS en las interrupciones del puerto B.

Saludos
El papel lo aguanta todo

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: PWM con SCR sincronizado a la red de corriente alterna con 16F877
« Respuesta #3 en: 15 de Octubre de 2008, 16:49:04 »
El papel lo aguanta todo

Desconectado Héctor Patricio

  • PIC10
  • *
  • Mensajes: 5
Re: PWM con SCR sincronizado a la red de corriente alterna con 16F877
« Respuesta #4 en: 15 de Octubre de 2008, 16:53:13 »
Hola, por lo que veo, el error es por despistado seguramente :) .Dentro de la subrutina RB_isr, deberías hacer el if con el RB4, no con el RB0...

Saludos.
Gracias pero...

No es eso, de hecho estaba probando conectar la señal TTL a RB0 y RB4 porque cuando ponía If(RB4) no pasaba nada y con if(RB0) tampoco

Creo que el problema es que nunca se activa la interrupción porque puse una rutina de servicio de interrupción simple, cosa de que cuando halla un cambio en RB4 se genere una señal pulsante sólo para saber si me estaba tomando la interrupción pero NO.

puse esto pero no hace nada tampoco

Código: [Seleccionar]
#include <16f877.h>
#device adc=8
#use delay(clock=4000000)
#byte port_b = 0x06
#byte port_c = 0x07
#byte port_d = 8
#byte adresl = 0x9e
#byte adresh = 0x1e
#bit RB4 = 0x06.4                  // puerto b está en la 0x06
#bit RB0 = 0x06.0
#ORG 0x1F00,0x1FFF {} /* reserva de memoria para el bootloader*/

int valor;
int n;

#int_EXT  
void  RB_isr(void) /*Rutina de servicio a la interrupción para antender a la señal TTL en fase con la red*/
{
output_high(PIN_D0); /*generación del "pulsito" para disparar el SCR*/
delay_us(100); /*duración del "pulsito" de disparo del SCR*/
output_low(PIN_D0);
delay_us(100);
output_high(PIN_D0); /*generación del "pulsito" para disparar el SCR*/
delay_us(100); /*duración del "pulsito" de disparo del SCR*/
output_low(PIN_D0);


}


/* programa principal*/
main()
{
enable_interrupts(INT_RB);   // habilita interrupción de las lineas de mas peso de puerto B
    enable_interrupts(GLOBAL);   // GIE = HIGH
set_tris_a(0xff); /*todo el puerto a como entrada*/
set_tris_b(0xff); /*RB entrada*/
set_tris_c(0x00); /*todo el puerto c como salida*/
set_tris_d(0x00);
port_b = 0x00;
port_c = 0x00;
setup_adc_ports(AN0_AN1_VSS_VREF); /* A0 A1 VRefh=A3*/
setup_adc(ADC_CLOCK_DIV_8); /*Para Clock de 4MHZ => Tconv = 24us */
set_adc_channel(0); /* Elige canal 0 del ADC */
while(1)
{
valor=read_adc(); /*Lee Canal 0 */
}
}[code]

El PIN RD0 siempre está en alto no oscila con los cambios en RB4 como debería ser  :(
[/code]

Desconectado Héctor Patricio

  • PIC10
  • *
  • Mensajes: 5
Re: PWM con SCR sincronizado a la red de corriente alterna con 16F877
« Respuesta #5 en: 15 de Octubre de 2008, 17:15:21 »
gracias a todos.

era eso del bug de la puerta B
puse las intrucciones en assembler al principio de la ISR
#asm movf port_b,0 #endasm

y se arregló