Error in mplab

Thread Starter

kuannygohcheetatt

Joined Oct 31, 2013
61
Rich (BB code):
//bimary 0b110
//hexadecimal 0xA
//dec imal 110

#define XTAL_FREQ 4MHZ

#include <htc.h>
#include <pic.h>
#include "delay.h"
#include <stdio.h>
#include "lcd.h"
#include <math.h>

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & BOREN_OFF & LVP_OFF);

//global variable
unsigned char temperature;

char ADC_VALUE[32];
char helo[32];
char helow[32];
unsigned char temp2 = 0;
unsigned char finalpressure2;
void pic_init();
unsigned int getAdd();

void main(void) {
    unsigned int adcValue;
    unsigned int adcValue2;
    unsigned char base;
    float voltage;
    float altitude;
    float voltage2;
    float pressure;
    float finalpressure;
    pic_init();
    lcd_init();


    DelayMs(10);
    while (1) {

        ADCON0 = 0b00001001;
//        DelayUs(1000);
//        GO_DONE = 1;
//        while (GO_DONE) {
//            continue;
//        }

        adcValue = getAdd();//((ADRESH << 8) | ADRESL);
        voltage = adcValue * 5.0 / 1023;
        voltage = voltage * 100 + 3.0;
        temperature = (unsigned char) voltage;
        temp2 = (voltage - temperature)*10;

        sprintf(ADC_VALUE, "%d.%d deg Celciuselo h", temperature, temp2);
        lcd_clear();
        lcd_goto(1, 1);
        lcd_puts(ADC_VALUE);
        DelayMs(1500);

        ADCON0 = 0b00010001;
//        DelayUs(1000);
//        GO_DONE = 1;
//
//        while (GO_DONE) {
//            continue;
//        }

        adcValue2 = getAdd();//((ADRESH << 8) | ADRESL);
        voltage2 = adcValue2 * 5.0 / 1023;
        pressure = (((voltage2 / 5.0) + 0.095) / 0.009);

        
          altitude = (1-pow((pressure/101.1325),0.190263))*44330.32172;
        
     
        base = (unsigned char) altitude;


        sprintf(ADC_VALUE, "%d ", base);
        lcd_clear();
        lcd_goto(1, 1);
        lcd_puts(ADC_VALUE);
        lcd_goto(2, 1);
        lcd_puts("altitude meter");

        DelayMs(1000);


        sprintf(helow, "%.2f  hpa", pressure * 10-3);
        lcd_clear();
        lcd_goto(1, 1);
        lcd_puts(helow);
        DelayMs(1500);
        if (RB2 == 0) {
            RB1 = 1;
            DelayMs(2000);
            RB1 = 0;
            TMR0 = 0;
            lcd_clear();
            lcd_goto(1, 1);
            lcd_puts("pulse counting");
            lcd_goto(2, 1);
            lcd_puts("pls wait for 20 second");

            DelayMs(23000);
            
            RB1 = 1;

            sprintf(helo, "your pulse is %d ", TMR0 * 3);
            lcd_clear();
            lcd_goto(1, 1);
            lcd_puts(helo);
            DelayMs(1000);
        }
        RB1 = 0;

    }
}

void pic_init() {
    TRISC = 0xff;
    TRISB = 0b00000101;
    TRISD = 0x00;
    PORTB = 0x00;
    PORTD = 0x00;
    TRISA = 0xff;

    //let portA analogue converted to analogue enable

    ADCON1 = 0b11000000;
    OPTION_REG = 0b00101000;


}

unsigned int getAdd(){
    DelayUs(1000);
        GO_DONE = 1;

        while (GO_DONE) {
            continue;
        }

        return((ADRESH << 8) | ADRESL);
}


This is my code, everytime when i compile it will have error, i found out that this line

altitude = (1-pow((pressure/101.1325),0.190263))*44330.32172;
is causing the problem but i duno how to fix it

the error message is
:0: error: can't find 0x78 words (0x78 withtotal) for psect "text831" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x76 words (0x76 withtotal) for psect "text850" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x6F words (0x6f withtotal) for psect "text842" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x6E words (0x6e withtotal) for psect "text846" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x6C words (0x6c withtotal) for psect "text847" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x66 words (0x66 withtotal) for psect "text845" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x5E words (0x5e withtotal) for psect "text849" in class "CODE" (largest unused contiguous range 0x49)
:0: error: can't find 0x4E words (0x4e withtotal) for psect "text860"
 

t06afre

Joined May 11, 2009
5,934
You have probably not enough program memory in your chip. You have included some libraries that are well known to eat up program memory. You must rewrite your code or use a PIC with more program memory. You are also using the HI-Tech C compiler. The free version that you probably use. Do not optimize the code generated. If you have some other computer you might try to do a fresh install of the C compiler. That will give you 60 or 30 days of trail period. With full code optimization. That will cut your code size with about 40 to 50 percent.
 

MrChips

Joined Oct 2, 2009
30,824
Agreed.

Floating point library and sprintf functions require a lot of memory space.

You have two options:

1) Roll your own fixed point arithmetic and LCD output,

or

2) Move to a chip with more memory.
 

JohnInTX

Joined Jun 26, 2012
4,787
Look at the .map file (generated by the linker). It will tell you where things are and confirm the space used. Try compiling for a bigger PIC. Sometimes its a bank issue that leaves usable memory inaccessible. If your problem persists on a bigger chip, that's an indication. You can also look at the map file and C listing file (with the generated assembly code) to see what's using the most space and see if you can simplify the code.

Sometimes with HiTech, breaking a complex statement into intermediate steps helps as it allows the compiler to bite off smaller chunks that fit easier into tight memory. If your PIC has multiple banks of memory but the compiler doesn't seem to be able to fill it, try breaking the .c source into a couple of files and minimize the calls across the files (to lighten up on the bank switching the compiler has to do). This goes for RAM declarations too.

Delays with different times sometimes generate a new routine for each time value (because it has to generate a count loop). See if you can lump all delays into one routine and call repeatedly. It takes less code to have Delay(1000) and Delay(2000) as two invocations than to have

Rich (BB code):
void delay500(){
 Delay(500);
}
and call delay500 twice for 1000 than to have two separate routines. (based on my HiTech 18F version and XC8 for midrange). It might be useful to make it delay250(void) to keep the counter a byte instead of an integer. Then just call away at one instruction per call.

Calls are cheap. Calls with parameters not so much. If you can limit params, even at the expense of multiple calls you can save code.

These and more will jump out at you if you look at the C with assembler listing. Many times equivalent constructs will generate less code.

Depending on the compiler lines like:
Rich (BB code):
voltage = adcValue * 5.0 / 1023;
can be smaller if you do the constant folding yourself i.e. evaluate 5.0/1023 and use it as the constant. Any decent compiler will do this automatically but I don't know about the non-optimizing versions.

As MrChips pointed out, sprintf with floats is just about as big as it gets as far as code generation. Looking at the LCD libraries would be something I would do as well. They likely use their own delays...

As the others have indicated, going to the PRO version increases the compiler optimization by a lot. I'm not sure about your HiTech version but XC8 PRO can cut the code size by half depending on the chip etc.

uCHIP will upgrade HiTech now to XC8 for free. If you had PRO, you get PRO in XC8. XC8 ports can sometimes be problematic but its really aggressive in optimization in the PRO mode.

What PIC is it for?

Good luck.

Sorry for the rambling.. thinking out loud..
 
Last edited:

MrChips

Joined Oct 2, 2009
30,824
A lot of people take the easy route and use sprintf and floats. But you pay the price as you are now finding out.

I have done dewpoint determination and display to two decimal places in both °C and °F with 2k code space without ever having to touch a float.
 

JohnInTX

Joined Jun 26, 2012
4,787
A lot of people take the easy route and use sprintf and floats. But you pay the price as you are now finding out.

I have done dewpoint determination and display to two decimal places in both °C and °F with 2k code space without ever having to touch a float.
Agreed. I got curious so I was playing with XC8 on a PIC17C87 (enhanced midrange) and read the manual (iRTFM!) about how printf was optimized only to load the formatters that were actually specified in all the format strings. Here are some actual numbers:

Base code with no printf: 433 flash ROM words. Not bad for the FREE mode with a full duplex, interrupt-driven buffered UART, a timer/IRQ driven system TIK and the requisite blinking LED as Task0.

Add (only one at a time):
printf("K") takes it to 467 used. No numbers, just print strings.
printf("K%u,k) 726 used, unsigned int with default formatting
printf("K%d",k) 743 used, signed int with default formatting
printf("K%f",f) 4147 used! The price of convenience. A second exact invocation of printf("K%f",f) took it to 4157 so the call overhead is not too bad if you can afford 4K of program space to get started.

These numbers would likely be better if
1) I could get XC8 into the PRO mode but it won't - new, improved license management that isn't working -and-
2) it were an 18F or better. It makes pretty good code even in FREE mode but still a lot of banking in this PIC family.

For MrChips:
printf("K%d.%02d",k/100,k%100); clocks in at 1143, a significant improvement over floats if you can use it.

Have fun!

EDIT: I also reconfirmed what I said above about delays. I tried a few and saw that each one with a different time made its own code. Subsequent uses of the same delay resulted in a call to that code. 2, 3 and 4 calls to delay(50) would be way better than delay(50), delay(100), delay(200) etc.
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
...
Depending on the compiler lines like:
Rich (BB code):
voltage = adcValue * 5.0 / 1023;
can be smaller if you do the constant folding yourself i.e. evaluate 5.0/1023 and use it as the constant.
...
Minor nitpick, the correct math to scale a 10bit ADC is;
voltage = adcValue * 5.0 / 1024;

I covered that in detail in this thread, but for some reason it was not stickied;
http://forum.allaboutcircuits.com/showthread.php?t=80018
 

JohnInTX

Joined Jun 26, 2012
4,787
Minor nitpick, the correct math to scale a 10bit ADC is;
voltage = adcValue * 5.0 / 1024;
I know. Just copied/pasted from the original thread. Lots of programmers make that mistake, though, so its good to point it out. I guess if we wanted to pick even further it would be adcValue*(Vref+ - Vref-)/1024
 

JohnInTX

Joined Jun 26, 2012
4,787
@RB That's OK..
Me too.
At least we can keep each other entertained!

BTW, it was your post about using the PWM for a sine wave and efforts to minimize harmonic distortion that prompted me to try the 1787 w/DAC in the first place so thanks for that... I think.

These numbers would likely be better if
1) I could get XC8 into the PRO mode but it won't - new, improved license management that isn't working
FWIW, after ver 1.12 the annual HPA kicks in meaning that if you want to upgrade after a year, it co$ts to stay in the PRO mode... surprise. At least you can keep multiple versions of the compiler installed so stay PRO for current projects and only upgrading if necessary for new chips, bug fixes etc.
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
Ouch! Yearly leasing of a small C compiler? It's bad enough for most people that they have to pay once for it.

Yearly leasing was previously the domain of really big expensive software like CAD programs etc. :(
 

JohnInTX

Joined Jun 26, 2012
4,787
Ouch! Yearly leasing of a small C compiler? It's bad enough for most people that they have to pay once for it.
Yearly leasing was previously the domain of really big expensive software like CAD programs etc. :(
Surprised me as well. I guess I can see the rationale i.e. to keep improving it, add devices and keep the FREE mode free.

But to clarify, once you have a specific compiler in the PRO mode, it stays there. You only have to pay up if you upgrade to use newer chips and want to continue to use PRO mode. That said, the bug-list fixes in each version would warrant (in my view) a free upgrade or two. And, to uCHIP's credit, they maintain a list of earlier versions which re-install with the old license back in the PRO mode, which I did.

Like @RB, I remember the days when you bought a compiler (Archimedes, 2500AD, Aztec etc.) once and it did (and still does) work for the one specific target. But, those guys are all out of business so maybe selling it once is not such a workable plan.

All that said, I'd pay real $$$ if XC8 would compile Salvo.
 

adam555

Joined Aug 17, 2013
858
Just came across this issue.

I have no problems running my small program -with the math library-, but as soon as I add the "pow()" function I get all these errors:

Code:
:0: error: (1347) can't find 0x68 words (0x68 withtotal) for psect "text23" in class "CODE" (largest unused contiguous range 0x63)
:0: error: (1347) can't find 0x4C words (0x4c withtotal) for psect "text12" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x40 words (0x40 withtotal) for psect "text8" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x3F words (0x3f withtotal) for psect "strings" in class "STRING" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x3E words (0x3e withtotal) for psect "text11" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x29 words (0x29 withtotal) for psect "text19" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x21 words (0x21 withtotal) for psect "text20" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x20 words (0x20 withtotal) for psect "maintext" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x1F words (0x1f withtotal) for psect "text18" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x19 words (0x19 withtotal) for psect "text22" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x18 words (0x18 withtotal) for psect "text15" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x12 words (0x12 withtotal) for psect "text21" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x11 words (0x11 withtotal) for psect "text14" in class "CODE" (largest unused contiguous range 0x6)
:0: error: (1347) can't find 0x9 words (0x9 withtotal) for psect "text6" in class "CODE" (largest unused contiguous range 0x6)
On top it took me hours of debugging to finally found out they changed the old C power operand (^) for the "pow()" function; which doesn't even work. Wonder why they had to mess with it; it was perfect as it was.

Anyway, is there any other way to make this calculation without using "pow()"?

Thanks
 
Top