Problema motor paso a paso

Iniciado por 02arca14, 16 Abril 2012, 19:16 PM

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

02arca14

tengo mi programa para que mi motor paso a paso trabaje y encienda con un boton pero tiene un segundo que es el paro de emergencia el cual va anclar el motor la primera parte me la hace bien enciende y apaga el motor pero no me lo ancla estoy utilizando una interrupcion externa para ello necesito bandera pero no se como utilizarlo mi codigo es el seguiente

#include <18F4550.h>
#use delay(clock=48M)
#fuses HSPLL,NOPROTECT,NOWDT,NOMCLR,NOLVP,NODEBUG,USBDIV,PLL5,VREGEN

int bandera;
#INT_EXT
void interrupts_ext0(void){
bandera=0;
output_a(0xff);
}

       
     const char pasos[5]={0x0c,0x06,0x03,0x09};
         signed  int8 i;
      void main(){
          enable_interrupts(INT_EXT);
          enable_interrupts(GLOBAL);
          ext_int_edge(L_TO_H);
   
   for(;; ){

             
     if(input(pin_a5)){
     bandera=1;}
     
    if(bandera){
    bandera=1;
           for(i=0;i<=3&&bandera;i++)
              {output_a(pasos);
              delay_ms(250); }
                                 
           
          for(i=3;i>0&&bandera;i--)
            {output_a(pasos);
              delay_ms(250); } 
     
     }
      else{
      output_a(0x00);
     
      }   
     
   }
   
  }
     
   


skapunky

#1
La idea es buena, pero las banderas siempre se usan con while, en caso de quererlas utilizar con IF debes al hacer la comprobación hacer un salto con "goto" desestructurando el programa y es algo que si se puede evitar es mejor. Fijate en esta idea:

En la interrupción externa la idea es darle un valor a la bandera, eso lo has hecho bien..pero para que cambias el estado del puerto A? Eso en éste caso deberías hacerlo en el programa principal. Lo ideal es solo dar valores al flag en la interrupción externa.

Fijate en lo que hago, a ver si te sirve de inspiración:

//Condiciones iniciales
bandera =1;
//fin condiciones iniciales
int bandera;
#INT_EXT
void interrupts_ext0(void){
bandera=0;
// output_a(0xff); Esto no se que es, pero ponlo en la parte principal del programa sea lo que sea.
}

void main{

while (bandera){  //si bandera=1 se ejecutará el programa con normalidad
  for(i=0;i<=3&&bandera;i++)
             {output_a(pasos);
             delay_ms(250); }
                               
         
         for(i=3;i>0&&bandera;i--)
           {output_a(pasos);
             delay_ms(250); }  
}
output_a(0x00); //esto se ejecutará al activar int externa donde bandera =0
bandera = 1;  // Reseteamos al valor inicial el flag
}


Espero que aunque no te funcione bien el programa puesto, no se que es cada salida ni entrada ni el funcionamiento, veas el úso que le doy a la bandera con el while.

Por otro lado, tu programación se le puede corregir unos detalles, acostumbrate a utilizar una primera fase con las condiciones iniciales del sistema contodas las variables y puertos configurados.

-Utiliza la instrucción "tris_X" para determinar si es puerto de entrada o salida.

-Pon las variables declaradas todas juntas en la parte superior del programa.

-Para determinar el estado de un puerto, hay una instrucción llamada "input_state(XX)" donde XX es el puerto y bit de éste. Por ejemplo :

if (input_state(A0) {
} //el bit o del puerto A vale 1
else
{ //el bit o del puerto A vale 0
}

- Último detalle a comentarte, para assignar utiliza =, para comparar ==, eso tenlo presente.
Killtrojan Syslog v1.44: ENTRAR

02arca14

la declaracion output_a(0xff) me explicaron que declaro mi todo mi puerto a  que tenga comom salida 1 .
la bandera si le entendi como usarla a tu explicacion y utilize para cambiar mi codigo .
cambiando el codigo y usando 2 interunciones mas se logra anclear el motor q es el paro de emergencia
es este mi segundo codigo


#include <18F4550.h>
#use delay(clock=48M)
#fuses HSPLL,NOPROTECT,NOWDT,NOMCLR,NOLVP,NODEBUG,USBDIV,PLL5,VREGEN

int bandera;

#INT_EXT
void interrupts_ext0(void){
if (bandera){
bandera=0;
output_a(0x00);
}
else {
bandera=1;}

}
#INT_EXT1
void interrups_ext1(void){
if (bandera){
output_a(0xff);
bandera=0;
}
else{
output_a(0x00);}

         
         }
       
     const char pasos[5]={0x0c,0x06,0x03,0x09};
         signed  int8 i;
      void main(){
          enable_interrupts(INT_EXT);
          enable_interrupts(INT_EXT1);
          enable_interrupts(GLOBAL);
          ext_int_edge(L_TO_H);
         
   
   for(;;){

             
     if(bandera){   /*me pregunta por el estado de la badera si es 1 realiza las operacion del bucle ya que maneja una an si n o es 1 no lo realiza*/
   
           for(i=0;i<=3&&bandera;i++)
              {output_a(pasos);
              delay_ms(250); }
                                 
           
          for(i=3;i>0&&bandera;i--)
            {output_a(pasos);
              delay_ms(250); } 
   
     
     }
       
     
   }
   
  }
     
   


skapunky

#3
Citarla declaracion output_a(0xff) me explicaron que declaro mi todo mi puerto a  que tenga comom salida 1 .

Exacto, es decir pones todo el puerto A a 11111111, pero fijate que lo tienes puesto en el boton de la int externa, es decir al pulsar en tu codigo cambias el flag bandera=1 y pones todo el puerto A en estado alto, donde es mas aconsejable esto último hacerlo en el programa principal.

Una cosa es la declaracion de los puertos como entrada/salida y otra es poner un puerto todo a 0 o 1 (no es lo mismo!). Las declaraciones de los bits de los puertos, para configurarlos como entrada o salida se utiliza la instrucción tris_X, donde X es el nombre del puerto. Esta declaración se hace a principio de codigo, donde se suelen poner eso y las condiciones iniciales.

Si por ejemplo quiero tener todo el puerto A como salida, pondría al principio del programa:

//condiciones iniciales
TRIS_A (0xFF) //declaramos puerto A como salida
output_a (0xFF) //siempre va bien hacer esto, para iniciar el puerto con los pines en el mismo estado ya que a veces se inician mal, lo puedes comprobar en un simulador como proteus.
// fin condiciones iniciales

void main(){
//tu programa
}



NOTA:

Depende la libreria, en vez de usar TRIS_X se usa SET_TRIS_X

Por cierto, te funciona el programa sin declarar los puertos como E/S mediante TRIS ???? lo estas usando en un simulador o en el PIC directamente? Lo único que se me ocurre es que uses el CCS con su wizard, donde puedes declarar mediante opciones del wizard que puertos son de E/S sin la necesidad de escribir tu manualmente los TRIS.
Killtrojan Syslog v1.44: ENTRAR

02arca14

 me funciona sin declarar tris  ya que utilize output_a con lo que digo mi q todo mi puerto a es de salida y lo cheque en proteus y si me salio utilizo pic c para programar.
y en mi paro de emergencia de mi motor necesito ponerlo a 1 toda mis salidas de mi pic para q entren en el ulm2803 y asi enclavar mi motor paso
a paso . mi diagrama tiene un pic el 18f4550,ulm2803,y un motor paso a paso

#INT_EXT     /  este es mi interrupcion B0 cuando mi interrupcion entre mi  bandera si esta en cero la cambiara a 1 y si es uno a cero y cambiara el funcionamiento de mi programa principal lo encendera y  para mi motor normalment.

void interrupts_ext0(void){
if (bandera){
bandera=0;
output_a(0x00);
}
else {
bandera=1;}

}


#INT_EXT1     /interrupcion B1 este funcionara cuando mi bandera este en uno la cambiara a cero por lo cual saldra en mis salida por todo el puerto a un 1 y asi anclando mi motor esta interrupcion es mi paro de emergencia amarra el motor para que no siga girando por inercia
void interrups_ext1(void){
if (bandera){
output_a(0xff);
bandera=0;
}
else{
output_a(0x00);}

         
         }