Autor Tema: Problemas con Mplab 7.30 al programar el 18F4550, "Address good bad"  (Leído 2836 veces)

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

Desconectado Souflo

  • PIC10
  • *
  • Mensajes: 1

Buenas!! Estoy haciendo un proyecto con el pic 18F4550, mplab7.30 y ccsc pcwh 3.236. Se trata de un control de motores y odometría para un robot móvil de tracción diferencial. Aún tengo mucho por hacer pero ya empiezo a tener problemas con lo poco que hice hasta el momento. El caso es que compilo el programa y todo va bien, solo me da un warning de un while TRUE. Pero al ir a programar el PIC con el programador jupic, compatible con picstart plus, la programación parece que se hace correctamente, pero cuando empieza la verificación, ésta falla dando el siguiente error: Program Memory Errors, Address  Good  Bad, y aparecen un monton de direcciones de memoria y sus correspondientes contenidos.

El programa es un bucle infinito que chequea constantemente si se activa a nivel alto alguna de las patillas del puerto b, cuando esto sucede, activo los 2 motores a una velocidad determinada usando una controladora de motores MD22 en modo I2C, una vez que están en movimiento los motores, se hacen una serie de mediciones de los encoders de cuadratura, 10 mediciones de cada encoder, de las cuales luego me quedo con la medición que mas veces se repitió, para más adelante desarrollar un algoritmo de control P-I o P-I-D, y un control odométrico. Pero este problema de Address good bad me tiene bloqueado. Parece que la programación se lleva a cabo, aunque con errores en la verificación. Si pruebo a montar el PIC programado en el circuito de prueba, éste no deja de resetearse continuamente.

Por otra parte, no consigo que me funcione la interrupción del timer0, uso un cristal externo de 4Mhz y según los cálculos que hice para conseguir una frecuencia de desborde cada 100ms, debería de utilizar un preescaler de 4 e inicializar el timer0 de 16 bits con el valor 40536, pero la cosa no funciona. Como debería de configurar el timer 0?

Y por último, otra duda. Intento utilizar el timer1 de 16 bits para capturar los pulsos de un encoder, y el timer 3 para los pulsos del otro encoder, pero en el PIC 18F4550 el timer 1 y el timer 3 creo que comparten las patillas de entrada, por lo que solo controla los pulsos de un encoder. Habría alguna manera de utilizar independientemente cada timer por separado para contear los pulsos, o tengo que cambiar a otro PIC.

Gracias por adelantado por cualquier ayuda que me podais brindar, os adjunto el código del programa para que podais ver en que me estoy equivocando. :(

/// CONFIGURACION INICIAL   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <18f4550.h>                        //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT   //XT=> 4MHz, NOWDT=>sin perro guardián, PUT=>power up timer , NOPROTECT=>sin proteccion contra lectura
#use delay(clock=4000000)                      //velocidad del cristal externo, habilitandose delay_ms() y delay_us()
#use i2c(master, sda=PIN_B0, scl=PIN_B1)        //definicion i2c estandar
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7) //definición rs232 estandar
#use standard_io(A)                            //puerto A como salida, el compilador genere codigo para hacer q un pin de E/S sea entrada o salida
                                              //cada vez que se utiliza
 
/// CONSTANTES Y VARAIABLES GLOBALES  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//int const MD22_dir_lec=0xB1;        // Direccion I2C de la controladora (para lectura)
int const MD22_dir_esc=0xB0;          // Direccion I2C de la controladora (para escritura)
int control_0 = 0;
int control_2 = 0;
int contador_timer = 0;
int i = 0;
int j = 0;
int k = 0;
int16 contador_encoder1 = 0;
int16 contador_encoder2 = 0;
int tics_10ms_i[10] = {0,0,0,0,0,0,0,0,0,0};
int tics_10ms_d[10] = {0,0,0,0,0,0,0,0,0,0};
int tics = 0;


/// DECLARACIONES DE FUNCIONES  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void i2cw1(int i2cdev, int i2cdir, int i2cdat); // Rutina de escritura I2C completa
void i2cw2(int i2cdev, int i2cdat);             // Rutina de escritura I2C parcial
void controla_velocidad();                      // Rutina para el control de la velocidad del motor
int get_tics();                           //Función que se queda con el valor mas repetido de tics en las 10 mediciones de cada encoder


/// ISR del Timer1  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#int_RTCC
 void TIMER0_isr() {

   output_high(PIN_A0);   // Para ver la duración de esta ISR.
   contador_timer++;
   set_timer0(40536);
   //printf("timer0_int__=%U\n\r",contador_timer);
   output_low(PIN_A0);
}


/// PROGRAMA  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void main(void)
{
    delay_ms(500);                        //Breve Retardo para que se estabilice la tension
   set_tris_a(0xf0);                     //portA como salida
    set_tris_b(0xff);                     //PortB como entrada
   //setup_counters(RTCC_EXT_L_TO_H, RTCC_DIV_4);
    //setup_counters(RTCC_INTERNAL, RTCC_DIV_4);
   setup_timer_1(T1_EXTERNAL);
   setup_timer_3(T3_EXTERNAL);
   //set_timer0(40536);
   set_timer1(0);
   set_timer3(0);

   //enable_interrupts(INT_RTCC); //Habilitamos la interrupcion del timer 0
   //enable_interrupts(Global);
   printf("\nPIC Iniciando\n\r");

        i2cw1(MD22_dir_esc, 0, 1);               //selecciono modo de funcionamiento 1: -128=atras todo 0=parada 128=avance todo
      delay_ms(32);                      //                             3: reg1->velocidad ambos motores [-128 127] reg2->giro centro=0
      i2cw1(MD22_dir_esc, 1, 0);               //Freno el motor escribiendo 0 en el registro 1
      delay_ms(32);

      output_high(PIN_A2);
      delay_ms(1000);
        output_low(PIN_A2);

   do{

   output_high(PIN_A1);

      if (input(PIN_B2)){                  //Si activamos el pin B0 velocidad al 50% (avance)
     delay_ms(200);                     //Retardo para evitar rebotes
      if (input(PIN_B2)&&control_0 == 0&&!input(PIN_B5)){
         i2cw1(MD22_dir_esc, 1, 50);
         i2cw1(MD22_dir_esc, 2, 50);
         control_2 = 0;
         control_0 = 1;
          output_low(PIN_A1);
         delay_ms(200);
         output_high(PIN_A1);
         controla_velocidad();
         tics = get_tics();
         printf("tics/10ms_i = %U\n\r",tics);
      }
      if (input(PIN_B2)&&control_0 == 1&&input(PIN_B5)){      //Frenada si velocidad = 50%
      delay_ms(200);
         if (input(PIN_B2)&&(control_0 == 1)&&(input(PIN_B5))){
            i2cw1(MD22_dir_esc, 1, 0);
            i2cw1(MD22_dir_esc, 2, 0);
            control_0 = 0;
             output_low(PIN_A1);
            delay_ms(200);
            output_high(PIN_A1);
            controla_velocidad();
            tics = get_tics();
              printf("tics/10ms_i = %U\n\r",tics);
         }
      }
      }

     else if (input(PIN_B3)&&control_0 == 0&&!input(PIN_B5)){      //Velocidad = 75%
     delay_ms(200);
         if(input(PIN_B3)&&control_0 == 0&&!input(PIN_B5)){
            i2cw1(MD22_dir_esc, 1, 100);
            i2cw1(MD22_dir_esc, 2, 100);
            control_2 = 0;
            control_0 = 2;
            output_low(PIN_A1);
            delay_ms(200);
            output_high(PIN_A1);
            controla_velocidad();
                tics = get_tics();
              printf("tics/10ms_i = %U\n\r",tics);
         }
          if (input(PIN_B3)&&input(PIN_B5)&&control_0 == 2){  //Frenada si velocidad = 75%
          delay_ms(200);
           if (input(PIN_B3)&&input(PIN_B5)&&control_0 == 2){
            i2cw1(MD22_dir_esc, 1, 0);
            i2cw1(MD22_dir_esc, 2, 0);
            control_0 = 0;
            output_low(PIN_A1);
            delay_ms(200);
            output_high(PIN_A1);
            controla_velocidad();
            tics = get_tics();
            printf("tics/10ms_i = %U\n\r",tics);
           }
          }
     }

     else if (input(PIN_B4)&&control_0 == 0&&!input(PIN_B5)){               //Si activamos el pin B2 velocidad marcha atras al 25%
     delay_ms(200);
         if(input(PIN_B4)&&control_0 == 0&&!input(PIN_B5)){
            i2cw1(MD22_dir_esc, 1, 127);
            i2cw1(MD22_dir_esc, 2, 127);
            control_0 = 3;
            control_2 = 0;
              output_low(PIN_A1);
            delay_ms(200);
            output_high(PIN_A1);
            controla_velocidad();
            tics = get_tics();
            printf("tics/10ms_i = %U\n\r",tics);
         }
            if (input(PIN_B4)&&control_0 == 3&&input(PIN_B5)){   //Frenada si velocidad marcha atras
         delay_ms(200);
            if (input(PIN_B4)&&control_0 ==3&&input(PIN_B5)){
               i2cw1(MD22_dir_esc, 1, 0);
               i2cw1(MD22_dir_esc, 2, 0);
               control_0 = 0;
               output_low(PIN_A1);
               delay_ms(200);
               output_high(PIN_A1);
               controla_velocidad();
               tics = get_tics();
                 printf("tics/10ms_i = %U\n\r",tics);
            }
         }
     }
     else if (input(PIN_B5)&&control_2 == 0){         //Si en cq momento se activa PIN_B3 se produce una frenada
     delay_ms(200);
         if (input(PIN_B5)){
            i2cw1(MD22_dir_esc, 1, 0);
              i2cw1(MD22_dir_esc, 2, 0);
            control_2 = 1;
            control_0 = 0;
         }

      }
   output_low(PIN_A1);
    }while(TRUE);
}


/// FUNCIONES  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void controla_velocidad(){

 j = 0;

 for(j=0;j<10; j++){
 
  set_timer1(0);
  delay_ms(10);
  contador_encoder1 = (get_timer1());
  tics_10ms_i[j] = contador_encoder1;
  printf("encoder_i(tics/10ms)=%lu\n\r",contador_encoder1);
  contador_encoder1 = 0;
 }

 j=0;

 for(j=0;j<10;j++){

  set_timer3(0);
  delay_ms(10);
  contador_encoder2 = (get_timer3());
  tics_10ms_d[j] = contador_encoder2;
  printf("encoder_d(tics/10ms)=%lu\n\r",contador_encoder2);
  contador_encoder2 = 0;
 }
 printf("timer0_int=%U\n\r",contador_timer);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int get_tics(){

int aux[4]={0,0,0,0};
int cont[4]={0,0,0,0};
int cambio = 0;
int x=0;

i=1;
aux[0] = tics_10ms_i[0];
cont[0]++;

 for(x=0;x<3;x++){
  for(i=1;i<10;i++){
    if(tics_10ms_i==aux
  • ) cont
  • ++;   

   else if (cambio == 0){
      aux[x+1] = tics_10ms_i;
        cont[x+1]++;
      cambio = 1;
    }
  }
  i=1;
  cambio=0;
 }

 for(i=0;i<10;i++){
   if(tics_10ms_i==aux[3]) cont[3]++;
 }

i=0;
j=0;
k=0;
 for(j=0;j<4;j++){
  for(i=0;i<4;i++){
   if (cont[j]>=cont) k++;
  }
  if (k==4) return(aux[j]);
  k=0;
}

}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void i2cw1(int i2cdev, int i2cdir, int i2cdat){ // Rutina de escritura I2C completa

  i2c_start();                  // Inicializo comunicación I2C
  i2c_write(i2cdev);            // Envio Dirección de dispositivo I2C + R/W
  i2c_write(i2cdir);            // Envio address eeprom donde escribir
  i2c_write(i2cdat);            // Envio byte a escribir
  i2c_stop();                   // Cierro comunicacion
  delay_ms(32);          // Espero a que escriba correctamente

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void i2cw2(int i2cdev, int i2cdat){             // Rutina de escritura I2C parcial


  i2c_start();                  // Inicializo comunicación I2C
  i2c_write(i2cdev);            // Envio Dirección de dispositivo I2C + R/W
  i2c_write(i2cdat);            // Envio byte a escribir
  i2c_stop();                   // Cierro comunicacion
  delay_ms(32);          // Espero a que escriba correctamente

}


 

anything