Autor Tema: Duda con PWM por software  (Leído 1422 veces)

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

Desconectado venturl

  • PIC10
  • *
  • Mensajes: 4
Duda con PWM por software
« en: 03 de Julio de 2012, 14:05:48 »
Hola:
Veran, mi proyecto consiste en comunicar por cdc una placa con un pic 18f2550 a 4 mhz y Labview. En Labview solo hay 4 pulsadores (arriba abajo izquierda y derecha), que mandan al pic por el puerto B los valores 0x01 , 0x02 , 0x04 o 0x08, segun la direccion seleccionada. Este es el programa que uso en el pic:

#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
#use delay(clock=48000000)
#include ".\libreria\usb_cdc.h"
#rom int 0xf00000={1,2,3,4}

void main() {
   int8 x;
   set_tris_b(0x00);
   output_b(0x00);
   usb_cdc_init(); // Configuramos al puerto virtual.
   usb_init(); // Inicializamos el stack USB.
     while(!usb_cdc_connected()) {} // espera a detectar una transmisión de la PC
       do{usb_task();
          if (usb_enumerated()){  // Espera a que el dispositivo sea enumerado por el host.
            if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
                x=usb_cdc_getc();
                output_b(x);
                
              }
             }
       }while (TRUE); // bucle infinito.
  
}


Hasta aqui no hay ningun problema, todo funciona correctamente.

Ahora necesito generar una PWM por software que segun las consignas de Labview haga que dos servomotores giren a izquierda o derecha.
Los servos son Parallax continuous rotation con 1.3ms(para izquierda) o 1.7ms(para derecha) y 20 ms de periodo.

Se que debo usar las interrupciones de los timers:
void TIMER1_isr()
{
set_timer1( xxx );
}


Pero desconozco la forma en que esto funciona.




Un saludo y muchas gracias.

P.D. he usado la busqueda pero ningun hilo me ha resuelto la duda.
« Última modificación: 03 de Julio de 2012, 14:07:58 por venturl »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Duda con PWM por software
« Respuesta #1 en: 03 de Julio de 2012, 14:21:00 »
Utiliza el buscador, hay infinidad de ejemplos de utilización del timers  ;-)
No contesto mensajes privados, las consultas en el foro

Desconectado venturl

  • PIC10
  • *
  • Mensajes: 4
Re: Duda con PWM por software
« Respuesta #2 en: 03 de Julio de 2012, 17:36:25 »
Hola, he buscado pero no me ha quedado muy claro...

Añado esto que he puesto para que por favor valoren si esta bien:

Programa principal:#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
#use delay(clock=48000000)
#include ".\libreria\usb_cdc.h"
#rom int 0xf00000={1,2,3,4}

int8 x;
int16 contador=0;
int16 frec=0;            // Variable que indica la frecuencia del PWM
int anchura=0;         // Anchura del PWM, el duty cicle
int salidaservo=0;
int paro=0;

void main()
{
 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
 set_timer1(65435);               // cargamos el timer para que cuente 100 uS
 enable_interrupts(int_timer1);   // Seleccionar interrupciones por rebasamiento de TMR0
 enable_interrupts(GLOBAL);      // Activar interrupciones

 
   set_tris_b(0x00);
   output_b(0x00);
   usb_cdc_init(); // Configuramos al puerto virtual.
   usb_init(); // Inicializamos el stack USB.
     while(!usb_cdc_connected()) {} // espera a detectar una transmisión de la PC (Set_Line_Coding).
       do{usb_task();
          if (usb_enumerated()){  // Espera a que el dispositivo sea enumerado por el host.
            if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
                x=usb_cdc_getc();
                output_b(x);
               
                //seleccion de servos y direccion
            
              if (x==0x04)   //izquierda
               {
                  frec=200;    //200*100uS=20 ms
                    anchura=100;  //17*100uS =1.7ms
                   salidaservo=PIN_A0 ; // salida del primer servo
               }
         else if (x==0x02)  //adelante
               {
                  frec=200;
                    anchura=13;
                   salidaservo=PIN_A1 ;
               }
         else if (x==0x08)  //derecha
               {
                     frec=200;
                  anchura=17;
                   salidaservo=PIN_A0 ;
               }
         else if (x==0x10)  //atras
               {
                  frec=200;
                  anchura=13;
                    salidaservo=PIN_A1 ;
                    }
            else if(x=0x00)
                    {
                     frec=200;
                     paro=1;
                    }
                }
             }
       }while (TRUE); // bucle infinito.
     
}




#int_TIMER1
TIMER1_isr()
{
  contador=contador+1;   //esta variable marca el numero de 100uS que se han dado

   if (contador<anchura)
    {
      output_high(salidaservo); 
    }
   else
    {
      output_low(salidaservo);
    }
   if (contador==frec||paro==1) 
    {
       paro=0;
       contador=0;      // Reseteamos el contador
    }

  set_timer1(65436);  //?????????????????
}
« Última modificación: 04 de Julio de 2012, 07:31:36 por venturl »


 

anything