MikroC y sus problemas con la RAM PIC 16FXXX

Hola a todos! Bueno les comento, mi primer experiencia con microcontroladores la tuve con el famoso at89s52 , programando en el KEIL en C. Pese a las pocas librerias a disposicion a su escaso hard por ser un micro viejo y mas que nada porque ya casi no se consiguen empece a migrar a PIC. Como todos, arrranque por la serie 16F que es la mas basica. Soy estudiante de ing.electronica y ya curse materias de programacion por lo cual tengo un manejo medio-alto del C. Comparando compiladores, me tope con la decicion de elegir uno. Eleji el MikroC for PIC, por su interface amigable, por sus librerias, por la informacion que encontre (en un primer instante) por su standar ascii y porque si quiero migrar a otro micro, las instrucciones son casi y practicamente las mismas. Lcd_Out es la misma, pongas el micro que pongas un mero ejemplo. Llendo al grano, me tope con que para las familias 16F este querido compilador no direcciona la memoria RAM del micro cuando quiere acceder a los bancos 3 y 4 por lo cual me veo limitado a la mitad de la memoria que el micro me da. Estoy laburando con un 16F88 (ya que tiene puerto ADC). El proyecto que estoy realizando requiere de pantalla lcd y una interfas grafica masomenos agradable y el problema radica en que los lcd_out usan mucha memoria.

Leyendo y leyendo me tope con que debo direcionar manualmente los bancos de memoria con el bit IRP del registro STATUS pero en ningun lado encontre como realizar esto! hasta en la ayuda de mikro C dice que se debe direccionar manualmente la memoria pero no dice como y lo mas comico es que dice que si al programador se le complica puede migrar a 18F y problema solucionado. Que facil no? Pues no, mi proyecto tiene que salir con este micro por su suficiente capacidad y precio. Que me dicen? Alguien tiene idea?

Saludos y gracias a todos.
 
Para direccionar entre bancos de RAM se usan, como bien leíste, los bits RP0, RP1 e IRP. RP0 y RP1 juntos sirven para direccionar un banco a la vez:

RP1:RP0=00-->banco 0
RP1:RP0=01-->banco 1
RP1:RP0=10-->banco 2
RP1:RP0=11-->banco 3

IRP es sólo para manejar el direccionamiento indirecto usando los registros FSR e INDF.

IRP=0 manejas direccionamiento indirecto en los bancos 0 y 1
IRP=1 manejas direccionamiento indirecto en los bancos 2 y 3

Estos bits suelen manejarse con comandos de bit, no se bien como se hace esto en alto nivel :oops:

Espero al menos haberme explicado de como se hace el cambio en bancos de RAM

Saludos
 
No sé si esto sirva pero fue obtenido directamente de mikroElektronika: Microcontrolador PIC16F887
Código:
[COLOR=Green]/* Al entrar o al salir de la instrucción en ensamblador del programa, el compilador
no va a guardar los datos en el banco de la RAM actualmente activo. Esto significa
que en esta sección de programa la selección de banco depende de los registros SFR
utilizados. Al volver a la sección de programa escrito en C, los bits de control
RP0 y RP1 deben devolver el estado que tenían antes de la ejecución del código en
lenguaje ensamblador. En este ejemplo, el problema se soluciona al utilizar la
variable auxiliar saveBank que guarda el estado de estos dos bits*/

saveBank = STATUS & 0b01100000; // Guardar el estado de los bits RP0 y RP1
                      // (bits 5 y 6 del registro STATUS)
asm {                 // Inicio de la secuencia en ensamblador
...
...                   // Código ensamblador
...
}                     // Final de la secuencia en ensamblador
STATUS &= 0b10011111; // Bits RP0 y RP1 devuelven su estado original
STATUS |= saveBank;
...
...[/COLOR]
No utilizo ese compilador por tantos problemas que tiene y lo complejo que tiene al hacer algo sencillo.
Tampoco he visto este asunto más que en ensamblador, por lo general los compiladores de alto nivel hacen el cambio de bancos automáticamente.
 
Gracias por sus respuestas!!! No eh tenido otros problemas para programar en este compilador salvo este, es la verdad un bache importante que no puedas usar toda la ram en los 16F. En el caso del ultimo codigo, creo que se aplica solo cuando se introduce un conjunto de insutrucciones en assembler. A mi el programa me tira el error de IRP bit debe ser direccionado manualmente... y me marca la variable mas larga y unica de mi programa un char txt [7] si mal no recuerdo. La idea es que esa variable la guarde en el banco 2 y 3 segun le corresponda, pero no lo entender como hacerlo en C
 
Hola.
Revisa en Ram Saver

Indica la modificación que debes hacer al usar LCD_Out. No lo he probado pero hay buenos comentarios.

Código:
//============= START RAM SAVER ===========================================
const char txt1[] = "GLE Solar Engery";
const char txt2[] = "Thermal Controller";
const char txt3[] = "Analog T0: ";

char msg[17]; //declare array set 16 bytes of RAM aside for copying into

// copy const to ram string
char * CopyConst2Ram(char * dest, const char * src){
  char * d ;
  d = dest;
  for(;*dest++ = *src++;)
    ;
  return d;
}

//================ END RAM SAVER ==========================================

Sobre el compilador, funciona bien para trabajos cortos, también hay cierta incompatibilidad entre librerias, no recuerdo cuales pero al mezclar algunas me han dado dolores de cabeza ... al final cambie a otro compialdor para también trabajos más serios... opinión.

Saludos.
 
Claro eso sirve para ahorar ram en variables que toman un solo valor osea constantes. Pero la que utilice yo es una variable propiamente dicha, cambia su valor dentro del programa.

De acuerdo al compilador, he leido cientos de opiniones, y la verdad que es un boca river, hay muchos que prefieren el mikro C, otros el CCS...cada cual tiene sus motivos que son totalmente validos. Por ahora salvo este problema de la ram que es solucionable, el problema es que no se como pero el manual te lo dice, si direccionas a esos bancos podes usar la ram tranquilamente. El problema es como! No tuve otros problemas con este compilador. Mi programa esta ocupando ROM 83% y RAM 49% y como esta es totalmente funcional, por el momento funcionando en proteus. Pero si tuviera la chance de usar toda la ram podria incluir mas textos en pantalla como estos:

lcd_out(1,1,"Hola mundo");

Eso es lo que ocupa memoria a morir. Pero cuando supero el 50% me dice que hay que direccionar los bancos y me señala el unico string que tengo, que es variable , porque en el muestro la "Humedad" que lee un SHT21 en flotante, por ende cambia constantemente y no puedo hacer el truco de ahorro de ram.
 
hola adri_ariel_05, es cierto que en mikroC no puedes usar toda la ram para mostrar mensajes (lcd_out()).
si solo quieres cambiar los bancos es facil (status.b5=x, status.b6=x), pero no me parese una buena opción ya que al compilar no se tiene certeza de donde están las variables por lo cual abría que revisar las estadísticas que trae mikroC y ver ahí en que banco esta tu vector y esperar que hayas elegido el banco correcto.

si tienes mensajes como "Humedad=x.xx%" o "voltaje="....esas son constantes exceptuando por x.xx que es variable, para este caso sera mejor que los que son constantes se guarden en la "rom" y solo la variable en la ram. Ahora ¿Como hacer para que la o las variables esten situadas en una dirección especifica de la memoria ram? Simple, bastara con usar la directiva absolute.
 
Bueno, buscando y buscando... ni en el foro de Mikroe han resuelto dicho detalle... hasta donde vi...

Agregando a lo que dijo Saint_ puedes intentar usar tus varibles en los bancos 2, 3 y dejar al compilador a que use libremente el 1 y 2... puede ser...

También optimizar un poco el programa, digo... variable flotante solo usa 4 bytes, hacer cálculos con flotante consume buen trozo de memoria en un PIC de 8 bits... hay trucos para trabajar solo con enteros, por decir 3.35 equivale a 335 (entero)... puede convenir y solo poner el punto donde corresponda...
 
Y como seria entonces la secuencia de programacion para ustedes?

status.b5=1 (bancos 2 y 3=
declaracion de variable
status.b5=0

asi?

De acuerdo a lo que comentaban sobre el flotante, el mismo sale de una formula que da el datasheet del sht21, si o si entrega en float, abria que ver como reformularla para que entre un entero y luego se coloca la coma donde corresponde. En mi caso la variable es float y por ejemplo el texto "Humedad:" esta directamente en el lcd_out(1,1,"Humedad:"), no hay manera de zafar y eso creo que no hay forma de direccionarlo. La verdad es una linda macana. Porque uno puede optimizar seguro...pero nunca se va a poder aprobechar toda la ram del micro.
 
adri_ariel_05, estas equivocado, si se puede aprovechar toda la ram pero utilizando el poderoso asm, o un muy buen manejo del compilador que se utiliza. Por otro lado con la información que publicas solo podemos dar sugerencias de manera general y lo que necesitas es algo mas especifico y por eso es que no se encuentra la solución al problema.
Este es un ejemplo de como se podría solucionar el problema.
Código:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
/*******************************************************************************
variables
*******************************************************************************/
float humedad;
char humedad_txt[15] absolute 0x20;//vector situado en el banko0
/*******************************************************************************
Constantes
*******************************************************************************/
const char texto0[]="Humedad:";
/******************************************************************************/
void mostrar_lcd(char fila,char columna,const char *texto)
{
   char lcd[17];
   char n=0;
   while((lcd[n++]=*texto++)!=0);
   lcd_out(fila,columna,lcd);
}
void main()
{
   Lcd_Init();
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Cmd(_LCD_CURSOR_OFF);
   mostrar_lcd(1,1,texto0);
   while(1)
   {
      humedad=humedad*1.1+1;
      floattostr(humedad,humedad_txt);
      lcd_out(1,9,humedad_txt);
      delay_ms(500);
   }
}
Aunque seria mejor que subas el código que tienes hecho para ver como solucionar el problema.
 
No creo poderte ayudar en MikroC, puesto que yo manejo ensamblador (y estoy pensando en migrarme a otro compilador, de un nivel mas alto que MPLab, no sin antes dominar bien ensamblador), pero, en ensamblador el direccionamiento indirecto se hace mas o menos asi:
Código:
;---------------------------------------------------------------------------------
;*IRP ES EL BIT, DEL REGISTRO STATUS, QUE PERMITE EL DIRECCIONAMIENTO A LOS BANCOS
;	0 = BANCO 0 Y 1
;	1 = BANCO 2 Y 3

;*FSR ES EL REGISTRO EN EL QUE SE ESCRIBE/LEE LA DIRECCIÓN DE LA RAM 
;EN LA QUE SE VA A ESCRIBIR/LEER

;*INDF ES EL NOMBRE DEL REGISTRO DONDE SE ESCRIBE/LEE LA INFORMACION
;---------------------------------------------------------------------------------

	BCF		STATUS,IRP		;DIRECCIONAMIENTO A BANCOS 0 Y 1
	MOVLW	D'160'			;DIRECCION RAM EN LA QUE ESCRIBIRAS
	MOVWF	FSR	
;---------------------------------------------------------------------------------
;AQUI ESTOY ACCESADNDO A LA DIRECCION A0h (160), QUE SE ENCUENTRA EN EL BANCO 1
;DEL PIC 16F877A (LO TOMO COMO EJEMPLO)										
							
;TEN POR ENTENDIDO QUE PUEDES MANEJAR RAM DESDE LA DIRECCION '0'
;HASTA LA DIRECCION '255'(DE 2 BANCOS), PERO ENTRE ELLAS ESTAN ALGUNOS REGISTROS
;DE USO PROPIO DEL PIC, ASI QUE TENDRIAS QUE REVIZAR EN EL DATASHEET
;CUALES SON LAS DIRECCIONES UTILES O DE PROPOSITO GENERAL.

;SI CAMBIAS EL ESTADO DEL BIT IRP DEL REGISTRO STATUS, LA DIRECCION
;QUE CARGUES NO SERA LA MISMA, EJEMPLO:
;	BCF		STATUS,IRP		;BANCO 0 Y 1
;	MOVLW	D'255'
;	MOVWF	FSR				;PONE EL PUNTERO EN LA DIRECCION FFh DEL PIC (255)
;	MOVLW	D'50'
;	MOVWF	INDF			;SE CARGA, EN LA DIRECCION FFh, EL VALOR D'50'
;	BSF		STATUS,IRP		;BANCOS 2 Y 3, EL PUNTERO EN DIRECCION 1FFh DEL PIC (511)
;	MOVWF	INDF			;SE CARGA, EN LA DIRECCION 1FFh, EL VALOR D'50'

;DE ESTA MANERA, PUEDES PASAR DE UNA DIRECCION A OTRA (255 A 511) CON TAN SOLO
;CAMBIAR EL BIT IRP DEL REGISTRO STATUS.
;---------------------------------------------------------------------------------
			
BORRA_DATO_RAM
	CLRF	INDF			;LIMPIA EL REGISTRO DONDE ESTA EL PUNTERO
	MOVF	FSR,W			;LEE LA ULTIMA DIRECCION QUE SE LIMPIO
	SUBLW	D'254'			;SE DETERMINA SI LLEGO A LA DIRECCION 255
	BTFSC	STATUS,C		;SI NO SE LIMPIO LA ULTIMA DIRECCION DEL BANCO
	GOTO	INCREMENTA_FSR	;SE VA A INCREMENTAR EL REGISTRO FSR
	GOTO	OTRO_PROCESO	;SI YA TERMINO, SE VA A OTRO PROCESO
INCREMENTA_FSR
	INCF	FSR,1			;INCREMENTA EL PUNTERO
	GOTO	BORRA_DATO_RAM	;Y VA DE NUEVO A BORRAR UN DATO EN LA RAM
			
;---------------------------------------------------------------------------------	
;ESTE PROGRAMA ES SOLO UN CICLO QUE BORRA TODOS LOS DATOS QUE TENGA LA RAM 
;DESDE LA DIRECCION 160 HASTA LA 255, CLARO ESTA DEL BANCO 1 DEL PIC16F877A
;---------------------------------------------------------------------------------


Espero te sirva de algo este ejemplo.
 
Muchachos, no pude solucionar el tema, pero pude esquivarlo, encontre el algoritmo que guarda strings en rom , totalmente funcional en la libreria del LCD, por ende guarde todos los mensajes de pantalla en rom y libere la ram. A mi me sirvio porque tenia bastante rom disponible. Me termino quedando en ram un 30% usado y 91% usado de rom y ya el programa esta casi en su etapa final. Al menos en proteus funciona correctamente y estoy a la espera de los componentes para probar en la realidad.

Les cuento de que se trata. En la empresa donde trabajo, Kohinoor (si, secarropas, poderoso el chiquitin) donde tambien se fabrican heladeras, tenemos un laboratorio de ensayos, en el cual me encuentro yo y un compañero mas. Para poder cumplir con las normas que exige el Inti, las heladeras deben ser sometidas a varios tipos de ensayo para poder especificar el tipo de letra energetica al cual corresponde y que sus cualidades termodinamicas cumplan correctamente. Para estos ensayos se meten las heladeras en unas camaras, las cuales estan acondicionadas a una temperatura especificada desde un control. El problema es que los equipos de aire acondicionado tienden a secar el ambiente sacando la humedad del rango que exige la norma, debe estar entre 45% y 75%. Por ende, como soy la unica persona con conocimiento electronico en toda la parte tecnica de la empresa (si, ni yo puedo creer que esto sea asi) los demas son todos ing. mecanicos. (yo tecnico, por ahora :p) me pidieron si podia desarrollar un humificador para dichas camaras.

Antes que nada necesitaba medir la humedad, por eso tome el pic16F88 , me arme la libreria para manejar el sensor de humedad y temperatura SHT21 y luego empece a armar el programa final. Me tope con el problema de la ram y ahi realice la consulta.

Cuando supero el 50% el compilador tira ese error y lo asocia a solo las cadenas de caracteres usadas. Char nombre []. Entonces mi pregunta era, como direccionar dichas cadenas a los bancos 2 y 3. Realmente prove de todas las formas posibles y no hubo caso.
 
Hola.
Una cosa... la ROM al ser memoria volatil nunca se carga con nada hasta encender el PIC... luego de encender, el PIC lo carga con datos, datos que solo hay en la ROM que en tu caso son strings... y básicamente hay string por duplicado.

Sinceramente no se me ocurrio eso hasta ahora... es mejor indicar al compilador que use los datos directos de ROM.

Por cierto como has declarado tus strings....

char texto0[]="Humedad:"; // El compilador lo considera como variable y copia lo que ya existe en RAM, si hay más cadenas, esto ocupa mucha memoria en RAM.

const char texto0[]="Humedad:"; // El compilador lo considera como constante, lo usa directo de la ROM... y tratarlo como mencionó Saint_ anteriormente... se puede mejorar si el compilador lo permite.

Me parece que eso era el detalle, ahún así solo especulo ya que nunca vimos tu código jeje.

Saludos.
 
Utilice una funcion que encontre en el foro de mikro C , si mal no recuerdo era esta, en el trabajo tengo el programa completo

char* codetxt_to_ramtxt(const char* ctxt){
static char txt[20];
char i;
for(i =0; txt = ctxt; i++);
return txt;
}

lcd_out(1,1,codetxt_to_ramtxt("Hola mundo")); y problem resuelto. Al menos en proteus anda!
 
Última edición:
Buen día, estoy realizando una programación con el mikroc, y es sobre el proyecto de clase de controlar un variador de velocidad, estoy apenas en la sesión de prueba y ya tuve el primer problema, resulta que al definir como un vector las salidas binarias del puerto D me marca que hay un error y es que no tiene suficiente memoria ram, ¿existe alguna forma de liberar la memoria ram para yo poder realizar esta programación? les adjunto el código que he hecho para este trabajo.

Código:
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

int porcentaje;
char txt1[]="Valor de salida ";
char txt2[]="en porcentaje: \\porcentaje";
char i;

unsigned short int codificador[256]={
0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,
0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0,
0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd0,
0xcf,0xce,0xcd,0xcc,0xcb,0xca,0xc9,0xc8,0xc7,0xc6,0xc5,0xc4,0xc3,0xc2,0xc1,0xc0,
0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0,
0xaf,0xae,0xad,0xac,0xab,0xaa,0xa9,0xa8,0xa7,0xa6,0xa5,0xa4,0xa3,0xa2,0xa1,0xa0,
0x9f,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90,
0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80,
0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
0x6f,0x6e,0x6d,0x6c,0x6b,0x6a,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60,
0x5f,0x5e,0x5d,0x5c,0x5b,0x5a,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,
0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,
0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,
0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,
0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,
0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};

signed short int verificador;
void main() {
ANSEL  = 0;
  ANSELH = 0;
  C1ON_bit = 0;
  C2ON_bit = 0;

  Lcd_Init();

  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

PORTC.F0=1;
TRISD=0;
PORTD=255;
delay_ms(200);
for(;;)
{
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,1,txt1);
  Lcd_Out(2,1,txt2);
  PORTD=codificador[verificador];
  delay_ms(500);
  if (portc.f0==1)
  {
    verificador++;
    if (verificador=255) (verificador=0);
    porcentaje=(verificador*100)/255;
  }
  else
  {
    verificador--;
    if (verificador=0) (verificador=255);
    porcentaje=(verificador*100)/255;
  }
}
}
...
 
Hola, el 16f887 tiene 368 byte de ram, es posible que te de error porque estas reservando
256 byte en esta variable "unsigned short int codificador[256]", la opciones serian poner una memoria externa o ver dentro de la memoria de programa.
No se si el microc te permite esta ultima opcion.
 
Utiliza la memoria de programa, si es que el arreglo es fijo, y tuliza un puntero para pedir cada los valores.

Código:
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

int porcentaje;
char txt1[]="Valor de salida ";
char txt2[]="en porcentaje: \\porcentaje";
char i;

const unsigned short int codificador[256]={
0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,
0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0,
0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd0,
0xcf,0xce,0xcd,0xcc,0xcb,0xca,0xc9,0xc8,0xc7,0xc6,0xc5,0xc4,0xc3,0xc2,0xc1,0xc0,
0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0,
0xaf,0xae,0xad,0xac,0xab,0xaa,0xa9,0xa8,0xa7,0xa6,0xa5,0xa4,0xa3,0xa2,0xa1,0xa0,
0x9f,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90,
0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80,
0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
0x6f,0x6e,0x6d,0x6c,0x6b,0x6a,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60,
0x5f,0x5e,0x5d,0x5c,0x5b,0x5a,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,
0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,
0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,
0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,
0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,
0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};

signed short int verificador;

unsigned int* ptr;

void main() {
ANSEL  = 0;
  ANSELH = 0;
  C1ON_bit = 0;
  C2ON_bit = 0;

  Lcd_Init();

  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

PORTC.F0=1;
TRISD=0;
PORTD=255;
delay_ms(200);

ptr=decodificador;
for(;;)
{
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,1,txt1);
  Lcd_Out(2,1,txt2);
  PORTD=(*ptr);
  delay_ms(500);
  if (portc.f0==1)
  {
    ptr++;
    if (ptr=255) (ptr=0);
    porcentaje=(ptr*100)/255;
  }
  else
  {
    ptr--;
    if (ptr=0) (ptr=255);
    porcentaje=(ptr*100)/255;
  }
}
}
 
Muchísimas gracias por responder, la solución que hasta el momento ha funcionado en parte es la de george.manson.69, pero ahora tengo un ligero problema con la visualización en el lcd, ¿cómo le hago para que muestre una variable en pantalla?
 
Claro eso sirve para ahorar ram en variables que toman un solo valor osea constantes. Pero la que utilice yo es una variable propiamente dicha, cambia su valor dentro del programa.

De acuerdo al compilador, he leido cientos de opiniones, y la verdad que es un boca river, hay muchos que prefieren el mikro C, otros el CCS...cada cual tiene sus motivos que son totalmente validos. Por ahora salvo este problema de la ram que es solucionable, el problema es que no se como pero el manual te lo dice, si direccionas a esos bancos podes usar la ram tranquilamente. El problema es como! No tuve otros problemas con este compilador. Mi programa esta ocupando ROM 83% y RAM 49% y como esta es totalmente funcional, por el momento funcionando en proteus. Pero si tuviera la chance de usar toda la ram podria incluir mas textos en pantalla como estos:

lcd_out(1,1,"Hola mundo");

Eso es lo que ocupa memoria a morir. Pero cuando supero el 50% me dice que hay que direccionar los bancos y me señala el unico string que tengo, que es variable , porque en el muestro la "Humedad" que lee un SHT21 en flotante, por ende cambia constantemente y no puedo hacer el truco de ahorro de ram.


Este hilo es viejo, pero eventualmente a alguien le puede servir. A veces ocurre que se requiere destinar muchos recursos para mensajes de display LCD, y si se tiene suficiente Eeprom disponible se puede utilizar sin problemas para alojar alli los mensajes y recuperarlos al momento de tener que enviar el mensaje al LCD. Esto resuelve holgadamente el problema de bancos y es muy sencillo de implementar.
He usado este procedimiento en dispositivos que llevan años funcionando, solo he cuidado de alojar en Eeprom los mensajes menos recurrentes (o de menor uso, como se quiera decir) para no tener una lectura excesiva que pueda afectar la vida útil de la memoria Eeprom. Saludos.
 
Atrás
Arriba