|
|
View previous topic :: View next topic |
Author |
Message |
lasal
Joined: 25 Jan 2012 Posts: 13
|
out of rom problem |
Posted: Mon Apr 23, 2012 3:22 am |
|
|
The code:
Code: |
#include <gps_main.h>
//#include <string.h>
#include <input.c>
#include <stdlib.h>
//Real time clock chip definitions
#define RTC_SCLK PIN_A0
#define RTC_IO PIN_A1
#define RTC_RST PIN_A2
#include <DS1302.C>
//user LCD character definitions
#define Satalite_icon 0
#define Hammer_icon 1
//LCD connection definitions
#define LCD_DB4 PIN_C1
#define LCD_DB5 PIN_C2
#define LCD_DB6 PIN_C3
#define LCD_DB7 PIN_D0
#define LCD_RS PIN_A7
#define LCD_RW PIN_A6
#define LCD_E PIN_C0
#include <flex_lcd.c>
//structures
typedef struct _GPRMCInfo
{
char Valid;
float Latitude;
char N_S;
float Longitude;
char E_W;
float Speed;
} GPRMCInfo;
//function decleration
void lcd_load_custom_chars(void);
void sys_menu();
void display_time();
void display_date();
void set_time();
void set_date_year();
void set_date_mth();
void set_date_day();
void set_date_dow();
void gps();
void GPRMC_decode(char *GPRMCStr);
//void clr_line2();
//void clr_line1();
//----------------------------------------------variable decleration------------------------------------------------------
//state controle variables
unsigned int state=0,loop=0,system_state=0,setup=0;
//clock variables
unsigned int hr,min,sec;
volatile unsigned int set_hr,set_min;
unsigned int day,mth,year,dow,hour;
volatile unsigned int set_day,set_mth,set_year,set_dow;
//const int c=0x20;
unsigned int backlit=0;
//gps variables
GPRMCInfo RMCInfo;
char GPSData[80];
unsigned int8 GPSDataPtr=0;
char c;
int8 GPSDataReady = FALSE;
//user LCD charactor data
const int8 lcd_custom_chars[] =
{
// Char Number 0 -- Satalite_icon
0x07,0x15,0x0A,0x07,0x07,0x0A,0x15,0x07
// Char Number 1 -- Signal_level1
0x1C,0x1E,0x05,0x04,0x04,0x04,0x04,0x04
};
//INT0 external interrupt
#int_EXT
void EXT_isr(void)
{
}
//recieve data awailable
#int_RDA
void RDA_isr(void)
{
c = getc();
switch (c)
{
case '$':
GPSDataPtr = 0;
break;
case '\n':
GPSDataReady = TRUE;
break;
}
GPSData[GPSDataPtr++ & 0x7F] = c;
}
#int_TIMER1
void TIMER1_isr(void)
{
if(backlit!=-1)backlit--;
if(backlit==0)output_low(PIN_D1);
}
#int_TIMER2
void TIMER2_isr(void)
{
}
#int_TIMER0
void TIMER0_isr(void)
{
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_bit); //32.7 ms overflow
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //262 ms overflow
setup_timer_2(T2_DIV_BY_16,255,16); //2.0 ms overflow, 32.7 ms interrupt
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
enable_interrupts(INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_8MHZ);
rtc_init();
lcd_init();
delay_ms(500);
while(true){
if(input_state(pin_A3)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(100);
state++;
if(state==2)state=0;
}
if(state==0){
display_time();
display_date();
if(input_state(pin_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(1);
if(input_state(pin_A4)==0){system_state=1;state=3;}
delay_ms(100);
}
}//state 0 options
if(state==1){
gps();
if(input_state(pin_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(1);
if(input_state(pin_A4)==0){system_state=1;state=3;}
delay_ms(100);
}
}
if(system_state==1){
sys_menu();
if(setup<10)if(input_state(pin_A4)==0){backlit=500;output_high(PIN_D1);setup=setup+10;delay_ms(100);}
if(setup<10)if(input_state(pin_A3)==0){backlit=500;output_high(PIN_D1);setup++;if(setup==5)setup=0;}
if(input_state(pin_E1)==0){backlit=500;output_high(PIN_D1);state=0;system_state=0;setup=0;}
}
}//while loop ends
}//main loop ends
//clock_functions-----------------------------------------------------------------
//------------------------------display time--------------------------
void display_time(){
lcd_load_custom_chars();
rtc_get_time(hr,min,sec) ;
lcd_gotoxy(1,1);
lcd_putc(Satalite_icon);
lcd_gotoxy(2,1);
printf(lcd_putc," TIME %02d:%02d:%02d"hr,min,sec);
}
//----------------------------display date------------------------
void display_date(){
rtc_get_date(day,mth,year,dow);
lcd_gotoxy(1,2);
if(dow==1)printf(lcd_putc," %02d-%02d-%02d SUN" day,mth,year);
if(dow==2)printf(lcd_putc," %02d-%02d-%02d MON" day,mth,year);
if(dow==3)printf(lcd_putc," %02d-%02d-%02d TUE" day,mth,year);
if(dow==4)printf(lcd_putc," %02d-%02d-%02d WED" day,mth,year);
if(dow==5)printf(lcd_putc," %02d-%02d-%02d THU" day,mth,year);
if(dow==6)printf(lcd_putc," %02d-%02d-%02d FRI" day,mth,year);
if(dow==7)printf(lcd_putc," %02d-%02d-%02d SAT" day,mth,year);
//delay_ms(200);
}
//------------------------------set time----------------
void set_time(){
delay_ms(1);
rtc_get_time(hr,min,sec);
lcd_gotoxy(1,1);
printf(lcd_putc,"SET TIME %02d:%02d"hr,min);
lcd_gotoxy(1,2);
printf(lcd_putc," %15c" c);
delay_ms(100);
if(input_state(PIN_A3)==0){
backlit=500;
output_high(PIN_D1);
set_hr=hr;
set_hr++;
if(set_hr>23)set_hr=0;
hour=set_hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A4)==0){
backlit=500;
output_high(PIN_D1);
set_min = min;
set_min++;
if(set_min>59)set_min=0;
min=set_min;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A5)==0){
backlit=500;
output_high(PIN_D1);
set_min = 0;
min = set_min;
set_hr = 0;
hour = set_hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
loop++;
if(loop==2000){state=0;system_state=0;setup=0;}
if(input_state(PIN_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(20);
setup=setup-10;
}
}
//------------------------set date year-----------------------
void set_date_year(){
rtc_get_date(day,mth,year,dow);
delay_ms(5);
lcd_gotoxy(1,1);
printf(lcd_putc,"SET YEAR %02d" year);
display_date();
delay_ms(100);
set_year=year;
if(input_state(PIN_A3)==0){
backlit=500;
output_high(PIN_D1);
set_year++;
if(set_year>99)set_year=0;
year=set_year;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A4)==0){
backlit=500;
output_high(PIN_D1);
set_year--;
if(set_year<0)set_year=99;
year=set_year;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A5)==0){
backlit=500;
output_high(PIN_D1);
set_year = 0;
year=set_year;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
loop++;
if(loop==2000){state=0;system_state=0;setup=0;}
if(input_state(PIN_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(20);
setup=setup-10;
}
}
//----------------------------set date month--------------
void set_date_mth(){
rtc_get_date(day,mth,year,dow);
delay_ms(5);
lcd_gotoxy(1,1);
printf(lcd_putc,"SET MONTH %02d" mth);
display_date();
delay_ms(100);
set_mth=mth;
if(input_state(PIN_A3)==0){
backlit=500;
output_high(PIN_D1);
set_mth++;
if(set_mth>12)set_mth=1;
mth=set_mth;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A4)==0){
backlit=500;
output_high(PIN_D1);
set_mth--;
if(set_mth<1)set_mth=12;
mth=set_mth;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A5)==0){
backlit=500;
output_high(PIN_D1);
set_mth = 1;
mth=set_mth;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
loop++;
if(loop==2000){state=0;system_state=0;setup=0;}
if(input_state(PIN_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(20);
setup=setup-10;
}
}
//---------------------set date day------------------
void set_date_day(){
rtc_get_date(day,mth,year,dow);
delay_ms(5);
lcd_gotoxy(1,1);
printf(lcd_putc,"\fSET DAY %02d" day);
display_date();
delay_ms(200);
set_day=day;
if(input_state(PIN_A3)==0){
backlit=500;
output_high(PIN_D1);
set_day++;
if(set_day>31)set_day=1;
day=set_day;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A4)==0){
backlit=500;
output_high(PIN_D1);
set_day--;
if(set_day<1)set_day=31;
day=set_day;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A5)==0){
backlit=500;
output_high(PIN_D1);
set_day = 1;
day=set_day;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
loop++;
if(loop==2000){state=0;system_state=0;setup=0;}
if(input_state(PIN_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(20);
setup=setup-10;
}
}
//---------------------------------set day of week------------
void set_date_dow(){
rtc_get_date(day,mth,year,dow);
delay_ms(5);
lcd_gotoxy(1,1);
printf(lcd_putc,"\fSET DAY OF WK %02d" dow);
display_date();
delay_ms(200);
set_dow=dow;
if(input_state(PIN_A3)==0){
backlit=500;
output_high(PIN_D1);
set_dow++;
if(set_dow>7)set_dow=1;
dow=set_dow;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A4)==0){
backlit=500;
output_high(PIN_D1);
set_dow--;
if(set_dow<1)set_dow=7;
dow=set_dow;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
if(input_state(PIN_A5)==0){
backlit=500;
output_high(PIN_D1);
set_dow = 1;
dow=set_dow;
rtc_get_time(hr,min,sec) ;
hour = hr;
rtc_set_datetime(day,mth,year,dow,hour,min);
backlit =0;
}
loop++;
if(loop==2000){state=0;system_state=0;setup=0;}
if(input_state(PIN_E0)==0){
backlit=500;
output_high(PIN_D1);
delay_ms(20);
setup=setup-10;
}
}
//lcd custom charactor loading-----------------------------------------
void lcd_load_custom_chars(void)
{
int8 i;
// Set address counter pointing to CGRAM address 0.
lcd_send_byte(0, 0x40);
// Load custom lcd character data into CGRAM.
// It can only hold a maximum of 8 custom characters.
for(i = 0; i < sizeof(lcd_custom_chars); i++)
{
lcd_send_byte(1, lcd_custom_chars[i]);
}
// Set address counter pointing back to the DDRAM.
lcd_send_byte(0, 0x80);
}
//GPS functions------------------------------------------------------------
void gps(){
if(GPSDataReady==TRUE){
GPRMC_decode(GPSData);
GPSDataReady=FALSE;
}
if(RMCInfo.Valid=='A'){
printf(LCD_PUTC, "\fLAT %4.2g %c"RMCInfo.Latitude,RMCInfo.N_S);
printf(LCD_PUTC, "\nLON %4.2g %c"RMCInfo.Longitude,RMCInfo.E_W);
}
else{ printf(LCD_PUTC, "\f Satellite ");
printf(LCD_PUTC, "\nConnection Lost!!");
}
delay_ms(100);
}
//System settings functions--------------------------------
void sys_menu(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fSettings" );
lcd_gotoxy(10,1);
lcd_putc(Hammer_icon);
if(setup==0){
lcd_gotoxy(1,2);
printf(lcd_putc,"Set Time" );
}
if(setup==1){
lcd_gotoxy(1,2);
printf(lcd_putc,"Set Year" );
}
if(setup==2){
lcd_gotoxy(1,2);
printf(lcd_putc,"Set Month" );
}
if(setup==3){
lcd_gotoxy(1,2);
printf(lcd_putc,"Set Date" );
}
if(setup==4){
lcd_gotoxy(1,2);
printf(lcd_putc,"Set Day Of Week" );
}
if(setup==10){
set_time();
}
if(setup==11){
set_date_year();
}
if(setup==12){
set_date_mth();
}
if(setup==13){
set_date_day();
}
if(setup==14){
set_date_dow();
}
delay_ms(100);
}
//-------------------gps decode function-------
//copy string (pos n to pos m) from s2 to s1
char* StrnmCpy(char *s1, char *s2, size_t n, size_t m)
{
int8 i;
char *s;
for (s=s1, i=n, s2+=n; i<=m; i++)
*s++ = *s2++;
*s = '\0';
return s1;
}
///////////////////////////////////////////////////////////////////////////////
// find c in s starting from pos st
int8 StrFnd(char *s, char c, size_t st)
{
int8 l;
for (l=st, s+=st ; *s != '\0' ; l++, s++)
if (*s == c)
return l;
return -1;
}
///////////////////////////////////////////////////////////////////////////////
void GPRMC_decode(char *GPRMCStr)
{
int8 p1, p2;
char TempStr[16];
p1 = StrFnd(GPRMCStr, ',', 0); //find first comma
if (p1 == 6)
{
//check for valid packet:
if ( (StrFnd(GPRMCStr, 'A', p1+1) == 18) && (GPRMCStr[0]=='$')) //valid?
{
RMCInfo.Valid = 'A';
//Get time
p1 = StrFnd(GPRMCStr, ',', 0); //find first comma
p2 = StrFnd(GPRMCStr, ',', p1+1); //find next comma
//Get latitude & direction
p1 = StrFnd(GPRMCStr, ',', p2+1); //find next comma
p2 = StrFnd(GPRMCStr, ',', p1+1); //find next comma
RMCInfo.Latitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
RMCInfo.N_S = GPRMCStr[p2+1];
//Get longitude & direction
p1 = StrFnd(GPRMCStr, ',', p2+1); //find next comma
p2 = StrFnd(GPRMCStr, ',', p1+1); //find next comma
RMCInfo.Longitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
RMCInfo.E_W = GPRMCStr[p2+1];
//Get speed
p1 = StrFnd(GPRMCStr, ',', p2+1); //find next comma
p2 = StrFnd(GPRMCStr, ',', p1+1); //find next comma
//RMCInfo.Speed = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1));
//Get date
p1 = StrFnd(GPRMCStr, ',', p2+1); //find next comma
p2 = StrFnd(GPRMCStr, ',', p1+1); //find next comma
}
else //not valid
{
RMCInfo.Valid = 'V';
}
}
}
|
This is my header file:
Code: |
#include <16F887.h>
#device ICD=TRUE
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES DEBUG //Debug mode for use with ICD
#use delay(int=8000000)
#use rs232(baud=4800,errors,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=GPS) |
This is the error I got when compiling:
Code: |
Clean: Deleting intermediary and output files.
Clean: Deleted file "gps_main.ESYM".
Clean Warning: File "D:\GPS\gps_main.o" doesn't exist.
Clean: Deleted file "gps_main.ERR".
Clean: Done.
Executing: "E:\PICC\Ccsc.exe" +FM "gps_main.c" +DF +LN +T +A +M +Z +Y=9 +EA
>>> Warning 205 "gps_main.c" Line 335(1,1): Unsigned variable is never less than zero
>>> Warning 204 "gps_main.c" Line 335(1,1): Condition always FALSE
>>> Warning 202 "D:\GPS\gps_main.h" Line 13(5,8): Variable never used: rs232_errors
*** Error 71 "gps_main.c" Line 759(0,1): Out of ROM, A segment or the program is too large MAIN
Seg 00800-00FFF, 00C4 left, need 00954
Seg 01000-017FF, 0800 left, need 00954
Seg 01800-01EFF, 0700 left, need 00954
Seg 00000-00003, 0000 left, need 00954
Seg 00004-00050, 0000 left, need 00954
Seg 00051-007FF, 0006 left, need 00954
1 Errors, 3 Warnings.
Halting build on first failure as requested.
BUILD FAILED: Mon Apr 23 14:50:10 2012
|
Please can some body help me with this problem |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Apr 23, 2012 4:01 am |
|
|
"Out of rom problem"
Yes, its that simple. Your code is too large to fit in your device. I compiled it for a larger PIC and it needed 9636 bytes of program memory and the 16F887 only has 8192 bytes.
Your code is either too long or too complex, or both. I don't know what takes up most space in your code. Floating point needs a lot of ROM. printf is another heavy ROM user, and printf of floating point values are even worse.
You are not likely to be able to optimise your code to make it fit. You can make this code more efficient but you are most likely wasting your time and therefore money. You need a larger PIC.
RF Developer |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 23, 2012 6:34 pm |
|
|
What's your compiler version ? I got it to compile with vs. 4.130 by
getting rid of the sys_menu() function, and moving all the code for that
function into main(), in place of the function call.
Quote: |
void main()
{
.
.
.
if(system_state==1){
//sys_menu(); // Comment out the function call
// Put below, all the code for the sys_menu() function
lcd_gotoxy(1,1);
printf(lcd_putc,"\fSettings" );
lcd_gotoxy(10,1);
lcd_putc(Hammer_icon);
if(setup==0){
lcd_gotoxy(1,2);
printf(lcd_putc,"Set Time" );
}
.
.
.
// End of "dropped in" code for sys_menu()
if(setup<10)if(input_state(pin_A4)==0){backlit=500;output_high(PIN_D1);setup=setup+10;delay_ms(100);}
if(setup<10)if(input_state(pin_A3)==0){backlit=500;output_high(PIN_D1);setup++;if(setup==5)setup=0;}
if(input_state(pin_E1)==0){backlit=500;output_high(PIN_D1);state=0;system_state=0;setup=0;}
}
}//while loop ends
}//main loop ends
|
The basic problem is that you are using too many stack levels (7 + 1 for
the interrupt). This is reported at the top of the .LST file. Because of
this, the compiler can't call routines that it needs to call. (It has no more
stack levels to do this). So it tries to place them inline, and there's not
enough room in the ROM segment to do this. By moving sys_menu() into
main(), it removes one stack level (it's now 6 in main + 1 for interrupt).
Apparently this is now enough for the compiler to partition the code
successfully.
Quote: |
volatile unsigned int set_year;
if(set_year<0)set_year=99;
|
The code above generates this warning:
Quote: |
>>> Warning 205 "pcm_test.c" Line 402(1,1): Unsigned variable is never less than zero
|
You need to fix the if() statement. Design a different test. Read the warning. |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Tue Apr 24, 2012 6:50 am |
|
|
Why not just use #inline on sys_menu() instead of copying it? Functions are good.
There is a *lot* of duplicated code. For example: Code: | void display_date(){
rtc_get_date(day,mth,year,dow);
lcd_gotoxy(1,2);
if(dow==1)printf(lcd_putc," %02d-%02d-%02d SUN" day,mth,year);
if(dow==2)printf(lcd_putc," %02d-%02d-%02d MON" day,mth,year);
if(dow==3)printf(lcd_putc," %02d-%02d-%02d TUE" day,mth,year);
if(dow==4)printf(lcd_putc," %02d-%02d-%02d WED" day,mth,year);
if(dow==5)printf(lcd_putc," %02d-%02d-%02d THU" day,mth,year);
if(dow==6)printf(lcd_putc," %02d-%02d-%02d FRI" day,mth,year);
if(dow==7)printf(lcd_putc," %02d-%02d-%02d SAT" day,mth,year);
//delay_ms(200);
} | Try: Code: | const char DAYNAMES[7][*]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
void display_date(){
rtc_get_date(day, mth, year, dow);
lcd_gotoxy(1, 2);
printf(lcd_putc, " %02d-%02d-%02d %s", day, mth, year, DAYNAMES[dow-1]);
} | You could also try a similar thing in sys_menu. Put the "Set..." strings into a const array then have some code like: Code: | if (setup < 5) {
lcd_gotoxy(1, 2);
printf(lcd_putc, SET_STRINGS[setup]);
} | Note that for simple strings, CCS will automatically call functions that take a single char in a loop: Code: | lcd_putc(SET_STRINGS[setup]); | No need for a printf at all.
When trying to reduce program size, *always* check the listing file *before* and *after* making a change. Half the time the code size increases! _________________ Andrew |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 24, 2012 11:07 am |
|
|
Quote: |
Why not just use #inline on sys_menu() instead of copying it? Functions are good.
|
I had tried that, and it didn't work. It still gives an Out of ROM error.
I added #inline above the sys_menu() function and the function prototype:
Quote: |
#inline
void sys_menu();
|
Quote: |
#inline
void sys_menu(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fSettings" );
lcd_gotoxy(10,1);
lcd_putc(Hammer_icon);
.
.
.
} |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|