Como siempre: No es tan difícil como parece.
El error que me da al compilar con CCS es el siguiente:
* Error 71 "C:\Users\José\Desktop\proyecto\programa2\programa.c" Line 447(17,18): Out of ROM, A segment or the program is too large MAIN
Seg 01000-017FF, 029D left, need 0773
Seg 01800-01FFF, 0800 left, need 083F
Seg 00000-00003, 0000 left, need 083F
Seg 00004-0003B, 0000 left, need 083F
Seg 0003C-007FF, 0056 left, need 083F
Seg 00800-00FFF, 036A left, need 083F
Seg 01000-017FF, 029D left, need 083F
Muchas gracias de nuevo """"
Obtenido de http://www.todopic.com.ar/foros/index.php?topic=29725.0
Este error y parecidos es achacado a la falta de memoria en el pic. No más lejos aunque el error es parecido.
Lo que indica es un desbordamiento de la Pila.
El microcontrolador no puede saltar tantas veces dentro de una función. Si seguimos el programa vemos que saltamos de una función a otra y de esta a otra más hasta conseguir el desbordamiento.
Una sencilla prueba es localizar la llamada a la subrutina que te da el error y eliminarla. Ahora mete trozos de programa y te lo acepta perfectamente. Si cambias la llamada por otra (da igual la que metas ) el programa hace lo mismo y te da el error. Suele ocurrir más a menudo cuando trabajas con interrupciones. Al trabajar en ensamblador y querer llamar la función de uno y otro lado, generas saltos de un banco a otro para poder llegar. El compilador hace esto mismo.
Otra prueba es hacer otra función igual (pero con distinto nombre,eh!!) y colocarla junto a la función que nos falla. Ya no da el error.
La siguiente función o subrutina da el error al llamar a atcomand() (la que está lejos). Se soluciona colocando otra cerca: atcomand_(). En esta ocasión es una tontería pero en otras si hace falta.
//______________________________________________________________
void EnviarSms(int o ){
busL=1;
atcomand_(); // ACTIVANDO ESTA FUNCIONA NO DA EL ERROR
// atcomand(); // LA FUNCION ES LA MISMA, LO QUE CAMBIA ES LA UBICACIÓN
printf("MGS=\"+346" );
switch (o) {
case 0x01:
eprom=0xB8;
break;
case 0x02:
eprom=0xC0;
break;
case 0x03:
eprom=0xC8;
break;
case 0x04:
eprom=0xD0;
break;
case 0x05:
eprom=0xD8;
break;
case 0x06:
eprom=0xE0;
break;
case 0x07:
eprom=0xE8;
break;
case 0x08:
eprom=0xF0;
break;
}
for (i=0;i<=7;i++){
printf("%C",read_EEPROM(eprom + i));
}
printf("%C",'\"');
printf("%C",'\r');
}
//___________________________________________________________-
void atcomand_(){ // ESTO SOLUCIONA EL PROBLEMA
printf("AT+C");
}
//_____________________________________________________________
Esto es usado en el programa, como veremos después, para el envío se sms a números de teléfono que tenemos guardados en la EEprom del PIC.
Mejor solución:
Usando la directiva #inline.
Si colocamos esta directiva en la declaración de funciones se soluciona el problema ya que el compilador realiza una copia del código en cualquier parte donde se llame al procedimiento. Esto es útil para ahorrar espacio en la pila (stack) y aumentar la velocidad.
//______________________________________________________________
declaración de funciones
...
void enter();
#inline //COLOCANDO LA DIRECTIVA SE SOLUCIONA EL PROBLEMA
void atcomand();
...
//______________________________________________________________
Una sencilla prueba es localizar la llamada a la subrutina que te da el error y eliminarla. Ahora mete trozos de programa y te lo acepta perfectamente. Si cambias la llamada por otra (da igual la que metas ) el programa hace lo mismo y te da el error. Suele ocurrir más a menudo cuando trabajas con interrupciones. Al trabajar en ensamblador y querer llamar la función de uno y otro lado, generas saltos de un banco a otro para poder llegar. El compilador hace esto mismo.
Otra prueba es hacer otra función igual (pero con distinto nombre,eh!!) y colocarla junto a la función que nos falla. Ya no da el error.
La siguiente función o subrutina da el error al llamar a atcomand() (la que está lejos). Se soluciona colocando otra cerca: atcomand_(). En esta ocasión es una tontería pero en otras si hace falta.
//______________________________________________________________
void EnviarSms(int o ){
busL=1;
atcomand_(); // ACTIVANDO ESTA FUNCIONA NO DA EL ERROR
// atcomand(); // LA FUNCION ES LA MISMA, LO QUE CAMBIA ES LA UBICACIÓN
printf("MGS=\"+346" );
switch (o) {
case 0x01:
eprom=0xB8;
break;
case 0x02:
eprom=0xC0;
break;
case 0x03:
eprom=0xC8;
break;
case 0x04:
eprom=0xD0;
break;
case 0x05:
eprom=0xD8;
break;
case 0x06:
eprom=0xE0;
break;
case 0x07:
eprom=0xE8;
break;
case 0x08:
eprom=0xF0;
break;
}
for (i=0;i<=7;i++){
printf("%C",read_EEPROM(eprom + i));
}
printf("%C",'\"');
printf("%C",'\r');
}
//___________________________________________________________-
void atcomand_(){ // ESTO SOLUCIONA EL PROBLEMA
printf("AT+C");
}
//_____________________________________________________________
Esto es usado en el programa, como veremos después, para el envío se sms a números de teléfono que tenemos guardados en la EEprom del PIC.
Mejor solución:
Usando la directiva #inline.
Si colocamos esta directiva en la declaración de funciones se soluciona el problema ya que el compilador realiza una copia del código en cualquier parte donde se llame al procedimiento. Esto es útil para ahorrar espacio en la pila (stack) y aumentar la velocidad.
//______________________________________________________________
declaración de funciones
...
void enter();
#inline //COLOCANDO LA DIRECTIVA SE SOLUCIONA EL PROBLEMA
void atcomand();
...
//______________________________________________________________
Como siempre: No es tan difícil como parece.
No hay comentarios:
Publicar un comentario