Autor Tema: Onda Cuadrada para controlar motor  (Leído 2235 veces)

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

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
Onda Cuadrada para controlar motor
« en: 14 de Febrero de 2005, 16:45:00 »
Hola

Estoy realizando un programa para controlar un motor de pasos pequeño (practico con este porque luego va a ser más grande). Lo que hago es generar una señal cuadrada que varia tanto en frecuencia como en ciclo de trabajo. Para esto estoy haciendo uso de las interrupciones por desbordamiento del timer así como la de puerto serie (RDA). Para las señales de control utilizo visual basic y mi problema es que en ocasiones el pic deja de responder cuando doy la instrucción de detener. La interrupción por puerto serie la utilizo para detener el motor, y la de desbordamiento para generar la señal cuadrada. Creo que tengo problemas en como preguntar acerca del caracter de entrada y tal vez ahí se quede, pero según yo no debería haber problema. El código es este:
Codigo:

#include <16f874A.h>
#fuses HS, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <lcd.c>

//long cicalt=10;
//long periodo=150;
char rotacion, paso,terminar;
long cicalt,periodo;
int i,j;
long cicbaj,retardo,conteo;

#INT_RTCC
pulso()
{
if(--conteo==0)
   {
      output_high(PIN_B0);
       for(i=1;i<=periodo;i++)
         {
            for(j=1;j<=cicalt;j++)
               {
               delay_ms(1);
               }
         }
      conteo=retardo;
   }
output_low(PIN_B0);
set_rtcc(178);
}

#INT_RDA
detener()
{
   terminar=getc();
   if (terminar=="s")
      {
         disable_interrupts(GLOBAL);
         disable_interrupts(INT_RTCC);
         disable_interrupts(INT_RDA);
         output_b(0);
         reset_cpu();
      }
}

main()
   {
      set_tris_b(0xF0);      
      output_high(PIN_B1);
      while(!kbhit()); //Espera la recepcion de un caracter
      periodo=getc();
      while(!kbhit()); //Espera la recepcion de un caracter
      cicalt=getc();
      while(!kbhit()); //Espera la recepcion de un caracter
        rotacion=getc();
      while(!kbhit()); //Espera la recepcion de un caracter
        paso=getc();
      if (rotacion=="i")
         {
            output_high(PIN_B2);
         }
      else if (rotacion=="d")
         {
            output_low(PIN_B2);
         }
      if (paso=="m")
         {
            output_high(PIN_B3);
         }
      else if (paso=="c")
         {
            output_low(PIN_B3);
         }
      output_low(PIN_B1);
      //output_low(PIN_B2);
      //output_low(PIN_B3);
      cicbaj=20-cicalt;
      retardo=periodo*cicbaj;
      conteo=retardo;
      lcd_init();
      lcd_putc("f");
      lcd_gotoxy(1,1);
      printf(lcd_putc,"cicbaj=%2lu",cicbaj);
      lcd_gotoxy(1,2);
         printf(lcd_putc,"conteo=%4lu",conteo);
      setup_counters(RTCC_INTERNAL,RTCC_DIV_64);
      set_rtcc(178);
      enable_interrupts(INT_RTCC);
      enable_interrupts(INT_RDA);
      enable_interrupts(GLOBAL);
         while(TRUE);
   }


Gracias

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
RE: Onda Cuadrada para controlar motor
« Respuesta #1 en: 15 de Febrero de 2005, 00:29:00 »
Pues si te funciona todo, excepto la detención al pulsar una tecla, es probable que la interrupción esté interfiriendo y por eso no funcione.
De todas formas, ¿porqué no lo haces con PWM y te ahorrarás bastante código?

Desconectado badtzdizzy

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 234
RE: Onda Cuadrada para controlar motor
« Respuesta #2 en: 15 de Febrero de 2005, 16:58:00 »
Gracias por tu sugerencia, de hecho el error lo tenía en el visual basic y es que en ocasiones no se cargaba el valor en la variable y pues me mandaba un dato "vacío" por el puerto serie y el pic se colgaba. Existe alguna forma de prevenir esto en el pic?

Por otro lado si había pensado en usar el PWM pero voy a manejar frecuencias bien pequeñas (0.33 - 50 Hz) y pues tal vez tenga problemas con el cristal. Y pues como voy a estar variando esos valores pues ya te imaginarás.

Ahorita estoy haciendo por partes mi programa porque quiero hayar la mejor forma de mandar ésta señal al driver de un motor de pasos y al mismo tiempo recibir datos y meterlos al convertidor para posteriormente graficarlos en tiempo real. Y pues es ahí donde me estoy atorando. De hecho como te dije ya tengo ambos programas pero ahora no se como unirlos.

Si me pueden echar la mano se los agradecería bastante.

Para el motor es el programa de arriba y para los datos es este:
Codigo:

#include <16f874A.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#device ADC=10
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  
#include<lcd.c>

long i, dato, muestras;
int tmuestreo;
char datohigh, datolow, temp;

void adquirir()
   {
      delay_us(tmuestreo);
                           dato = read_adc();
      datolow=dato;
      temp=(dato>>8);
      datohigh=temp&3;
      putc(datohigh);
      putc(datolow);      
                }
                        

main()
{
   long dato;
   char valor, canal;
   int periodohigh, periodolow, muestrashigh, muestraslow;
   int tmuestreo;
   long periodo, muestras;
   setup_adc_ports( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   lcd_init();
   while(!kbhit()); //Espera la recepcion de un caracter
   valor=getc();
   if (valor=="j")
     {
   output_high(PIN_B7);
                putc("8");
   while(!kbhit()); //Espera la recepcion de un caracter
   muestrashigh=getc();
   while(!kbhit()); //Espera la recepcion de un caracter
   muestraslow=getc();
   while(!kbhit()); //Espera la recepcion de un caracter
                periodohigh=getc();
   while(!kbhit()); //Espera la recepcion de un caracter
   periodolow=getc();
   muestras=muestrashigh*256+muestraslow;
   periodo=periodohigh*256+periodolow;
   tmuestreo=(50*periodo)/muestras;
   lcd_putc("f");
         lcd_gotoxy(1,1);
   printf(lcd_putc,"p=%4lu",periodo);
   lcd_gotoxy(9,1);
   printf(lcd_putc,"m=%4lu",muestras);
   lcd_gotoxy(1,2);
         printf(lcd_putc,"tm=%3u",tmuestreo);
    while (TRUE)
                          {
      while(!kbhit()); //Espera la recepcion de un caracter
      valor=getc();
         if (valor=="i")
         {
                  for (i=1;i<=muestras;i++)
               {        
                                                                                                set_adc_channel( 0 );
                  adquirir();
                  set_adc_channel( 3 );
                  adquirir();
               }
         }
         else reset_cpu();
                   }
   }
}




 

anything