Autor Tema: Ayuda completar codigo proyecto PAP (codigo en C - 16F628A)  (Leído 3087 veces)

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

Desconectado sokoloko

  • PIC12
  • **
  • Mensajes: 77
Ayuda completar codigo proyecto PAP (codigo en C - 16F628A)
« en: 02 de Agosto de 2010, 07:02:20 »
Hola amigos,

Ya voy poco a poco comprendiendo algunas cosillas de la programación en C para PICS pero eun me queda mucho. Os pongo el codigo con el que estoy trabajando a ver si me podeis aclarar algunas cosillas y ayudarme a que funcione.

Comentar que el codigo lo he bajado de una web alemana y he ido comentando lo que mas o menos entiendo, jeje!!

Tengo el problema de que compilo el hex con mplab y no solo no me hace nada sino que las entradas del pics no me admiten valores.

Código: [Seleccionar]
// Control de motor paso a paso unipolar con un ULN2803 y un pic 16F628
// Salidas activas con 0
// Funciona con paso completo o medio paso
// control de I del motor en funcion de dos resistencias en el STK
// paro de motor despues de no recibir pulsos en 3 min
// ENTRADAS:
// RB0 = Pulsos
// RB1 = no se usa
// RB2 = Direccion en
// RB3 = Bloqueo del motor
// RB4 = Paso completo o medio
// SALIDAS:
// RA0 = Bobina A
// RA1 = Bobina B
// RA2 = Bobina C
// RA3 = Bobina D

#include <16F628A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,MCLR,NOPROTECT,BROWNOUT,NOLVP
#use fast_io(B)
#use fast_io(A)
#BYTE port_A = 5

#define dir_direccion PIN_B2
#define dir_bloqueo   PIN_B3
#define dir_paso      PIN_B4  


BYTE  ULTIMO_ESTADO=0;
// medio paso
BYTE const paso_medio[8] = {0b00000111,
                            0b00000011,
                            0b00001011,
                            0b00001001,
                            0b00001101,
                            0b00001100,
                            0b00001110,
                            0b00000110};
                              
// paso completo
BYTE const paso_completo[8] = {0b00001100,
                               0b00001100,
                               0b00000110,
                               0b00000110,
                               0b00000011,
                               0b00000011,
                               0b00001001,
                               0b00001001};
                              
                              
BYTE const paro_motor[1] = {0b11111111};
static int16 contador = 0;

// interrupcion por sobrecarga del timer
#int_timer1        //Esta funcion es llamada cada vez que timer1 sobrepasa (2^16).
timer_isr() {                  
    contador++;   //  Variable que almacena el tiempo sin señal de entrada.
    }

// interrupcion por cambio de B0
#INT_EXT
void step (void){
   int1 Dir;
   int1 Bloq;
   int1 Paso;
  
   Dir = input(dir_direccion);
   Bloq = input(dir_bloqueo);
   Paso = input(dir_paso);
   If(Bloq)
       break;  
   if (Dir)  // comprueba el bit de direccion B2
      {        
      if(ULTIMO_ESTADO==7)
          {
          ULTIMO_ESTADO=0;
          }
      else
          ULTIMO_ESTADO++;
      }
   else
      {
      if(ULTIMO_ESTADO==0)
         {
         ULTIMO_ESTADO=7;
         }
      else
         ULTIMO_ESTADO--;
     }
  
      if(Paso)        // si esta a 1 el pin B4 paso completo
          port_A = paso_completo[ULTIMO_ESTADO];
      else // Sino, paso medio
          port_A = paso_medio[ULTIMO_ESTADO];
    
     // resetea el contador de tiempo maximo de motor parado cada vez que llega un pulso
     contador = 0;
}

void main()
   {
   int i;
    setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );  //init timer1
    enable_interrupts(INT_TIMER1);  //turn on timer1 interrupt
    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
    ext_int_edge(H_TO_L);           //init interrupt edge triggering for B0, Active Low
  
     enable_interrupts(GLOBAL);
  
   set_tris_a(0x00);  //set port A&B for correct data i/o directions
   set_tris_b(0xFF);
  
  port_A = paro_motor[0];
 
    for (i=0;i<100;i++)
      {
       port_A = paso_medio[ULTIMO_ESTADO+1];
      }
    for (i=0;i<100;i++)
      {
       port_A = paso_medio[ULTIMO_ESTADO];
       }
  
   enable_interrupts(INT_EXT);     //activa la interrupcion externa de B0
 
  
while(TRUE)  //Si el pin B3 esta activo, se bloquea el motor hasta que cambia de estado.
   {
   if(input(PIN_B3))
      port_A = paro_motor[0];
   }
  }



Adjunto tmb el proyecto, y el conjunto en Proteus.



Desconectado pablomanieri

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 639
Re: Ayuda completar codigo proyecto PAP (codigo en C - 16F628A)
« Respuesta #1 en: 02 de Agosto de 2010, 08:29:07 »
Hola sokoloko.  En el esquemático del ISIS tienes conectados el Puerto A como entradas y el Puerto B como salidas y en el código tienes el puerto A como salida y el puerto B como entradas. Debes corregir eso.

Desconectado sokoloko

  • PIC12
  • **
  • Mensajes: 77
Re: Ayuda completar codigo proyecto PAP (codigo en C - 16F628A)
« Respuesta #2 en: 02 de Agosto de 2010, 16:30:35 »
Muchas gracias Pablo!!   :-/ :D

Tenia un esquema similar y lo fui modificando, sin darme cuenta de algo tan basico, jejeje!!! Ahora la ejecucion del programa funciona.

Voy a estudiar un poco mas a fondo el codigo, pues hay cosillas que no entiendo, como por ejemplo donde se definen los 3 min que si no hay impulsos de entrada se bloquean los motores, ni la parte del main (que aun no se que significan la mitad de las cosas)  :P

Muchas gracias.


Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: Ayuda completar codigo proyecto PAP (codigo en C - 16F628A)
« Respuesta #3 en: 03 de Agosto de 2010, 05:21:33 »
Lo de los tres minutos es simple. SI no hay impulsos es que el motor no s emovera y para que tenerlo con corriente tanto tiempo sobrecalentandose?
Si pasan 3 min sin que quieras que se mueva nada, se desconecta y se queda quieto, al siguiente impulso se conecta solo.

Desconectado sokoloko

  • PIC12
  • **
  • Mensajes: 77
Re: Ayuda completar codigo proyecto PAP (codigo en C - 16F628A)
« Respuesta #4 en: 03 de Agosto de 2010, 06:47:18 »
Gracias por la explicación Algec,

Entiendo que desconecte el motor para que no se caliente si no se usa, pero lo que no entiendo es en codigo como ni donde se programa, y aun menos donde se indican los 3 min.

Se que es la variable contador la que se va incrementando en cada ciclo de reloj si no hay impulso de entrada.....pero, donde se compara con 3 min??

Otra cosilla que no entiendo es esta parte del codigo:

Código: [Seleccionar]
void main()
   {
   int i;
    setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );  //init timer1
    enable_interrupts(INT_TIMER1);  //turn on timer1 interrupt
    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
    ext_int_edge(H_TO_L);           //init interrupt edge triggering for B0, Active Low
   
     enable_interrupts(GLOBAL);
   
   set_tris_a(0x00);  //set port A&B for correct data i/o directions
   set_tris_b(0xFF);
   
  port_A = paro_motor[0];
 
    for (i=0;i<100;i++)
      {
       port_A = paso_medio[ULTIMO_ESTADO+1];
      }
    for (i=0;i<100;i++)
      {
       port_A = paso_medio[ULTIMO_ESTADO];
       }
   
   enable_interrupts(INT_EXT);     //activa la interrupcion externa de B0

Por que se hacen dos bucles for de 100 pasos cada uno??   :?

Gracias.