Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

28/06/2016 #21
Moderador

Avatar de D@rkbytes

chango107 dijo: Ver Mensaje
¿Me podrías dar una idea de cómo podría realizar esta operación?
Mira el programa adjunto.
No he verificado su funcionamiento físicamente, pero te puede servir de orientación.
28/06/2016 #22

Avatar de juanma2468

Encontre un error en tu esquema, fijate que la señal de ingreso la estas poniendo en el pin A1, pero para que ocurra un interrupcion, debe estar conectado en el pin A2. Adjunto un imagen con la modificacion que debes realizar. Y vuele a verificar el funcionamiento.
28/06/2016 #23


juanma2468 dijo: Ver Mensaje
Encontre un error en tu esquema, fijate que la señal de ingreso la estas poniendo en el pin A1, pero para que ocurra un interrupcion, debe estar conectado en el pin A2. Adjunto un imagen con la modificacion que debes realizar. Y vuele a verificar el funcionamiento.
fue mi error al subir la imagen no me fije que la conexión estaba en el pin erroneo, en fisico esta sobre el pin que me indicas el pin 11, pero si fue mi error al subir la imagen con esa conexión pido disculpas por eso, y en cuanto a

D@rkbytes dijo: Ver Mensaje
Mira el programa adjunto.
No he verificado su funcionamiento físicamente, pero te puede servir de orientación.
en el momento estoy usando proteus 8 y de compilador ccs, no se porque cuando guardo el proyecto que me enviaste deja de funcionar, si lo ejecuto en el formato en que viene funciona de maravilla, pero si lo guardo en archivos para esta versión comienza a fallar.

en general e intentado colocar la variable de manera global pero me sigue presentando fallas en cuanto a que el programa no funciona, no he manejado mucho las interrupciones por timer, pero me parece una muy optima opción asi que comenzaré a trabajar con este módulo, y espero que asi se solucione el problema

---- Actualizado ----

Hola D@rkbytes, tomando en base el código que me aconsejaste de guia lo modifique y realicé el siguiente programa :

Código:
#include <16f676.h>
#fuses   NOMCLR
#device adc=10
#use     delay(crystal = 20MHz)
long fase;

#INT_EXT
void sd_externa_rb0 (void)
{
   set_timer0(fase);
   enable_interrupts(INT_TIMER0);   
}

#INT_TIMER0
void sdi_desborde_timer0 (void)
{
   disable_interrupts(INT_TIMER0);
   output_high(PIN_A1);
   delay_us(250);
   output_low(PIN_A1);
}

void main()
{
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(sAN0);
   set_adc_channel(0);
   delay_us(22);
   
   enable_interrupts(GLOBAL);
   setup_timer_0 (T0_INTERNAL|T0_DIV_256);
   enable_interrupts(INT_EXT);
   
   while(true)
   {
      fase = ((((157 * read_adc()) / 1024)) + 93);
   }
}
hasta el momento he podido realizar simulaciones pero no me genera algún desfase, corroboro que ingresa a las interupciones dado que si genera un pulso pero como si el ADC leyera siempre el valor de 0
28/06/2016 #24
Moderador

Avatar de D@rkbytes

Para lo que requieres, no es necesario que uses el conversor a 10 bits.
Antes de que modifiques el programa, primero comprueba que funcione con el ADC a 8 bits.
29/06/2016 #25

Avatar de juanma2468

Código:
#include <16f676.h>  
#device adc=10  
#fuses NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, HS, PUT   
#use delay (clock=20000000)  
#use fast_io(C)  
#define LED  PIN_C1

// Definiciones de variables
float Vin; 
long Dfase,Dfase2;
 
#INT_EXT  
void EXT_isr(void)  
{
   Vin=(5*read_adc())/1023;    
   if (Vin <= 2.5)        
  {               
      Dfase=(Vin*3100);
      delay_us(Dfase);
      delay_us(200);
      Output_high(LED);               
      delay_us(250);               
      Output_low(LED);               
      Dfase2=(7730-Dfase);               
      delay_us(Dfase2);               
      Output_high(LED);               
      delay_us(250);               
      Output_low(LED);    
   }         
   else
   {               
       delay_us(200);
       Dfase=(Vin*3150);               
       delay_us(Dfase);               
       Output_high(LED);               
       delay_us(250);               
       Output_low(LED);     
    }  
}     

void main()  
{        
    setup_comparator (NC_NC_NC_NC);
    Output_low(PIN_C0);        
    setup_adc_ports(sAN0|VSS_VDD);        
    setup_adc(ADC_CLOCK_DIV_2);        
    set_adc_channel(0);    
    ext_int_edge(L_TO_H);        
    enable_interrupts(INT_EXT);       
    enable_interrupts(GLOBAL);       
    while(true)        
    {               
    }  
}
Verifique el codigo que te habia modificado y encontre que el problema era la etiqueta que declara la interrupción, esta quedo mal ubicada, lo simule y si entraba en la interrupción, luego tendras que ver si lo los tiempos son correctos o no.
29/06/2016 #26


juanma2468 por el momento ya he dejado de lado los retardos con el delay y estoy usando las interrupciones del Timer tiene mas presentación y al parecer funciona mejor, solamente que ahora cambia el problema que vengo presentando el cambió ya que el código que implemento es el siguiente
Código:
#include<16f676.h>
#fuses NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, HS, PUT 
#device adc=8
#use delay (clock=20000000)

int8 fase;

#INT_EXT
void sd_externa_rb0 (void)
{
   set_timer0(fase);
   enable_interrupts(INT_TIMER0);   
}

#INT_TIMER0
void sdi_desborde_timer0 (void)
{
   disable_interrupts(INT_TIMER0);
   output_high(PIN_A1);
   delay_us(200);
   output_low(PIN_A1);
}


void main()
{
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(sAN0);
   set_adc_channel(0);
   delay_us(22);
   enable_interrupts(GLOBAL);
   setup_timer_0 (T0_INTERNAL|T0_DIV_256);
   enable_interrupts(INT_EXT);
   
   while(true)
   {
      fase = 250-((157*read_adc())/255);
      delay_us(20);
   }
}
la interrupción se genera y el timer0 se activa pero no cambia el valor dependiendo la lectura del ADC siempre se queda en el mismo punto como muestra la imagen, en que puedo estar fallando?
Imágenes Adjuntas
Tipo de Archivo: jpg Circuito.jpg (98,0 KB (Kilobytes), 8 visitas)
01/07/2016 #27


he realizado estos cambios pero persiste el inconveniente, que otro cambio podria realizar?

Código:
#include<16f676.h>
#fuses NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, HS, PUT 
#device adc=8
#use delay (clock=20000000)



#INT_EXT
void sd_externa_rb0 (void)
{
int8 fase;
   fase = 250-((157*read_adc())/255);
   delay_us(20);
   set_timer0(fase);
   enable_interrupts(INT_TIMER0);   
}

#INT_TIMER0
void sdi_desborde_timer0 (void)
{
   disable_interrupts(INT_TIMER0);
   output_high(PIN_A1);
   delay_us(200);
   output_low(PIN_A1);
}


void main()
{
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(sAN0);
   set_adc_channel(0);
   delay_us(22);
   enable_interrupts(GLOBAL);
   setup_timer_0 (T0_INTERNAL|T0_DIV_256);
   enable_interrupts(INT_EXT);
   
   while(true)
   {

   }
}
01/07/2016 #28

Avatar de ruben90

El inconveniente me parece proviene de aquí,
Código:
#INT_TIMER0
void sdi_desborde_timer0 (void)
{
   disable_interrupts(INT_TIMER0);
   output_high(PIN_A1);
   delay_us(200);
   output_low(PIN_A1);
}
El pulso siempre durara 200uS.

Para que te sirve la sentencia while vacía?
Código:
while(true)
   {

   }
01/07/2016 #29


Hola ruben90, gracias por tu pronta respuesta, la duración del pulso debe ser siempre de 200uS, lo que quiero que se modifique es el tiempo del timer, el cual lo asigno en

Código:
#INT_EXT
void sd_externa_rb0 (void)
{
int8 fase;
   fase = 250-((157*read_adc())/255);
   delay_us(20);
   set_timer0(fase);
   enable_interrupts(INT_TIMER0);   
}
y el while vacio es mas para que el micro no ingrese en modo sleep, solo por prevención, no se que me puedas aconsejar para que el código sea funcional
01/07/2016 #30

Avatar de juanma2468

Creo que hay otro problema, Chango107 estas haciendo set_timer0 (fase); donde "fase" es supongamos para Vin de referencia del preset a la mitad 2,5V ==> fase = 172. Al setear el timer con dicho valor, significa que la interrupción va a ocurrir cuando el timer desborde, o sea cuando sobrepasa 255, por lo que van a ocurrir 84 pasos del timer hasta que eso ocurra, con un valor de 51,2 useg cada paso del incremento del timer. Si el valor que realmente quiere que ocurra para la interrupción es 172, entonces debes hacer set_timer (255 - fase);
01/07/2016 #31


Pues viendo sus consejos me he puesto en el trabajo de mirar mas las operaciones que esta realizando el micro, para eso separe operación por operación para validar si es algún problema en esos puntos, de lo cual tengo el siguiente programa

Código:
#include<16f676.h>
#fuses NOWDT, NOPROTECT, NOBROWNOUT, NOMCLR, XT, PUT 
#device adc=8
#use delay (clock=4000000)

int8 fase=0,fase1;
int16 q, q1;

#INT_EXT
void sd_externa_rb0 (void)
{
   set_timer0(fase);
   enable_interrupts(INT_TIMER0);   
}

#INT_TIMER0
void sdi_desborde_timer0 (void)
{
   output_high(PIN_A1);
   delay_us(200);
   output_low(PIN_A1);
   disable_interrupts(INT_TIMER0);
}


void main()
{
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(sAN0);
   enable_interrupts(GLOBAL);
   setup_timer_0 (T0_INTERNAL|T0_DIV_32);
   enable_interrupts(INT_EXT);
   
   while(true)
   {
   set_adc_channel(0);
   delay_us(20);
   fase1 = read_adc();
   delay_us(20);
   q=(157*fase1);
   q1=q/255;
   fase=250-q;
   }
}
y simulando paso a paso con ayuda de proteus me di cuenta que las operaciones de multiplicación y división no se están ejecutando de manera correcta ya que la multiplicación se esta quedando con un valor de máximo 8 bits, y la división siempre da 0. ¿Que podría hacer?
Imágenes Adjuntas
Tipo de Archivo: jpg Circuito.jpg (105,3 KB (Kilobytes), 5 visitas)
01/07/2016 #32

Avatar de ruben90

Tienes muchos errores de sintaxis,
Código:
int8 fase=0,fase1;
int16 q, q1;
...
while(true)
   {
   set_adc_channel(0);
   delay_us(20);
   fase1 = read_adc();
   delay_us(20); //Según el datasheet del PIC16F877A, el tiempo typ. de adquisición es de 40uS.
   q=(157*fase1); //Numero de 16 bits, OK.
   q1=q/255 //Haces la operacion, pero a donde aplicas q1?
   fase=250-q; //Restas un numero de 8 bits con uno de 16 bits?
   }
...
01/07/2016 #33


delay_us(20); //Según el datasheet del PIC16F877A, el tiempo typ. de adquisición es de 40uS.
en cuanto al tiempo de adquisición si no lo tenia claro, ya lo subi a 40uS pero igual pues antes no me presentaba inconvenientes por esta adquisición.

q=(157*fase1); //Numero de 16 bits, OK.
la operación de q=(157*fase1); es un número de 16 bits, pero igual el resultado de la operación no es correcto dado que fase1 en el momento tiene un valor de 115 lo cual se multiplica por 157 y da 135 como muestra la imagen lo cual no es correcto.

fase=250-q; //Restas un numero de 8 bits con uno de 16 bits?
la variable q1 va es en la siguiente línea pido disculpas por mi error, pero al igual siempre el resultado de esa división me esta dando cero.

subo nuevamente la imagen pero mas detallada hacia las variables en simulación ya que antes no se veía muy bien
Imágenes Adjuntas
Tipo de Archivo: jpg Circuito.JPG (130,9 KB (Kilobytes), 5 visitas)
01/07/2016 #34


puedes intentar algo asi si no requieres mucha presicion

Código PHP:
#include <16f688.h>
#include <stdint.h>
#device adc = 8
#use delay (internal = 8000000)

uint8_t flag 0;

#INT_EXT
void ext_isr ()
    {
    
flag 1;
    }

void main()    
    {
    
int16 c;
    
setup_oscillator(OSC_8MHZ);

    
output_low (PIN_C1);

    
setup_adc (ADC_CLOCK_DIV_16);
    
setup_adc_ports (sAN0VSS_VDD);
    
set_adc_channel (0);

    
ext_int_edge (L_TO_H);
    
enable_interrupts (INT_EXT);
    
enable_interrupts (GLOBAL);

    
setup_timer_0 (T0_DIV_64);

    while (
TRUE)
        {
        if (
flag)
            {
            
read_adc (ADC_START_ONLY);
            
delay_us(100);
            
read_adc (ADC_READ_ONLY);

            if (
240240;
            if (
15)
                {
                
set_timer0 (c);
                while (
get_timer0());
                
output_high (PIN_C1);
                
delay_us(200);
                
output_low (PIN_C1);
                }
            
flag 0;
            }
        }
    } 
saludos
Imágenes Adjuntas
Tipo de Archivo: jpg Screenshot 1.jpg (132,0 KB (Kilobytes), 7 visitas)
Tipo de Archivo: jpg Screenshot 2.jpg (134,0 KB (Kilobytes), 7 visitas)
Tipo de Archivo: jpg Screenshot 3.jpg (133,3 KB (Kilobytes), 6 visitas)
Tipo de Archivo: jpg Screenshot 4.jpg (133,4 KB (Kilobytes), 5 visitas)
Archivos Adjuntos
Tipo de Archivo: zip capture-1.avi.zip (1,81 MB (Megabytes), 3 visitas)
01/07/2016 #35

Avatar de ruben90

chango107 dijo: Ver Mensaje
la operación de q=(157*fase1); es un número de 16 bits, pero igual el resultado de la operación no es correcto dado que fase1 en el momento tiene un valor de 115 lo cual se multiplica por 157 y da 135 como muestra la imagen lo cual no es correcto.
Desconozco el porque, no tienes que declarar la librería math.h o stdint.h (para operaciones matemáticas) en este compilador? Como yo utilizo mikroC, no sabría decirte.
chango107 dijo: Ver Mensaje
la variable q1 va es en la siguiente línea pido disculpas por mi error, pero al igual siempre el resultado de esa división me esta dando cero.
q1 = 135/255 = 0.53 //como es variable entera solo muestra el cero.

El usuario carferper te da una solución, pero si armas el circuito de seguro el LM7805 revienta (VImax = 25V). La resistencia de base para el transistor debera ser de 3W. Ademas recuerda que la frecuencia después del puente de diodos es el doble que el de la linea (120Hz).

Debes tener precaución ya que es la red domestica (120V/220V).
01/07/2016 #36


ruben90 dijo: Ver Mensaje
Desconozco el porque, no tienes que declarar la librería math.h o stdint.h (para operaciones matemáticas) en este compilador? Como yo utilizo mikroC, no sabría decirte.]
Pues mira que lo habia intentado con anterioridad pero me presentaba inconvenientes al usar la declaración de #device adc=8, pero las declare nuevamente, elimine la línea que mencione anteriormente y ahora funciona sin ningún problema, hasta con el aporte del usuario carferper complete la simulación

Doy gracias a todos por la colaboración, interes y prontas respuestas, dejaré el código por aca para que otros puedan guiarse
Imágenes Adjuntas
Tipo de Archivo: jpg Circuito.jpg (103,7 KB (Kilobytes), 8 visitas)
Archivos Adjuntos
Tipo de Archivo: zip Cto disparo.zip (62,4 KB (Kilobytes), 8 visitas)
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.