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

Temas similares

04/09/2012 #1


Problema con pwm
Buenas tardes a todos


Tengo el siguiente problema

tengo un programa pwm que me varia con unos potenciometros el ancho del pulso y la frecuencia resulta que cuando hago la variación de los potenciometros se corta la señal y después se reactiva y megustaria que fuera fluido segun el cambio sin interrupciones

estoy trabajando con un pic16f88 a 4mhz


Código:
#include <16F88.h>  //Define el microcontrolador utilizado
#DEVICE ADC=8
#fuses INTRC_IO, NOWDT, NOPROTECT, PUT, NOLVP    //Define los fusibles
#use delay(clock=4000000)     //Define la velocidad del cristal

//#use standard_io(b)  //Utilizar puerto B en modo estandar
#use fast_io(b)  //Utilizar puerto B en modo estandar
#use fast_io(a)  //Utilizar puerto A en modo estandar

#include ".\include\flex_lcd.c" //se incluye el que esta en la carpeta especificada

#define AN_FRECUENCIA   0
#define AN_APERTURA     1
#define CONSTANTE_REBOTE 5    //Constante para antirebote, dura "n" periodos
                              //de señal PWM el antirebote. Se recomienda colocar
                             //valores de 3 en adelante

#define PIN_PWM         PIN_A2
#define BOTON_REL       PIN_B0
#define RELAY           PIN_B2




const int16 AJUSTE_TMR1_110Hz = 64400;
const int16 AJUSTE_TMR1_20Hz = 59286;

const int ticks_PULSO_MINIMO = 31;
const int ticks_PULSO_MAXIMO = 219;

float const uSxTick_RTCC = 32;       // Microsegundos por Tick de RTCC a 4 Mhz
float const uSxTick_TMR1 = 8;       // Microsegundos por Tick de TMR1 a 4 Mhz

//***Variables globales***

int1 flagTMR1 = 0;
int1 flagPWM1 = 0;
int tPWM1 = ticks_PULSO_MINIMO;
float tPWM;
int val_frecuencia,val_apertura,val_frec_anterior,val_ap_anterior;
int16 AJUSTE_TMR1;
float rpm,frec;
float t_aux;
int16 cont_antirebote;
int1 flag_antirebote;

//*********Declaracion de funciones***********************
void ajusta_pwm(void);

//************Funciones***************************

void ajusta_pwm(void){

   printf(lcd_putc, "\f");
   
//Ecuacion de la recta para calculo de AJUSTE_TMR1
   AJUSTE_TMR1=((20.0549*(int16)val_frecuencia))+59286;

   /*
   //LIMITADOR DE FRENCUENCIA
   if(AJUSTE_TMR1 > AJUSTE_TMR1_300Hz){
      AJUSTE_TMR1=AJUSTE_TMR1_300Hz;
   }
   
   if(AJUSTE_TMR1 < AJUSTE_TMR1_2Hz){
      AJUSTE_TMR1=AJUSTE_TMR1_2Hz;
   }
   */
   
   t_aux=((65535-AJUSTE_TMR1));
   
   /*
   //CALCULO DE RPM: METODO 1 (LARGO)
   t_aux=(((t_aux)/(1000))*(uSxTick_TMR1));  //Calculo de periodo
   frec=((1000)/(t_aux));             //Calculo la frecuencia
   rpm=((60)*(frec));                //Calculo las rpm
   */
   
   //**
   //CALCULO DE RPM: METODO 2 (CORTO PARA AHORRAR CODIGO)
   t_aux=((t_aux)*(0.008));         //Calculo de periodo
   //frec=((1000)/(t_aux));           //Calculo la frecuencia
   rpm=((60000)/(t_aux));               //Calculo las rpm
   //**   
   
   lcd_gotoxy(1, 1);
   printf(lcd_putc, "\fRPM: %5.0f",rpm); 
   //printf(lcd_putc, "\fF(Hz): %3.2f",frec);
   //printf(lcd_putc, "\fAjuste_TMR1: %Lu",AJUSTE_TMR1); 


   tPWM=((0.7372*(float)val_apertura))+31;
   tPWM1=(int)tPWM;
   
   /*
   //LIMITADOR DE ANCHO DE PULSO
   if(tPWM1 > ticks_PULSO_MAXIMO){
      tPWM1=ticks_PULSO_MAXIMO;
   }
   
   if(tPWM1 < ticks_PULSO_MINIMO){
      tPWM1=ticks_PULSO_MINIMO;
   }
   */
   
   t_aux=(tPWM1);
   
   /*
   //CALCULO DE TIEMPO DE PULSO: METODO 1 (LARGO)
   t_aux=(((t_aux)/(1000))*(uSxTick_RTCC));
   */

   //**
   //CALCULO DE TIEMPO DE PULSO: METODO 1 (CORTO PARA AHORRAR CODIGO)
   t_aux=((t_aux)*(0.032));
   //**
   
   lcd_gotoxy(2, 1); 
   printf(lcd_putc, "\nT.I: %3.2f mS",t_aux); 
   //printf(lcd_putc, "\fF(Hz): %3.2f",frec);
   //printf(lcd_putc, "\fAjuste_TMR1: %Lu",AJUSTE_TMR1); 

}

//***INTERRUPCION POR DESBORDAMIENTO DE TIMER1**********
#int_timer1
void timer1_isr(){
   flagTMR1=1;
   set_TIMER1(AJUSTE_TMR1);
}
//***INTERRUPCION EXTERNA POR CAMBIO (L TO H) EN RB0**********
#int_ext
void ext_isr(){   
   if ( flag_antirebote == 0 ) {
      output_toggle(RELAY);      //Conmuto relay     
      flag_antirebote=1;         //Establece flag
   }
}
//****FIN DE INTERRUPCIONES***

//****INICIO DEL PROGRAMA PRINCIPAL**
void main() 
{ 
   int ValTIMER0;
   cont_antirebote=0;
   flag_antirebote=0;
   disable_interrupts(global);   //Desabilita interrupciones globales   
   setup_counters(RTCC_INTERNAL,RTCC_DIV_32);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE); 
   EXT_INT_EDGE(L_TO_H);
   setup_adc(ADC_CLOCK_INTERNAL); //activa modulo ADC 
   setup_adc_ports(sAN0|sAN1|VSS_VDD);   //AN0,AN1 como analogicas 
   set_tris_a(0b00000011);//AN0, AN1 como entradas analogicas
   port_b_pullups(FALSE);  //Desabilita pullups
   set_tris_b(0b00000001);//RB0 como entrada, lo demas como salidas

   // The lcd_init() function should always be called once,
   // near the start of your program.
   lcd_init();

   
   val_frec_anterior=0;       //Inicializo a cero valores analogicos
   val_ap_anterior=0;         //
   flagTMR1=1;                //
   SET_TIMER1(AJUSTE_TMR1_20Hz);   
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_EXT);
   enable_interrupts(global); //Habilita interrupciones globales
   
   do {
   
//***********************************
      // DISPARO DEL PULSO PWM
      if(flagTMR1==1){
         flagTMR1=0;
         output_high(PIN_PWM);
         flagPWM1=1; 
         set_TIMER0(0);
         
         //**
         // CONTROL DESDE LOS POTENCIOMETROS
         set_adc_channel(AN_FRECUENCIA);    //Selecciona canal de ajuste frec. 
         delay_us(50);  //se requiere un pequeño delay al establecer el canal
                        //y antes de la lectura
         val_frecuencia=read_adc(); //empieza la conversion, lee resultado y lo guarda     
         delay_us(10);
      
         set_adc_channel(AN_APERTURA);    //Selecciona canal de ajuste frec. 
         delay_us(50);  //se requiere un pequeño delay al establecer el canal
                        //y antes de la lectura
         val_apertura=read_adc(); //empieza la conversion, lee resultado y lo guarda 
         delay_us(10);             
         //** 
         
         //**
         // CONDICION PARA AJUSTE DE PWM    
         if(val_frecuencia!=val_frec_anterior || val_apertura!=val_ap_anterior){
            ajusta_pwm();  //Rutina debe ser lo mas breve posible!
            val_frec_anterior=val_frecuencia;
            val_ap_anterior=val_apertura;
         }
         //**
         
         //******* Rutina para antirebote ******
         if ( flag_antirebote == 1 ) {
            cont_antirebote++;
            if ( cont_antirebote>=CONSTANTE_REBOTE && !input(BOTON_REL) ) {
               cont_antirebote=0;
               flag_antirebote=0;
            }
         }   
         //************************************        
         
      }
      // CONTROL DE ANCHO DEL PULSO PWM
      if(flagPWM1==1){
         valTIMER0 = get_TIMER0();
         if(valTIMER0>tPWM1){
            flagPWM1=0;
            output_low(PIN_PWM);
            
         } 
      }
    

//**********************************
   

   } while (TRUE);

}
//***FIN DE PROGRAMA PRINCIPAL
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.