Bueno Gente, ahora si toy un poco ahogado. Estuve leyendo de como sobre hacer más espacio en ROM como por ejemplo:
http://www.ccsinfo.com/forum/viewtopic.php?t=34265&start=7 que dice partir las funciones, pero no creo poder hacerlo
http://www.ccsinfo.com/forum/viewtopic.php?t=25150 que habla sobre algunos temas como #separate que no lo pude hacer andar
En fin creo que ahora necesito la ayuda de expertos
. Porque no sé como solucionar esto. Les pongo mi código.
#include "D:\Electrónica\Proyectos\Proyecto Medicion de Nivel H2O\ControlDeNivel-Maestro.h" ---> que contiene
-------------------------------------------------------------------------------------------
#include <16F876A.h>
#device adc=8
//#device PASS_STRINGS=IN_RAM
#FUSES NOWDT //Watch Dog Timer
#FUSES XT //Crystal Osc
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
---------------------------------------------------------------------------------------------
#include <flex_lcd.c> //libreria manejo lcd 8bits
#include <ds1302.c>
#case
// Conexiones: B0 -> ------
// B1 -> SCLK DS1302
// B2 -> RST DS1302
// B3 -> I/O DS1302
// B4 -> D4 LCD
// B5 -> D5 LCD
// B6 -> D6 LCD
// B7 -> D7 LCD
// A0 -> LM35 Sensor de Temperatura Externa
// A1 -> E LCD
// A2 -> RS LCD
// A3 -> BOMBA
// A4 -> OZONO
// A5 -> BUZZER
// C0 -> Botón ENTER
// C1 -> Botón ARRIBA
// C2 -> Botón ABAJO
// C3 -> Botón ESCAPE
// C4 -> LED Verde Bomba encendida
// C5 -> LED Amarillo Turbiedad Alta
// C6 -> RX
// C7 -> TX
///VARIABLES GLOBALES
long delay_txt = 400, anti_reb = 300; //delay en ms para textos en pantalla
//char volver;
char flag_clk = 0, ajuste_clk = 2;
char day,mth,year,dow,hour,min,sec;
char temp_H2O, temp_Interna, temp_Ambiente;
char Vmenu_AB = 0;
char Vmenu_A_A1_A2 = 1;
char Vmenu_A_A1_abc = 2;
char Vmenu_A_A1_c = 3;
char Vmenu_A_A2_abcd = 4;
char Vmenu_A_A2_b = 5;
char Vmenu_A_A2_c = 6;
char Vmenu_A_A2_d = 7;
char Vmenu_B_B1_B2_B3_B4_B5 = 8;
char Vmenu_B4_ab = 9;
char Vmenu_B5_ab = 10;
const char menu_AB[2][13] = {" Menu Ppal."," Ajustes"};
const char menu_A_A1_A2[2][10] = {" Control"," Datos"};
const char menu_A_A1_abc[3][13] = {" Manual"," Mecanico"," Automatico"};
const char menu_A_A1_c[2][14] = {" Normal"," Inteligente"};
const char menu_A_A2_abcd[4][16] = {" Turbiedad"," Temperatura"," Consumo"," Nivel de Agua"};
const char menu_A_A2_b[3][11] = {" Cisterna"," Tanque", " Ambiente"};
const char menu_A_A2_c[3][10] = {" 3 Meses"," Mensual", " Semanal"};
const char menu_A_A2_d[2][13] = {" Porcentaje"," Litros"};
const char menu_B_B1_B2_B3_B4_B5[5][16] = {" Fecha y Hora"," Lim Turbiedad"," Limites Carga"," Volum. Tanque"," Control Ozono"};
const char menu_B4_ab[2][11] = {" Cisterna"," Tanque"};
const char menu_B5_ab[2][13] = {" Activacion"," Tiempos"};
///DEFINICION DE FUNCIONES
void menu_principal (void); //muestra el menu principal
void menu_ajustes (void); //muestra el menu de ajustes
char elije_menu (int);
void modo_control (char); //seleccioa el tipo de control y guarda en EEPROM
void accion_control (void); //actua en cada interrupción de TMR0 de acuerdo al modo de control
void muestra_turbiedad (void);
void muestra_temp (int);
void muestra_consumo (void);
void muestra_nivel_de_agua (void);
void ajuste_limite_turbiedad (void);
void ajuste_fecha_y_hora (int);
void ajuste_nivel_de_carga (void);
void ajuste_control_ozono (void);
char menu_si_no(void);
#int_RDA
void RDA_isr(void)
{
}
#int_TIMER0
void interrupcion()
{
if(flag_clk > ajuste_clk) //¿ya es 130ms aprox?
{
ajuste_clk--; //SI -> decremento ajuste_clk...
if(ajuste_clk == 0)
ajuste_clk = 2; //...ajuste fino de 130ms aprox
flag_clk = 0; //reset flag_clk para contar 130ms aprox
rtc_get_date(day,mth,year,dow); //recibe dia,mes,año
rtc_get_time(hour,min,sec ); //recibe hora,minuto,segundo
day=get_bcd(day);
mth=get_bcd(mth);
hour=get_bcd(hour);
min=get_bcd(min);
sec=get_bcd(sec);
printf(lcd_putc,"\f%2X/%2X %2X:%2X:%2X",day,mth,hour,min,sec);
delay_ms(delay_txt);
}
set_timer0(0); //reset TMR0
flag_clk++; //incremento variable flag
}
void main()
{
char c=0;
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);//;setup_wdt(WDT_2304MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_adc_ports(RA0_ANALOG); //Sensor de temperatura
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
output_low(PIN_A3); //Desactivo el BACKLIGHT
lcd_init(); //inicializa lcd
rtc_init();
rtc_set_datetime(31, 3, 2008, 1, 23, 59);
//enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
//enable_interrupts(INT_RDA);
//enable_interrupts(GLOBAL);
disable_interrupts(GLOBAL);
for(;
{
muestra_temp(3);
c=input (PIN_C0);// + input (PIN_C1) + input (PIN_C2);
if (c != 1)
{
output_high(PIN_A3); //Activo el BACKLIGHT
lcd_putc("\f---Bienvenido---");
delay_ms(delay_txt);
disable_interrupts(INT_TIMER0); //interrupcion TIMER0 desactivada
menu_principal();
modo_control(3);
}
enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
//accion_control();
//mostrar_fecha y hora (implementado con otro chip)
}
}
void menu_principal (void)
{
char Enter1, Escape1;
char eleccion;
const char A=1, B=2, A1=1, A2=2, B1=1, B2=2, B3=3, B4=4, B5=5;
const char a=1, b=2, c=3, d=4;
Escape1 = input (PIN_C3);
Enter1 = input (PIN_C0);
do
{
eleccion = elije_menu(Vmenu_AB);
if (eleccion == A) //Menu Principal
{
eleccion = elije_menu(Vmenu_A_A1_A2);
if (eleccion == A1) //Control
{
eleccion = elije_menu(Vmenu_A_A1_abc);
switch (eleccion)
{
case a: modo_control (a); //lcd_putc("\fAct Ctrl. Manual");//activar control manual
break;
case b: modo_control (b); //lcd_putc("\fAct Ctrl. Mecan");//activar control mecánico
break;
case c: modo_control (c); //lcd_putc("\fAct Ctrl. Autom");//activar control automático
break;
}
}
if (eleccion == A2) //Datos
{
eleccion = elije_menu(Vmenu_A_A2_abcd);
switch (eleccion)
{
case a: lcd_putc("\fMostrar Turb.");//mostrar Turbiedad
break;
case b: lcd_putc("\fMostrar Temp.");//mostrar Temperaturas
break;
case c: lcd_putc("\fMostrar Consum.");//mostrar Consumos
break;
case d: lcd_putc("\fMostrar Niv. Tq.");//mostrar Niveles de Tanque
break;
}
}
}
if (eleccion == B) //Menu Ajustes
{
eleccion = elije_menu(Vmenu_B_B1_B2_B3_B4_B5);
switch (eleccion)
{
case B1: lcd_putc("\fAjust Fecha");//Ajustar Fecha y Hora
break;
case B2: lcd_putc("\fAjust Lim Turb");//Ajustar Límite de turbiedad máximo
break;
case B3: lcd_putc("\fAjust Lim Carg");//Ajustar Límites de carga de tanque
break;
case B4: //Cilindico o Rectangular
eleccion = elije_menu(Vmenu_B4_ab);
if (eleccion == a) lcd_putc("\fCalc Vol Cil");//Calcular volumen de tanque cilíndrico
if (eleccion == b) lcd_putc("\fCalc Vol Rect");//Calcular volumen de tanque rectangular
break;
case B5: //Control Ozono
eleccion = elije_menu(Vmenu_B5_ab);
if (eleccion == a) lcd_putc("\fAct Ozono");//Activar o desactivar Ozonizador
if (eleccion == b) lcd_putc("\fAjust Tiempos");//Ajustar Tiempos de Ozonizado
break;
}
}
}while (!Escape1);
delay_ms(500);
} //// -------------------------- fin de la funcion menu_principal() -------------------------- \\\\*/
void menu_ajustes(void)
{
lcd_putc("\fMenu Ajustes");
delay_ms(800);
//lcd_putc("\f");
//volver = atras;
break;
} //// --------------------------- fin de la funcion menu_ajustes() --------------------------- \\\\
char elije_menu (int menu)
{
char opc, i, sumar, num_pal, pulsa;
char Arriba, Abajo, Enter, Escape;
const char LCD_lines = 2;
if (menu == Vmenu_AB || menu == Vmenu_A_A1_A2 || menu == Vmenu_A_A1_c ||
menu == Vmenu_A_A2_d || menu == Vmenu_B4_ab || menu == Vmenu_B5_ab)
num_pal = 2;
if (menu == Vmenu_A_A1_abc || menu == Vmenu_A_A2_b || menu == Vmenu_A_A2_c )
num_pal = 3;
if (menu == Vmenu_A_A2_abcd )
num_pal = 4;
if (menu == Vmenu_B_B1_B2_B3_B4_B5 )
num_pal = 5;
pulsa = 0;
for (;
{
Arriba = input (PIN_C1);
Abajo = input (PIN_C2);
Escape = input (PIN_C3);
Enter = input (PIN_C0);
if (!Arriba || !Abajo || pulsa == 0)
{
if (pulsa == 0) pulsa = 1; //solo para entrar la primera vez
if (!Arriba)
pulsa --;
if (!Abajo)
pulsa ++;
if (pulsa > num_pal)
pulsa = num_pal;
if (pulsa < 1)
pulsa = 1;
lcd_putc("\f");
sumar = 0;
for (i = 0; i < LCD_lines; i++)
{
if (!Abajo && pulsa > 2 || !Arriba && pulsa == 2) //si se va a escribir fuera del LCD
sumar = 1;
if (!Abajo && pulsa > 3 || !Arriba && pulsa == 3) //si se va a escribir fuera del LCD
sumar = 2;
if (!Abajo && pulsa > 4 || !Arriba && pulsa == 4)
sumar = 3;
switch (menu)
{
case 0:
printf (lcd_putc, "%s",menu_AB[i + sumar]);
break;
case 1:
printf (lcd_putc, "%s",menu_A_A1_A2[i + sumar]);
break;
case 2:
printf (lcd_putc, "%s",menu_A_A1_abc[i + sumar]);
break;
case 3:
printf (lcd_putc, "%s",menu_A_A1_c[i + sumar]);
break;
case 4:
printf (lcd_putc, "%s",menu_A_A2_abcd[i + sumar]);
break;
case 5:
printf (lcd_putc, "%s",menu_A_A2_b[i + sumar]);
break;
case 6:
printf (lcd_putc, "%s",menu_A_A2_c[i + sumar]);
break;
case 7:
printf (lcd_putc, "%s",menu_A_A2_d[i + sumar]);
break;
case 8:
printf (lcd_putc, "%s",menu_B_B1_B2_B3_B4_B5[i + sumar]);
break;
case 9:
printf (lcd_putc, "%s",menu_B4_ab [i + sumar]);
break;
case 10:
printf (lcd_putc, "%s",menu_B5_ab[i + sumar]);
break;
}
opc = pulsa;
if (i == 0)
lcd_putc("\n");
}
//Pos de flecha con pulsa bajando 2:2(A >B), 3:2(B >C), 4:2(C >D), 5:2(D >E)
//Pos de flecha con pulsa subiendo 1:1(>A B), 2:1(>B C), 3:1(>C D), 4:1(>D E)
lcd_gotoxy(1,1);
if (!Abajo)
lcd_gotoxy(1,2);
if (!Arriba)
lcd_gotoxy(1,1);
lcd_putc(">");
delay_ms(delay_txt);
//volver = off;
}
if (!Enter)
{
Enter = input (PIN_C0);
//while (!Enter)
delay_ms(anti_reb);
return opc;
break;
}
if (!Escape)
break;
}
} //// ---------------------------- fin de la funcion elije_menu() ---------------------------- \\\\*/
void modo_control(char tipo)
{
char manual = 1, mecanico = 2, automatico = 3, si_no;
char dir_tipo_control = 0; //Direccion en EEPROM para el tipo de control
if (tipo == manual)
{
lcd_putc("\fCtrl Manual?");
si_no = menu_si_no();
if(si_no)
write_eeprom(dir_tipo_control,manual);
}
if (tipo == mecanico)
{
lcd_putc("\fCtrl Mecánico?");
si_no = menu_si_no();
if(si_no)
write_eeprom(dir_tipo_control,mecanico);
}
if (tipo == automatico)
{
lcd_putc("\fCtrl Automático?");
si_no = menu_si_no();
if(si_no)
write_eeprom(dir_tipo_control,automatico);
}
} //// --------------------------- fin de la funcion modo_control() --------------------------- \\\\
void accion_control(void)
{
disable_interrupts(INT_TIMER0); //interrupcion TIMER0 desactivada
lcd_putc("\fHacer algo");
delay_ms(delay_txt);
enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
} //// -------------------------- fin de la funcion accion_control() -------------------------- \\\\
void muestra_temp (int ubicacion)
{
char cisterna = 1, tanque = 2, ambiente = 3;
//leer via RS232 el dispositivo del tanque solicitando temp. externa y de tanque
if (ubicacion == cisterna)
{
temp_H2O = read_adc();
printf(lcd_putc,"\fTemp. Cisterna:");
printf(lcd_putc,"\nH2O:%d%cC Int:%d%cC",temp_H2O,0xdf,temp_H2O+2,0xdf);
delay_ms(delay_txt);
}
if (ubicacion == tanque)
{
temp_Interna = read_adc();
printf(lcd_putc,"\fTemp. Tanque:");
printf(lcd_putc,"\nH2O:%d%cC Int:%d%cC",temp_Interna,0xdf,temp_Interna+2,0xdf);
delay_ms(delay_txt);
}
if (ubicacion == ambiente)
{
temp_Ambiente = read_adc();
printf(lcd_putc,"\fTemp. Ambiente:");
printf(lcd_putc,"\n %d%cC",temp_Ambiente,0xdf);
delay_ms(delay_txt);
}
}
char menu_si_no(void)
{
char Enter, Escape, Arriba, Abajo;
char opcion = 2;
do
{
Arriba = input (PIN_C1);
Abajo = input (PIN_C2);
Escape = input (PIN_C3);
Enter = input (PIN_C0);
if (!Arriba)
{
lcd_putc("\n > Si No");
opcion = 1;
}
if (!Abajo || opcion == 2)
{
lcd_putc("\n Si > No");
opcion = 0;
}
if (!Escape)
break;
}while (Enter);
return opcion;
}
Luego esta funcion me consume bastante. O sea que los printf son jodidos en el tema ROM, pero como hacer que esto no suceda?
void muestra_temp (int ubicacion)
{
char cisterna = 1, tanque = 2, ambiente = 3;
//leer via RS232 el dispositivo del tanque solicitando temp. externa y de tanque
if (ubicacion == cisterna)
{
temp_H2O = read_adc();
printf(lcd_putc,"\fTemp. Cisterna:");
printf(lcd_putc,"\nH2O:%c%cC Int:%c%cC",temp_H2O,0xdf,temp_H2O+2,0xdf);
delay_ms(delay_txt);
}
if (ubicacion == tanque)
{
temp_Interna = read_adc();
printf(lcd_putc,"\fTemp. Tanque:");
printf(lcd_putc,"\nH2O:%c%cC Int:%c%cC",temp_Interna,0xdf,temp_Interna+2,0xdf);
delay_ms(delay_txt);
}
if (ubicacion == ambiente)
{
temp_Ambiente = read_adc();
printf(lcd_putc,"\fTemp. Ambiente:");
printf(lcd_putc,"\n %c%cC",temp_Ambiente,0xdf);
delay_ms(delay_txt);
}
}
Se me ocurre que con punteros a los arrays que contienen strings como
......
case 0:
printf (lcd_putc, "%s",menu_AB[i + sumar]);
break;
case 1:
printf (lcd_putc, "%s",menu_A_A1_A2[i + sumar]);
break;
........etc
en lugar de menu_AB y menu_A_A1_A2 poder pasarlos a la funcion sin que sean globales, pero juro que traté y no pude.