|
|
View previous topic :: View next topic |
Author |
Message |
mmc01
Joined: 16 Jun 2010 Posts: 31
|
Error Out Of ROM when I use many printf. |
Posted: Sun Aug 04, 2013 2:08 am |
|
|
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
|
|
Posted: Sun Aug 04, 2013 5:17 am |
|
|
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
|
|
Posted: Sun Aug 04, 2013 1:28 pm |
|
|
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
|
|
Posted: Sun Aug 04, 2013 8:15 pm |
|
|
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
|
|
Posted: Sun Aug 04, 2013 8:42 pm |
|
|
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
|
|
Posted: Sun Aug 04, 2013 9:10 pm |
|
|
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
|
|
Posted: Sun Aug 04, 2013 9:14 pm |
|
|
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
|
|
Posted: Mon Aug 05, 2013 9:30 am |
|
|
Thank you very much. |
|
|
|
|
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
|