CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Error Out Of ROM when I use many printf.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mmc01



Joined: 16 Jun 2010
Posts: 31

View user's profile Send private message

Error Out Of ROM when I use many printf.
PostPosted: Sun Aug 04, 2013 2:08 am     Reply with quote

I write code in ccs for alarm food. I just create new function for record and play voice that is Rec_Voice() , Play_Voice(). After I use these function in external interrupt (EXT_ISR) then it show error like this
Quote:
***Error 71 "test.c" Line 695(0,1): Out Of ROM, A segment or the program is too large EXT_ISR
if I don't call Rec_Voice() , Play_Voice() in EXT_ISR it can compile and use ROM only 55%. I can't use printf more than this. It will show error when I use printf. You can see EXT_ISR in the last line of code and function Rec_Voice() , Play_Voice() before EXT_ISR. How to fix my code ?

Code:
#include <16F886.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)

#include "flex_LCD.c"
#use I2C(master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
//#include "input.c"

#define ADDR_DS1307  0xD0 //Address DS1307

int set_hr=24;
int set_min=60;

typedef struct{
   BYTE sec;     // seconds
   BYTE min;     // minute
   BYTE hr;      // hour
   BYTE day;
   BYTE date;
   BYTE month;
   BYTE year;
}DS1307_RTC;

DS1307_RTC RTC;

typedef struct{

   int min;     // minute
   int hr;      // hour
   int sec_delay;
}time_feed;

time_feed t_feed;


void DS1307_Write(unsigned char ctl, unsigned char dat);
BYTE DS1307_Read(unsigned char ctl);
void DS1307_WriteDate(void);
void DS1307_WriteTime(void);

void DS1307_ReadDate(void);
void DS1307_ReadTime(void);
   
   
BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}

// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

   /*******************************************************/
void DS1307_Write(unsigned char ctl, unsigned char dat){
   i2c_start();
   i2c_write(ADDR_DS1307);
   i2c_write(ctl);
   i2c_write(dat);
   i2c_stop();
}

/*******************************************************/
BYTE DS1307_Read(unsigned char ctl){
   
   BYTE dat;
   
   i2c_start();
   i2c_write(ADDR_DS1307);
   i2c_write(ctl);
   
   i2c_start();
   i2c_write(ADDR_DS1307+1);
   dat = i2c_read(0);
   i2c_stop();
   return(dat);
}

/*******************************************************/
void DS1307_WriteDate(void){
   DS1307_Write(0x04,RTC.date);
   DS1307_Write(0x05,RTC.month);
   DS1307_Write(0x06,RTC.year);
}

/*******************************************************/
void DS1307_WriteTime(void){
   DS1307_Write(0x00,RTC.sec);
   DS1307_Write(0x01,RTC.min);
   DS1307_Write(0x02,RTC.hr);
}

/*******************************************************/
void DS1307_ReadDate(void){
   RTC.date = DS1307_Read(0x04);
   RTC.month = DS1307_Read(0x05);
   RTC.year = DS1307_Read(0x06);
}

/*******************************************************/
void DS1307_ReadTime(void){
   RTC.sec = DS1307_Read(0x00);
   RTC.min = DS1307_Read(0x01);
   RTC.hr = DS1307_Read(0x02);
}

void DS1307_SetTime(int hr, int min){

   RTC.hr = bin2bcd(hr);
   RTC.min = bin2bcd(min);
   RTC.sec = 0x00;
}

/************* Delay *************/
void delay(){
int sec_delay;
  for(sec_delay=t_feed.sec_delay;sec_delay>0;sec_delay--){
  lcd_gotoxy(1,2);
  delay_ms(1000);
  printf(lcd_putc,"\r Food = %d sec " sec_delay);
  }

}

/************* time **************/
void time(){

int hr=0;
int min=0;

delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r    -- : --    ");
    delay_ms(50);

while(1){

if(input(PIN_B1)==0){

delay_ms(100);
hr++;

if(hr>=24){hr=0;}

delay_ms(100);
    lcd_gotoxy(1,2);
 
    printf(lcd_putc,"\r    %02d : %02d   ", hr,min);
    delay_ms(50);
   

}else if(input(PIN_B2)==0){

delay_ms(100);
min++;

if(min>=60){min=0;}


delay_ms(100);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r    %02d : %02d   ", hr,min);
    delay_ms(50);
 
}

if(input(PIN_B3)==0){

    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r Time : %02d:%02d ", hr,min);
    delay_ms(500);


DS1307_SetTime(hr,min);
DS1307_WriteTime();

break;
     
}
}  // while hr

}

/************* check same time **************/
int check_time(int hr[], int hr_ck, int min[], int min_ck,int count){
  int x;
  for(x=0;x<count;x++){
 
  if((hr[x]== hr_ck) && (min[x]== min_ck)){
 
    if((hr_ck==24)&& (min_ck==60)){
   
      return 0;
      break;

   }else{
      return 1;
      break;
     
   }
  }
  }
   return 0;
 
}

/************ get now time ***************/
int16 getNow(){

   int16 now_hr,now_min;
   int16 now_all;
   DS1307_ReadTime();


   now_hr = bcd2bin(RTC.hr);
   now_min = bcd2bin(RTC.min);
     
   now_all = (now_hr*60)+now_min;
   
   //printf("\r\n n=%ld",now_all);
   return now_all;
}

/**************************************/
int16 next_time(int16 hr, int16 min, int pos){

int32 minimVal;
int i=0,check;
int16 now_all;
int32 all[5],t;
int16 hrk[5],mnk[5];
int n,j;
   
hrk[pos] = hr;
mnk[pos] = min;
all[pos] =(hrk[pos]*60 + mnk[pos]) ;

//minimVal2 = (hrk[0]*60) + mnk[0];
now_all = getNow();
//printf("\r\n pos=%d, n=%ld, ",pos,all[pos]);

n = sizeof(all)/sizeof(all[0]);

   /* bubble sort */
   for (i = pos; i > 0; i--) {
       for (j = 0; j < i; j++) {   /* move max (in [0] to [i]) to last ([i]) */
           if (all[j] > all[j+1]) {   /* exchange if bigger than next */
               t = all[j];
               all[j] = all[j+1];
               all[j+1] = t; } } }
               
               minimVal= all[0];

   for (i = 0; i < pos+1; i++) {
   //printf("\r\n%ld ", all[i]);
   
  if(all[i]>now_all){
  if(all[i]!=1500){
      minimVal= all[i];
      break;
  }
 }
       
     // printf("\r\n%ld ", all[i]);
       
   }

//printf("\r\n min %ld ", minimVal);

return minimVal;
}

/************* feed time **************/
void feed_time(int count){


int hr[5],min[5];
int16 next;

while(1){

if(input(PIN_B1)==0){

delay_ms(250);
set_hr++;

if(set_hr>24){
   set_hr=0;
   set_min= 0;
}

if(set_hr==24){
set_min=60;
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  -- : -- ",count+1);
    delay_ms(50);
}else{
delay_ms(100);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  %02d : %02d ", count+1, set_hr,set_min);
    delay_ms(50);
}
   
}else if(input(PIN_B2)==0){

delay_ms(250);
set_min++;

if(set_min>=60){
   set_min=0;
   
}
    delay_ms(100);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  %02d : %02d " count+1, set_hr,set_min);
    delay_ms(50);
   
}

if(input(PIN_B3)==0){
hr[count] = set_hr;
min[count] = set_min;

    if(check_time(hr,set_hr,min,set_min,count)){
     
    delay_ms(100);
    lcd_gotoxy(1,1);
    //printf(lcd_putc,"\rn=%d ar= %d,va= %d" ,count, set_hr,set_min);
    printf(lcd_putc,"\r This is same. ");
    delay_ms(500);
   
     
     }

    else{

          next= next_time(hr[count],min[count],count);
          t_feed.hr=next/60;
          t_feed.min=next%60;
         
          /*lcd_gotoxy(1,1);
          printf(lcd_putc,"\r hr =%d , min=%d " ,t_feed.hr,t_feed.min);
          delay_ms(500); */
         
if(set_hr==24){

    delay_ms(50);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r F%d :  -- : -- ",count+1);
    delay_ms(50);
   
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r                  ");
          delay_ms(50);

    if((count+2)!=6){

    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  -- : -- ",count+2);
    delay_ms(50);
    }
}else{

    delay_ms(100);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r F%d :  %02d : %02d " count+1, set_hr,set_min);
    delay_ms(50);
   
    if((count+2)!=6){
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  %02d : %02d ",count+2,set_hr,set_min);
    delay_ms(50);
    }
   
}
         
     break;
   
     }

//break;
     
}
     
}  // while hr

}

/************* Sec Period **************/
void sec_feed(){

//unsigned int sec=10;

while(input(PIN_B3)){

if(input(PIN_B1)==0){
delay_ms(100);
t_feed.sec_delay++;
if(t_feed.sec_delay>=300){t_feed.sec_delay=300;}
delay_ms(100);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay);
    delay_ms(50);
   
}

if(input(PIN_B2)==0){
delay_ms(100);
t_feed.sec_delay--;
if(t_feed.sec_delay<=1){t_feed.sec_delay=1;}
delay_ms(100);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay);
    delay_ms(50);

}
}  // while sec
t_feed.sec_delay = t_feed.sec_delay;
//delay();

}

/************* Set time **************/
void Set_Time(){

delay_ms(50);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r   Set Clock   ");
    delay_ms(50);
   
    lcd_gotoxy(1,2);
    printf(lcd_putc,"[Next]      [OK]");
    delay_ms(50);

while(1){

if(input(PIN_B3)==0){

      delay_ms(500);
     
      time();
     
      break;

}

   if(!input(PIN_B0)){
   
      break;
    }
}
}

/************* Set Feed Time **************/
void Set_Feed_Time(){
    int i;
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r Set Feed Time ");
    delay_ms(50);
   
        lcd_gotoxy(1,2);
    printf(lcd_putc,"[Next]      [OK]");
    delay_ms(50);


while(1){

if(input(PIN_B3)==0){

    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F1 :  -- : -- ");


      delay_ms(500);

     
      for(i=0;i<5;i++){     // count feed time
      feed_time(i);
      delay_ms(500);
      }
     
      if(t_feed.hr!=25){
          delay_ms(50);
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r Next : %02d:%02d  " ,t_feed.hr,t_feed.min);
          delay_ms(500);
      }else{
          delay_ms(50);
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r                  ");
          delay_ms(50);
      }
      break;

}

   if(!input(PIN_B0)){
                 delay_ms(50);
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r                  ");
          delay_ms(50);
      break;
    }
}
}

/***************** Set Period Time *********************/

void Set_Period_Time(){

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\rSet Feed Period");
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"[Next]      [OK]");
    delay_ms(50);
   
while(1){
   
if(input(PIN_B3)==0){
    delay_ms(500);
    sec_feed();
    break;
}

    if(!input(PIN_B0)){
   
      break;
    }
}
   }

/***************** Rec Voice *********************/

void Rec_Voice(){

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r Record Voice");
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"[Next]      [OK]");
    delay_ms(50);
   
while(1){
   
if(input(PIN_B3)==0){
    delay_ms(500);
    //sec_feed();
    break;
}

    if(!input(PIN_B0)){
   
      break;
    }
}
   }

/***************** Play Voice *********************/

void Play_Voice(){

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r Play Voice");
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"[Next]      [OK]");
    delay_ms(50);
   
while(1){
   
if(input(PIN_B3)==0){
    delay_ms(500);
    //sec_feed();
    break;
}

    if(!input(PIN_B0)){
   
      break;
    }
}
   }

#INT_EXT                         
void EXT_ISR(void)               
{
 
    delay_ms(500);
    Set_Time();
    delay_ms(500);
    Set_Period_Time();
    delay_ms(500);
    Set_Feed_Time();
    delay_ms(500);

/*It can compile if I not use this function. */
    Rec_Voice();
    delay_ms(500);
    Play_Voice();
    delay_ms(500);

}


Last edited by mmc01 on Sun Aug 04, 2013 10:04 am; edited 2 times in total
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 5:17 am     Reply with quote

One possible 'cure' is to create a 'display time' function. whenever you need to display the time, call this. Right now you have several 'display time' lines of code, each taking a lot of code space. By having a 'common' function, you'll save space.

If you still run out of space, you'll have to 'split' your program into 'chunks' that fit into the ROM segment spaces. Consult the CCS help files for this or search this forum for a 'how-to-do-it' post.

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 1:28 pm     Reply with quote

Your program doesn't have a main(), so it won't even compile enough
to test your problem. Without a main(), the compiler just says:
Quote:
Error: Expecting function name
mmc01



Joined: 16 Jun 2010
Posts: 31

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 8:15 pm     Reply with quote

PCM programmer wrote:
Your program doesn't have a main(), so it won't even compile enough
to test your problem. Without a main(), the compiler just says:
Quote:
Error: Expecting function name


Sorry my code is long. This is main code it show same error .
***Error 71 "test.c" Line 695(0,1): Out Of ROM, A segment or the program is too large EXT_ISR
Code:

void main(){
t_feed.sec_delay = 10;
int16 next;

lcd_init();

enable_interrupts(GLOBAL);

    enable_interrupts(INT_EXT);  // Set external interrupt                   (4)
    ext_int_edge(H_TO_L);        // External interrupt high to low edge      (5)

while(TRUE){
   //DS1307_ReadDate();
   
   lcd_gotoxy(1,1);
   DS1307_ReadTime();
   
   if((t_feed.hr==bcd2bin(RTC.hr)) && (t_feed.min==bcd2bin(RTC.min))){
      delay();
      next = next_time(24,60,5);
      t_feed.hr=next/60;
      t_feed.min=next%60;
                       
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r Next : %02d:%02d  " ,t_feed.hr,t_feed.min);
          delay_ms(500);
   }
   
   printf(lcd_putc,"\rTime : %2X:%2X:%2X\n", RTC.hr, RTC.min, RTC.sec);
   delay_ms(500);

}
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 8:42 pm     Reply with quote

My advice is to get all that stuff out of the External interrupt isr.
I did that in the changes shown in bold below. Then it compiles easily.
I don't like the way your program has all these huge 500ms delays tacked
in everywhere. I would change that somehow.

The changes in bold shown below consist of moving the isr code into main
and checking a flag to see if an interrupt occurred. Then execute the code.
Quote:

int8 ext_int_flag = FALSE;
#INT_EXT
void EXT_ISR(void)
{
ext_int_flag = TRUE;
}

//========================
void main()
{
int16 next;
t_feed.sec_delay = 10;


lcd_init();

enable_interrupts(GLOBAL);

enable_interrupts(INT_EXT); // Set external interrupt (4)
ext_int_edge(H_TO_L); // External interrupt high to low edge (5)

while(TRUE){


if(ext_int_flag == TRUE)
{
ext_int_flag = FALSE;

delay_ms(500);
Set_Time();
delay_ms(500);
Set_Period_Time();
delay_ms(500);
Set_Feed_Time();
delay_ms(500);

Rec_Voice();
delay_ms(500);
Play_Voice();
delay_ms(500);

}


//DS1307_ReadDate();

lcd_gotoxy(1,1);
DS1307_ReadTime();

if((t_feed.hr==bcd2bin(RTC.hr)) && (t_feed.min==bcd2bin(RTC.min))){
delay();
next = next_time(24,60,5);
t_feed.hr=next/60;
t_feed.min=next%60;

lcd_gotoxy(1,2);
printf(lcd_putc,"\r Next : %02d:%02d " ,t_feed.hr,t_feed.min);
delay_ms(500);
}

printf(lcd_putc,"\rTime : %2X:%2X:%2X\n", RTC.hr, RTC.min, RTC.sec);
delay_ms(500);
}
}
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 9:10 pm     Reply with quote

In addition, according to the stats, Exit_ISR is 40% of all the code by itself...
Another reason to clean it up.

Moving that out of the ISR drops the memory usage to about 37%
_________________
Google and Forum Search are some of your best tools!!!!


Last edited by dyeatman on Sun Aug 04, 2013 9:20 pm; edited 2 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 04, 2013 9:14 pm     Reply with quote

Thank you. I have don't have the Stat file with the command line version.
I was wishing I had it to analyze this problem.
mmc01



Joined: 16 Jun 2010
Posts: 31

View user's profile Send private message

PostPosted: Mon Aug 05, 2013 9:30 am     Reply with quote

Thank you very much. Very Happy Very Happy Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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