Autor Tema: Incrementos de frecuencia de 50 Hz  (Leído 2919 veces)

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

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
Incrementos de frecuencia de 50 Hz
« en: 11 de Octubre de 2004, 17:07:00 »
Hola

Quisiera saber si existe alguna forma de ir incrementando la frecuencia en valores de 50 Hz hasta llegar a 1000 Hz, yo lo estoy haciendo con delays pero como la base es en ms pues obviamente la de frecuencia no es la misma. La verdad no le hallo como hacerle, estaba pensando en usar timers pero las diferencias en ms no son constantes y pues no hallo como. Si alguien me puede ayudar le agradecería bastante. El programa que tengo es este:
Codigo:

#include <16f874A.h>
#fuses HS, NOPROTECT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#BIT RBIF=0xB.0
#byte PORTB=0x06
#include <lcd.c>

int i;
float periodo=100;
int tecla=0;
float freq;

void retardo()
   {
      for(i=1;i<=periodo;i++)
            {
               delay_ms(10);
            }
   }

void flash()
   {
      output_a(5);
      retardo();
      output_a(6);         
      retardo();
      output_a(10);      
      retardo();
      output_a(9);
      retardo();
   }

void opcion()
   {
      if(tecla==1)
         {
            tecla=0;
            if(periodo==1)
            periodo=100;
            else
            periodo=periodo-1;
         }
      if(tecla==2)
         {
            tecla=0;
            if(periodo==100)
            periodo=1;
            else
            periodo=periodo+1;
         }
   }

void despliegue_lcd()
   {
      lcd_putc("f");
         lcd_gotoxy(13,1);
         printf(lcd_putc,"Hz";
      freq=1000/periodo;
      lcd_gotoxy(1,1);
      printf (lcd_putc, "Freq=%3.3f", freq);
   }

#int_RB
void interrupcion()
    {
       
      int current;
      static int last=0xF0;      
                  
               delay_ms(50);
      current=PORTB;            
   
      if (!(bit_test(current,4))&&(bit_test(last,4))) {tecla=1;}   if (!(bit_test(current,5))&&(bit_test(last,5))) {tecla=2;}   if (!(bit_test(current,6))&&(bit_test(last,6))) {tecla=3;}
                if (!(bit_test(current,7))&&(bit_test(last,7))) {tecla=4;}   
   last=current;        
   opcion();
   despliegue_lcd();
   }

void main()
   {
      set_tris_a(0x00);
      port_b_pullups(TRUE);
      RBIF=0;
         enable_interrupts(int_RB);
         enable_interrupts(global);
         lcd_init();
         despliegue_lcd();
     
      while(TRUE)
         {
            flash();
         }
   }


Desconectado odukec

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 174
RE: Incrementos de frecuencia de 50 Hz
« Respuesta #1 en: 12 de Octubre de 2004, 08:29:00 »
Hola..

Yo lo haria por PWM, el problema es que empezaria aproximadamente desde 300Hz y hay para arriba no tendras problema, mas o menos sería algo de este estilo

Codigo:

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_1,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   setup_ccp1(CCP_PWM);      // asigno el PWM al modulo ccp1

   setup_timer_2(T2_DIV_BY_1, 48, 1); // configuración frecuencia

   set_pwm1_duty(25);  // Ancho de pulso

   while(TRUE){}
}




Este es para 425Hz.. con un cristal de 4Mhz, el calculo es de esta forma..

Frecuencia = 1 / ((frec_cristal^-1)*4*t2div*(periodo+1))

setup_timer_2(t2div,periodo,postscale)

Pues de hay conoces todo menos el periodo.. lo despejas y ya lo reemplazas en la función setup.. cuadras el duty.. y asignas el PWM al ccp1 o ccp2

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: Incrementos de frecuencia de 50 Hz
« Respuesta #2 en: 12 de Octubre de 2004, 10:55:00 »
Para una fosc=4MHz exactamente empezaría en:

fmín=244Hz

y acabaría en:

fmax=500KHz (por arriba no tendrías problemas)

Podrías reducir la fmín reduciendo la fosc. Por ejemplo para un cristal de 1MHz --- > fmín=61Hz


Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
RE: Incrementos de frecuencia de 50 Hz
« Respuesta #3 en: 12 de Octubre de 2004, 17:22:00 »
Hola

Gracias por los consejos pero yo lo que ando buscando es no usar el PWM, por eso quiero ver si existe alguna forma de manejarlo con delays. Yo lo he estado intentando pero tengo dudas en cierta parte de mi programa, siendo específico en la función ajuste. Me podrían echar la mano, lo que quiero es partir un flotante en parte entera y parte fraccionaria. Este es el código:
Codigo:

#include <16f874A.h>
#include <math.h>
#fuses HS, NOPROTECT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#BIT RBIF=0xB.0
#byte PORTB=0x06
#include <lcd.c>

int i;
float msec=20;
int usec=0;
float dato=1;
int tecla=0;
float freq;


void retardo()
   {
      for(i=1;i<=msec;i++)
         {
            delay_ms(1);
         }
      if(usec>0)
         {
            for(i=1;i<=usec;i++)
               {
                  delay_us(10);
               }
         }
   }

void flash()
   {
      output_a(5);
      retardo();
      output_a(6);         
      retardo();
      output_a(10);      
      retardo();
      output_a(9);
      retardo();
   }

void opcion()
   {
      if(tecla==1)
         {
            tecla=0;
            if(dato==20)
            dato=1;
            else
            dato=dato+1;
         }
      if(tecla==2)
         {
            tecla=0;
            if(dato==1)
             dato=20;
            else
            dato=dato-1;
         }
   }

void ajuste()
   {
      msec=fmod(20,dato);
      usec=((20/dato)-msec)*100;
   }      

void despliegue_lcd()
   {
      lcd_putc("f");
         lcd_gotoxy(12,1);
         printf(lcd_putc,"Hz";
      freq=dato*50;
      lcd_gotoxy(1,1);
      printf (lcd_putc, "Freq=%4.1f", freq);
   }

#int_RB
void interrupcion()
    {
       
         int current;
         static int last=0xF0;      
      
        delay_ms(50);
         current=PORTB;      //Valor actual del puerto B
      
   
      if (!(bit_test(current,4))&&(bit_test(last,4))) {tecla=1;}   
      if (!(bit_test(current,5))&&(bit_test(last,5))) {tecla=2;}   
      if (!(bit_test(current,6))&&(bit_test(last,6)))   {tecla=3;}   
      if (!(bit_test(current,7))&&(bit_test(last,7)))   {tecla=4;}

   last=current;
   opcion();
   ajuste();
   despliegue_lcd();
   }

void main()
   {
      set_tris_a(0x00);
      port_b_pullups(TRUE);
      RBIF=0;
         enable_interrupts(int_RB);
         enable_interrupts(global);
         lcd_init();
         despliegue_lcd();
     
      while(TRUE)
         {
            flash();
         }
   }


Gracias por la ayuda

Desconectado odukec

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 174
RE: Incrementos de frecuencia de 50 Hz
« Respuesta #4 en: 12 de Octubre de 2004, 18:21:00 »
Hola..

Yo lo hice por medio de la interrupcion del TMR0..
Claro que ya no me acuerdo como fue que le hice para calcular el tiempo, salen tres señales..

pongo el programa.. depronto te sirve

Codigo:


#define INTS_PER_SECOND 1
#define aux 4
byte seconds, sec2;
int int_count, sec;
short flag, flag1, flagb;
 
#int_RTCC

void clock_isr(){

   if(--int_count==0) {
      ++seconds;
      int_count=INTS_PER_SECOND;
      if(flag==0){
         flag=1;
         output_high(PIN_B1);
      }else{
         flag=0;
         output_low(PIN_B1);
      }
   }
   if(--sec==0) {
      ++sec2;
      sec=aux;
      if(flag1==0){
         flag1=1;
         output_high(PIN_B2);
      }else{
         flag1=0;
         output_low(PIN_B2);
      }
   }
   set_rtcc(235);
}


void main()
{

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   while(TRUE){
      if(flagb==0){
         flagb=1;
         output_high(PIN_B3);
         //delay_cycles(1);
      }else{
         flagb=0;
         output_low(PIN_B3);
         //delay_cycles(1);
      }

   }

}




La maxima freduencia que logro es aproximadamente 12Khz

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
RE: Incrementos de frecuencia de 50 Hz
« Respuesta #5 en: 12 de Octubre de 2004, 18:57:00 »
Gracias a todos por su ayuda, ya quedó como yo quería. Fue cuestion de entender el manejo de los enteros con los flotantes.
Codigo:

#include <16f874A.h>
#include <math.h>
#fuses HS, NOPROTECT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#BIT RBIF=0xB.0
#byte PORTB=0x06
#include <lcd.c>

int i;
int msec=100;
int usec=0;
float dato=1;
int tecla=0;
float freq;


void retardo()
   {
      for(i=1;i<=msec;i++)
         {
            delay_ms(1);
         }
      if(usec>0)
         {
            for(i=1;i<=usec;i++)
               {
                  delay_us(10);
               }
         }
   }

void flash()
   {
      output_a(5);
      retardo();
      output_a(6);         
      retardo();
      output_a(10);      
      retardo();
      output_a(9);
      retardo();
   }

void opcion()
   {
      if(tecla==1)
         {
            tecla=0;
            if(dato==100)
            dato=1;
            else
            dato=dato+1;
         }
      if(tecla==2)
         {
            tecla=0;
            if(dato==1)
             dato=100;
            else
            dato=dato-1;
         }
   }

void ajuste()
   {
      msec=100/dato;
      usec=((100/dato)-msec)*100;
   }      

void despliegue_lcd()
   {
      lcd_putc("f");
         lcd_gotoxy(12,1);
         printf(lcd_putc,"Hz";
      freq=dato*10;
      lcd_gotoxy(1,1);
      printf(lcd_putc, "Freq=%4.1f", freq);
      lcd_gotoxy(1,2);
      printf(lcd_putc, "msec=%3d",msec);
      lcd_gotoxy(9,2);
      printf(lcd_putc, "usec=%2d",usec);
   }

#int_RB
void interrupcion()
    {
       
         int current;
         static int last=0xF0;      
      
        delay_ms(50);
         current=PORTB;      //Valor actual del puerto B
      
   
      if (!(bit_test(current,4))&&(bit_test(last,4))) {tecla=1;}   
      if (!(bit_test(current,5))&&(bit_test(last,5))) {tecla=2;}   
      if (!(bit_test(current,6))&&(bit_test(last,6)))   {tecla=3;}   
      if (!(bit_test(current,7))&&(bit_test(last,7)))   {tecla=4;}

      last=current;
      opcion();
      ajuste();
      despliegue_lcd();
   }

void main()
   {
      set_tris_a(0x00);
      port_b_pullups(TRUE);
            RBIF=0;
         enable_interrupts(int_RB);
         enable_interrupts(global);
         lcd_init();
         despliegue_lcd();
     
      while(TRUE)
               {
            flash();
               }
   }



 

anything