Autor Tema: Estructura Dinamica de datos en PIC  (Leído 1638 veces)

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

Desconectado p0scar

  • PIC10
  • *
  • Mensajes: 3
Estructura Dinamica de datos en PIC
« en: 25 de Noviembre de 2012, 23:36:03 »
Hola Amigos, tengo una pequeña duda y quisiera consultarlo con uds ya que siempre me saco las dudas con esta pagina sin escribir absolutamente y ahora me encuentro en el problema no encuentro este tema profundizado en ninguna lado. Aqui va: estoy haciendo un proyecto usando el PIC18F14K50 elegido principalmente por su precio sin tener en cuenta la memoria que tenia y luego avanzando mas en el proyecto me di cuenta de que si era un problema la memoria, porque necesitaba tener Buffer de los datos(de 127 caracteres c/u) provenientes de dos fuentes(USB y RS232) y cuando grabo ya me dice que tengo el 98% de la memoria ocupada y todavia me faltan muchas variables por usar. Entonces opte por no reservar la memoria directamente sino que a medida que la necesita la creaba, esto lo hacia con las estructuras dinamicas, pero aca mi problema fue que al usar 50 datos me quede sin memoria y ahi si que no entedi que paso, di mil vueltas tratando de resolver esto y nada... les paso el codigo y le comento cual es el proyecto. En este proyecto tengo que pasar de USB a RS232 y antes de convertir de nivel, tengo que ademas hacer una traducción de las instrucciones ya que las instrucciones provenientes del RS232 no las entiende la PC y viceversa (USB se conecta a PC y RS232 a un Hardware X). En este codigo que le paso solo es un rs232 a usb y viceversa, lo que quisiera que me expliquen es porque con tan pocos datos se me acaba la memoria... Bueno si saben algo al respecto me ayudan por favor Gracias.

Codigo:

#INCLUDE <EDD.h>
TYPEDEF STRUCT NODO
                   {
                    INT8 DATO;
                    STRUCT NODO *ENLACE;
                   }LISTA;
VOID MandoDatos(VOID);               //Funcion que se encarga de mandar los datos ya se por USB o por RS232
VOID TratoUsb(VOID);               
VOID TratoUART(VOID);               
VOID LIBEROMEM(LISTA *P);
BOOLEAN MandoDato=FALSE;             
INT8 BufferPC;                 
INT8 BufferImp;                 
INT8 TIMER=0;                        //Contador de tiempo, cuando llega a 4 quiere decir que pasó un segundo.
BOOLEAN DatoUSB=false;               //Bandera que indica que hay datos del USB.
BOOLEAN DatoUART=false;              //Bandera que indica que hay datos del USB
LISTA *BASE;
LISTA *BASE1;
BOOLEAN MEM=TRUE;
INT8 BUFFERAUX;
//***************************Rutina Principal***********************************************
VOID MAIN() {

   //********* CONFIGURAR EL TIMER 0 E INICIALIZO EL PUERTO USB************//   
   SETUP_TIMER_0 ( RTCC_INTERNAL | RTCC_DIV_64 ) ;  //                       
   SET_TIMER0 ( 18662 + GET_TIMER0 ( ) ) ;//Timer 0 cada 250ms
   ENABLE_INTERRUPTS(INT_RTCC);
   OUTPUT_LOW(LV);                                    // enciendo el led rojo y q aun no detecta el host
   OUTPUT_HIGH(LR);   
   USB_CDC_INIT();
   USB_INIT();                                        // Inicializamos el USB.
   USB_TASK();                                        //Habilita periferico usb e interrupciones
   USB_WAIT_FOR_ENUMERATION();                        //Esperamos hasta que el PicUSB sea configurado por el host
   OUTPUT_TOGGLE(LR);                                 //Indicamos que el PIC fue enumerado.
   OUTPUT_HIGH(LV);
   
     
 
// ************************** INICIO DEL PROGRAMA *************************************

WHILE(!USB_CDC_CONNECTED()){}                        // Espera a detectar una transmisión de la PC (Set_Line_Coding).{}
   

   
   WHILE (TRUE)
   { 
     
      USB_TASK();
      IF(USB_ENUMERATED())         
      {
     
         IF (USB_CDC_KBHIT()){                                //Pregunto si hay un dato proveniente del USB
                              LISTA *P,*Q;
                              BASE=NULL;
                              P=NULL;
                              Q=NULL;
                              P=(STRUCT NODO *)MALLOC(SIZEOF(*P));
                              BASE=P;
                              BufferPC=USB_CDC_GETC();
                              (*P).DATO=BufferPC;
                              (*P).ENLACE=NULL;
                           
                              WHILE(USB_CDC_KBHIT() && MEM){                           
                                                     BufferPC=USB_CDC_GETC();
                                                     Q=(STRUCT NODO *)MALLOC(SIZEOF(*P));                   //RESERVO UN LUGAR DE MEMORIA PARA ESTE ULTIMO DATO
                                                     IF(Q==NULL){
                                                                 printf(usb_cdc_putc, "NO HAY MAS MEMORIA");
                                                                 BUFFERAUX=BUFFERPC;
                                                                 MEM=FALSE;
                                                                }
                                                        ELSE{(*P).ENLACE=Q;             //HAGO EXACTAMENTE LOS MISMO QUE EN EL ANTERIOR SOLO QUE ACA EN EL PENULTIMO
                                                        P=Q;                                     //DATO(P1) APUNTO HACIA ESTE
                                                        (*P).DATO=BufferPC;
                                                         }
                                                     
                                                       }
                              (*P).ENLACE=NULL;
                           
                               DATOUSB=TRUE;                 
                              }

                             
                             
            IF(DatoUSB){
                        TratoUsb();                                       
                        }
       
                     
         
        IF(KBHIT()){ OUTPUT_TOGGLE(LR);                                             
                              LISTA *P,*Q;
                              BASE1=NULL;
                              P=NULL;
                              Q=NULL;
                              P=(STRUCT NODO *)MALLOC(SIZEOF(*P));
                              BASE1=P;
                              BUFFERIMP=GETC();
                              (*P).DATO=BUFFERIMP;
                              (*P).ENLACE=NULL;
                           
                              WHILE(KBHIT()){                         
                                                     BUFFERIMP=GETC();
                                                     Q=(STRUCT NODO *)MALLOC(SIZEOF(*P));                   //RESERVO UN LUGAR DE MEMORIA PARA ESTE ULTIMO DATO
                                                     IF(Q==NULL){
                                                                 printf(usb_cdc_putc, "NO HAY MAS MEMORIA");
                                                                 BUFFERAUX=BUFFERIMP;
                                                                 MEM=FALSE;
                                                                }
                                                     ELSE{(*P).ENLACE=Q;             //HAGO EXACTAMENTE LOS MISMO QUE EN ELANTERIOR SOLO QUE ACA EN EL PENULTIMO
                                                           P=Q;                       //DATO(P1) APUNTO HACIA ESTE
                                                          (*P).DATO=BUFFERIMP;
                                                         }
                                                     }
                              (*P).ENLACE=NULL;
                               DatoUART=TRUE;
                               }
             IF (DatoUART ){
                              TratoUART();                                 
                           }
         IF(MandoDato){
                       MandoDatos();                                   
                      }
      }
     }
 }
     


//************************************************Funciones*********************************************
//**********************Rutina encargada de enviar los datos vis USB o RS232****************************
VOID MandoDatos(){                             
WHILE(MandoDato){LISTA *P;
                 
                 IF (DatoUSB){P=BASE;                                                  //Si los datos provienen del USB los envio hacia la PC, en el caso de que
                              DO{                                               //no haya tratamiento de datos se cuantan los datos que llegaron, para ser enviados
                                  USB_CDC_PUTC ((*P).DATO);                   //nuevamente la misma cantidad pero por el puerto RS232. Si este no es el caso solo
                                  PUTCHAR(*P.DATO);                             //mando los comando necesarios.
                                  P=(*P).ENLACE;
                                  DELAY_MS(1);
                                  }WHILE(P!=NULL);                            //
                              IF (!MEM){
                                        USB_CDC_PUTC (BUFFERAUX);
                                        MEM=TRUE;
                                        }
                              LIBEROMEM(BASE);
                              DatoUSB=FALSE;
                              MANDODATO=FALSE;
                             
                                    }
                     IF (DatoUART)                                            //Lo mismo que el caso anterior salvo que es en el sentido opuesto
                                 {P=BASE1;
                                 DO{                                   //no haya tratamiento de datos se cuantan los datos que llegaron, para ser enviados
                                    USB_CDC_PUTC ((*P).DATO); //nuevamente la misma cantidad pero por el puerto RS232. Si este no es el caso solo
                                    //PUTCHAR(*P.DATO);             //mando los comando necesarios.
                                    P=(*P).ENLACE;
                                   }WHILE(P!=NULL);                            //
                                   IF (!MEM){
                                        USB_CDC_PUTC (BUFFERAUX);
                                        MEM=TRUE;
                                        }
                              LIBEROMEM(BASE1);
                              DatoUART=FALSE;
                              MANDODATO=FALSE;
                                    }
                 }
}
                                 

//**********************************Rutina de interpretacion del comando que llego de los Datos********************************************
//
VOID TratoUsb(VOID){
                     Switch((*BASE).DATO){                                     //Indentifico el comando y luego lo trato
                                    CASE 0x1f:
                                              MANDODATO=TRUE;
                                              BREAK;     
                                                                                                                     
                                    DEFAULT:  MANDODATO=TRUE;
                     }
}

VOID TratoUART(VOID){
                     
                     Switch((*BASE).DATO){                                    //Indentifico el comando y luego lo trato   
                                          CASE 0x01: 
                                                    MANDODATO=TRUE;
                                                    BREAK;   
                                                                                                                     
                                          DEFAULT:  MANDODATO=TRUE;
                     }
}


VOID LIBEROMEM(LISTA *P){  //EN ESTA RUTINA INTENTO LIBERAR LA MEMORIA DE LOS DATOS Q GUARDE   
                         LISTA *P1;
                         P1=P;
                         WHILE((*P1).ENLACE!=NULL){
                                          P=(*P).ENLACE;
                                          FREE(P1);
                                          P1=P;
                                                   }
                         FREE(P1);

                   }
                                         
                         
//******************************************Interrupciones***************************
#INT_RTCC //
void  RTCC_isr(VOID) //Interrupción TMR0
                   {
                   SET_TIMER0 ( 18662 + GET_TIMER0 ( ) ) ;
                   TIMER++;
                   
                   IF ( TIMER == 4 )                                            //Tiene que entrar 4 veces para que sea un segundo
                                    {
                                    TIMER = 0;
                                    IF ( USB_CDC_CONNECTED()){
                                    OUTPUT_TOGGLE(LV);}
                                    IF (!USB_ENUMERATED()){
                                    OUTPUT_TOGGLE(LV);}
                                    }
                   }