Autor Tema: Problema con programa usando CCS para el pic18F4550  (Leído 4572 veces)

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

Desconectado Arttak

  • PIC10
  • *
  • Mensajes: 4
Problema con programa usando CCS para el pic18F4550
« en: 12 de Noviembre de 2009, 23:56:02 »
Buenas a todos  :)

Estoy realizando un proyecto con el pic184550 para controlar una brujula electronica que esta empotrada en un servomotor que permite el movimiento en 180°, de manera que si yo le indico una posicion especifica, ante perturbaciones al movimiento del sistema este vuelva a la posicion inicial (en mi caso a los 90°).

He tenido problemas para poder obtener datos de la brujula por medio de la comunicacion I2C asi que queria poner el codigo de lo que he realizado para ver si me puedan ayudar a encontrar el error que estoy cometiendo.

Gracias de antemano a todos los aportes :D

Como preambulo les explico ciertas caracteristicas del sistema:

- La brujula permite obtener por medio de la comunicacion I2C su posicion en grados con respecto a una referencia de 0° en direccion al Norte.
- Dentro de las especificaciones de la brujula se pide que el bus de comunicacion trabaje a una frecuencia de 160kHz y en caso de excederse hasta 1MHz utilizar delays de 50us entre las escrituras al registro de la brujula.
- El servomotor tiene una libertad de movimiento de hasta 180°
- La posicion fija o posicion en estado estable es a los 90°, es por esto que se calcula el error para calcular el tiempo del delay para permitir el movimiento del servomotor.

CODIGO:

#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1                     //No PLL PreScaler

#use delay(clock=20000000)
#use i2c(Master,Fast,sda=PIN_B0,scl=PIN_B1)


#define   boton   PIN_A3     // Entrada del boton
#define   izq   PIN_A1
#define   der   PIN_A2


#define   led_0   portd,0     //Salidas a LED
#define   led_1   portd,1
#define   led_2   portd,2
#define   led_3   portd,3
#define   led_4   portd,4
#define   led_5   portd,5
#define   led_6   portd,6
#define   led_7   portd,7

void leer_brujula();
void pwm_der();
void pwm_izq();

int brujula;
int referencia = 90;
int error;
int time;

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(False);

   // TODO: USER CODE!!

while(true)
   {       
      if (!input(boton))
      {

      leer_brujula();            //Llamo al modulo de comunicacion I2C para leer la posicion que tiene la brujula en grados
      output_d(brujula);         //Imprime en el puerto D el dato en bits que corresponde a los grado leido desde la brujula
     
         if(brujula != 90)       //Como el servomotor tiene una libertad de 180° se establece 90° como la posicion a la que debe regresar el sistema, posicion estable
         {
     
            if(brujula < 90){
               
               error = referencia-brujula;   //Se calcula la diferencia entre la posicion leida por la brujula y los 90°
               time = error*5;               //Se calcula el tiempo de delay que permanece en alto la señal que activa el movimiento del servo hacia la derecha
               output_low(izq);
               output_high(der);             //Se activa la señal que mueve el servomotor a la derecha
               delay_ms(time);               //Tiempo que tarda la señal en alto
               output_low(der);*/
            }
           
            if(brujula > 90){
               
               error=brujula-consigna;    //Se calcula la diferencia entre la posicion leida por la brujula y los 90°
               time=error*5;              //Se calcula el tiempo de delay que permanece en alto la señal que activa el movimiento del servo hacia la izquierda
               output_high(izq);          //Se activa la señal que mueve el servomotor a la izquierda
               output_low(der);
               delay_ms(time);            //Tiempo que tarda la señal en alto
               output_low(izq);*/
 
            }
         }
         else{
         output_low(der);              //Mantiene en bajo la señal de movimiento del servomotor a la derecha
         output_low(izq);              //Mantiene en bajo la señal de movimiento del servomotor a la izq
         output_d(brujula);            //pone el valor de la brujula en binario en los pines RD0 A RD7       
         }
     
     
       
      }     
                     

   }

}



void leer_brujula()
{
   int   respaldo;
   
   i2c_start();               //Start
   i2c_write(0b11000000);     //Control  **Dirección del dispositivo con el último bit (R/W) en cero
   i2c_write(0b1);            //Direccion   **Número de registro a leer
   i2c_stop();                //Stop
   i2c_start();               //Start
   i2c_write(0b11000001);     //Control para lectura   **Número de registro a leer con el último bit (R/W) en uno
   
   respaldo = i2c_read();     //Se lee los grados de la brujula y lo guardo en respaldo
   brujula = respaldo;        //guardo la información en la variable global grados
   i2c_stop(); //Stop*/
}

---------------------------------------------------------------------------------------------------------------------------------------
Dentro de las posibles ideas que tengo que esto no me esta realizando lo que espero que sucediera es en cuanto a los tiempos de comunicacion del I2C. Creo que al trabajar con un cristal de 20MHz deberia de existir una manera de establecer la comunicacion al tiempo de 160KHz como especifica la hoja de datos de la brujula electronica, pero tengo falta de concepto en esa área.

Agradeceria bastante si alguien me pudiera ayudar en ver si tengo algun error en la forma que defino la comunicacion I2C y si tengo problemas de tiempos que talvez estoy leyendo varias veces el dato y no permite al pic realizar el analisis del grado leido desde el registro de la brujula.

Muchas Gracias de antemano por la ayuda B)


Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problema con programa usando CCS para el pic18F4550
« Respuesta #1 en: 14 de Diciembre de 2009, 14:20:13 »
¿Qué modelo de brújula es?, yo he usado una CPMS03 y quizás podría ayudarte si es la misma.