Author Topic: C: can't find words  (Read 5027 times)

0 Members and 2 Guests are viewing this topic.

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 550
  • Country: gb
C: can't find words
« on: May 06, 2020, 04:10:47 pm »
Honestly, I've tried everything! I'm doing an exercise from my "PIC C" book to display a value with one dec pl. The book says to isolate the tenths digit, round it and display (using a PIC16F1827):

       #include <xc.h>
       #include "C:\ExPICCX8\LCD.C"       
       #include "stdio.h"

       void main(void)                     // start of programme 
       {
         float cap = 0.1;
         float res = 2489;
         float pi = 3.14159;
         float freq;
         float temp;
         unsigned int units;
         unsigned int tenths;
         unsigned char outstring[20];

         ANSELB = 0;
         TRISB = 0;                         // set all PORTB bits as outputs 

         delayinit( 4 );                    // initialise delay for 4Mhz osc 
         lcdinit();                         // must be after delayinit() 

         freq = 1 / ( 15.3906 * cap / 1000000 * res );
         units = freq;                          // Converts ?float? to ?int? 
         temp =  10 * (freq - units) + 0.5;     // rounded tenths
         tenths = temp;
         
         lcdtop( 0 );                      // cursor to top line 1st char 
         lcdputs( "Phase shift Osc" );
         lcdbot( 0 );
         sprintf( outstring, "Freq = %d.%d Hz", units, tenths );
         lcdputs( outstring );

         while(1==1);                // stop loop 
       }

This always has the compile (XC8 v2.10) error:

:0:: error: (1347) can't find 0x10 words (0x10 withtotal) for psect "stringtext2" in class "STRCODE" (largest unused contiguous range 0xD)

Non line specific message::: advisory: (1493) updated 32-bit floating-point routines might trigger "can't find space" messages appearing after updating to this release; consider using the smaller 24-bit floating-point types

:0:: error: (1347) can't find 0xD words (0xd withtotal) for psect "text16" in class "CODE" (largest unused contiguous range 0x8)

However, if I change:
temp =  10 * (freq - units) + 0.5;     // rounded tenths
to:
temp =  1;     // rounded tenths

everything goes fine and it displays 261.1 as expected.

I've tried everything I can think of and I just don't get it. It (the version that compiles) only uses 80% of the programme memory and 49% of data memory.

Any suggestions would be most gratefully received?
You can release yourself but the only way to go is down!
RJD
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15439
  • Country: fr
Re: C: can't find words
« Reply #1 on: May 06, 2020, 04:41:21 pm »
Haven't used XC8 in ages, but just take a look at the error message.
It suggests using 32-bit floats (the default when using the 'float' type) may trigger this kind of message. I suspect 32-bit FP routines may take too much code size in some cases.
This part has a very small program memory size (7 KB!)

They suggest using 24-bit floats instead. Whether they are acceptable in your application in terms of precision is yours to figure out.
To enable 24-bit floats, I guess you need to enable the right compiler option. Look that up in XC8 docs.

As a general rule, using floating point on very small targets that do not embed any FPU is not always a great idea. Soft-FP takes significant code size, and is slow.
In your case, you can probably rewrite you calculations so they are using integers only.
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: C: can't find words
« Reply #2 on: May 06, 2020, 05:45:25 pm »
Give this https://microchipdeveloper.com/faq:45 a good slow read. Then generate your map file and see where blocks (psects) are coming up short. Try breaking a function up into two smaller ones. Try using the bank qualifier on variables.

Then get a larger pic  :)
- Invest in science - it pays big dividends. -
 

Offline PlainName

  • Super Contributor
  • ***
  • Posts: 7314
  • Country: va
Re: C: can't find words
« Reply #3 on: May 06, 2020, 07:56:45 pm »
Shouldn't that 0.5 be '0.5f'? I think XC8 treats n.m as double and n.mf as float. Given all the conversions in that line it might have its knickers in a twist. I'd split the line up into separate statements for each operation and see which one is prompting the issue.
 
 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1944
  • Country: us
Re: C: can't find words
« Reply #4 on: May 06, 2020, 10:54:10 pm »
It suggests using 32-bit floats (the default when using the 'float' type) may trigger this kind of message. I suspect 32-bit FP routines may take too much code size in some cases.
Caveat... A few years ago I tested all the various floating point widths from Microchip and the 32 bit libraries were substantially faster than their 24 bit versions, regardless of optimization setting. I can't remember all the details now but at the time I remember being delighted that I was getting increased precision for fewer CPU cycles. I did not evaluate for code space consumption, so for the OP's situation my results may not be directly applicable. Nevertheless, the moral of the story still holds: Sometimes the results aren't as obvious as you'd think. Real life testing is well worth the one-time investment.
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 550
  • Country: gb
Re: C: can't find words
« Reply #5 on: May 07, 2020, 05:42:43 pm »
Thank you very much all, will try those ideas.

BTW when you include a file with #include does the compiler include all the functions in that file or just the ones that are called?
You can release yourself but the only way to go is down!
RJD
 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1944
  • Country: us
Re: C: can't find words
« Reply #6 on: May 07, 2020, 05:51:02 pm »
BTW when you include a file with #include does the compiler include all the functions in that file or just the ones that are called?
The linker should only pull in the ones that are referenced, but oftentimes multiple functions are grouped together and when you invoke one you bring in the others even if they're not explicitly referenced. Floating point libraries are often like this. Some environments give you finer control over this behavior, you just have to do some research on the tools you're using.
 

Offline NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 2507
  • Country: gb
Re: C: can't find words
« Reply #7 on: May 07, 2020, 05:59:11 pm »
Taking out all the LCD stuff (because I don't have it) and commenting out delayinit because I don't have that either....

Code: [Select]
#include <xc.h>
//#include "C:\ExPICCX8\LCD.C"       
#include "stdio.h"

       void main(void)                     // start of programme
       {
         float cap = 0.1;
         float res = 2489;
         float pi = 3.14159;
         float freq;
         float temp;
         unsigned int units;
         unsigned int tenths;
         unsigned char outstring[20];

         ANSELB = 0;
         TRISB = 0;                         // set all PORTB bits as outputs

         //delayinit( 4 );                    // initialise delay for 4Mhz osc
         //lcdinit();                         // must be after delayinit()

         freq = 1 / ( 15.3906 * cap / 1000000 * res );
         units = freq;                          // Converts ?float? to ?int?
         temp =  10 * (freq - units) + 0.5;     // rounded tenths
         tenths = temp;
         
         //lcdtop( 0 );                      // cursor to top line 1st char
         //lcdputs( "Phase shift Osc" );
         //lcdbot( 0 );
         sprintf( outstring, "Freq = %d.%d Hz", units, tenths );
         //lcdputs( outstring );

         while(1==1);                // stop loop
       }

Compiles to....

Code: [Select]
Memory Summary:
    Program space        used   EB4h (  3764) of  1000h words   ( 91.9%)
    Data space           used    C5h (   197) of   180h bytes   ( 51.3%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    Configuration bits   used     0h (     0) of     2h words   (  0.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)
  Not much headroom!

If you also comment out the sprintf then you get down to...

Memory Summary:
    Program space        used   8DFh (  2271) of  1000h words   ( 55.4%)
    Data space           used    80h (   128) of   180h bytes   ( 33.3%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    Configuration bits   used     0h (     0) of     2h words   (  0.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)

So maybe re-write/hand-craft the conversion to the display and it will then fit?
« Last Edit: May 07, 2020, 06:14:37 pm by NivagSwerdna »
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: C: can't find words
« Reply #8 on: May 07, 2020, 06:46:08 pm »
Thank you very much all, will try those ideas.

BTW when you include a file with #include does the compiler include all the functions in that file or just the ones that are called?

Can you attach "C:\ExPICCX8\LCD.C"  to your post?
- Invest in science - it pays big dividends. -
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5410
  • Country: gb
Re: C: can't find words
« Reply #9 on: May 07, 2020, 07:42:40 pm »
You're out of program flash space.

I don't have your LCD libraries, but even with all the LCD references commented out, 3764 of 4096 words are used without optimisations. With -Os on with the Pro XC8, it's 2698 words, but I don't recommend using -Os when you're learning, it makes debugging in particular stepping code hard.

Code: [Select]
Memory Summary:
    Program space        used   EB4h (  3764) of  1000h words   ( 91.9%)
    Data space           used    C5h (   197) of   180h bytes   ( 51.3%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    Data stack space     used     0h (     0) of    B0h bytes   (  0.0%)
    Configuration bits   used     0h (     0) of     2h words   (  0.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)

There are two program memory hogs here. Firstly, the use of floating point. Secondly the use of sprintf.

On such a space constrained device, I'd strongly recommend against the use of both floating point and XXXprintf, and scale your data using various int types as a fixed point implementation.

Or just throw a bigger processor at it (e.g., PIC16F1847 appears to be pin and peripheral compatible, but more flash and RAM), and accept about 3k+ words of overhead.

(edit: sorry, I wrote this many hours ago and only just sent it).
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 550
  • Country: gb
Re: C: can't find words
« Reply #10 on: May 08, 2020, 02:34:34 pm »
You guys are great, thank you very much!

IDEngineer, I just wondered wether the compiler included everything because it reports the functions that I didn't call in LCD.c

That memory usage, NivagSwerdna, how did you get that? Also, thank you for doing all that. I guess space is my problem.

DrG, "C:\ExPICCX8\LCD.C" as requested:

       void delay100u( unsigned int k);       // delay in units of 100 uS 
       void delayinit( unsigned char freq );  // initialise delay routine 
       void lcdputch( unsigned char c );      // write one character to LCD 
       void lcdputs(const char *s);           // write string to LCD 
       void lcdwrite( unsigned char c );      // write one byte to LCD 
       void lcdtop( unsigned char offset );   // set LCD to top line 
       void lcdbot( unsigned char offset );   // set LCD to bottom line 
       void lcdclear( void );                 // clear LCD and home cursor 
       void lcdinit( void );                  // initialise LCD 

                                       // declare global variables 
       static unsigned char cycles;
                                       // define macros 
       #define STROBE PORTBbits.RB5=1,PORTBbits.RB5=0;
       #define RS PORTBbits.RB4


       void delay100u( unsigned int k )     
       {
         while(k > 0)
         {
           PR2 = cycles;                         // Move end count into PR2
           TMR2IF = 0;                           // Clear Timer2 interrupt flag
           T2CON = 0b00010100;                   // 1:1 clock, 1:3 postscaler
           while(TMR2IF == 0);                   // Wait for TMR2IF to set
           T2CON = 0;                            // Turn off Timer2
           k--;
         }
       }

       void delayinit( unsigned char freq)  // initialise delay routine 
       {
         cycles=30*freq/4;                         // 4Mhz=30, 8=60, 20=150   
       }

       void lcdputch( unsigned char c )         // write one char to the LCD 
       {
         RS = 1;                                       // LCD to write chars 
         PORTB = (PORTB & 0xF0) | (c >> 4);            // send top 4 bits 
         STROBE
         delay100u(1);
         PORTB = (PORTB & 0xF0) | (c & 0x0F);          // send bottom 4 bits 
         STROBE
         delay100u(1);
       }


       void lcdputs(const char *s)              // write a string to the LCD 
       {
         RS = 1;
         while( *s )
           lcdwrite( *s++ );
       }


       void lcdwrite( unsigned char c )         // write one byte to LCD 
       {
         PORTB = (PORTB & 0xF0) | (c >> 4);
         STROBE
         delay100u( 1 );
         PORTB = (PORTB & 0xF0) | (c & 0x0F);
         STROBE
         delay100u( 1 );
       }

       void lcdtop( unsigned char offset )      // set LCD to top line 
       {
         unsigned char data;                        // define local variable 
         data = 0x80 + offset;
         RS = 0;                                    // set LCD to COM mode 
         lcdwrite( data );
       }


       void lcdbot( unsigned char offset )      // set LCD to bottom line 
       {
         unsigned char data;                        // define local variable 
         data = 0xC0 + offset;
         RS = 0;                                    // set LCD to COM mode 
         lcdwrite( data );
       }


       void lcdclear( void )                    // clear LCD and home cursor 
       {
         RS = 0;                                    // set LCD to COM mode 
         lcdwrite( 0x01 );                          // write 01 to LCD 
         delay100u( 160 );                          // wait for LCD to clear 
       }

       void lcdinit( void )                     // initialise the LCD 
       {
         RS = 0;                                    // set LCD to COM mode 
         delay100u( 150 );                          // 15mS delay 
         PORTB = 0x03;
         STROBE
         delay100u( 50 );                           // 5mS delay 
         STROBE
         delay100u( 50 );
         lcdwrite( 0x32 );                          // set to 4 bit mode 
         lcdwrite( 0x2C );                          // set for 2 lines 
         lcdwrite( 0x08 );                          // display off 
         lcdwrite( 0x06 );                          // set increment cursor 
         lcdwrite( 0x0C );                          // display on, cur off 
         lcdwrite( 0x01 );                          // clear display 
         delay100u( 16 );                           // 1.6mS delay 
         lcdwrite( 0x02 );                          // home cur, clear RAM 
         delay100u( 16 );                           // 1.6mS delay 
       }


Cheers Howardlong, willco. This is all part of a teaching project so I, sort of, have no choice about PIC or floating point, etc. However, I do want to get to the botom of this problem as a learning opportunity in itself.
You can release yourself but the only way to go is down!
RJD
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: C: can't find words
« Reply #11 on: May 08, 2020, 03:18:47 pm »

/--/
DrG, "C:\ExPICCX8\LCD.C" as requested:

/--/


I stuck the included file code into the same file as main (moved the function declarations and globals up top).

I changed the XC8 options to link in the C90 library (in Global and Linker options).

This got rid of the psect errors and gave me a successful build. I don't have the chip and your hardware, so I can't go further. Take a look at the attached logging / mapping file. I don't see any space problems, but note this:
    BANK0                used    50h (    80) of    50h bytes   (100.0%)

See link in my first message as you may be able to move some thinks using the bank prefix declarations, but I don't think that you have to for testing.

Can you see if you can get it working with the changes to C90 from C99 (default)?

I *think* but don't know and don't want to go look into it further right now, that it is linking the smaller 24 bit FP libs in contrast to the larger 32 bit FP libs - does anyone know if that is the case?

You should get rid of those implicit conversion warnings. Also note a couple functions that are never called.

Hope this helps more than further confuses :)
« Last Edit: May 08, 2020, 03:24:07 pm by DrG »
- Invest in science - it pays big dividends. -
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 550
  • Country: gb
Re: C: can't find words
« Reply #12 on: May 08, 2020, 04:36:51 pm »
Brilliant, thank you DrG I'll have a go.

BTW when you remark that a couple of functions are not used - does this mean that all the functions in LCD.c are compiled not just the ones that are called or is it just that you've brought LCD.c into the main file in this case?
« Last Edit: May 08, 2020, 04:40:57 pm by PerranOak »
You can release yourself but the only way to go is down!
RJD
 

Offline NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 2507
  • Country: gb
Re: C: can't find words
« Reply #13 on: May 08, 2020, 05:09:58 pm »
In MPLABX the memory usage code and data appears in the project dashboard and also in the output window.

These are XC8 Linker... Reporting Options... "Display overall memory usage etc"

Please could you post your complete code... it doesn't seem to read from anywhere... if you are not careful everything will just get optimised out.  e.g. expressions that involve constants will evaluate at compile time and if they have no references they will not be linked.

PS
If you don't need floating point then don't use it... use scaled calculations in integer types... e.g long FreqTimes10 = a * b * c; and then scale on output.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8888
  • Country: fi
Re: C: can't find words
« Reply #14 on: May 08, 2020, 08:08:12 pm »
If you are going to do embedded microcontroller work, I recommend you learn early on how to deal with fixed point numbers, completely avoiding floating point. It's almost always nearly trivial once you get used to it; actually I "accidentally" tend to use fixed point practices even when I have the luxury of an FPU.

Floating point becomes a possibility on 8-bitters with approx. 8kB (preferably at least 16kB IMHO) of flash whenever the algorithm can be accepted to be a total slug, like calculating a single number for a human being to look at in realtime (in which case it doesn't matter even if it takes milliseconds to calculate).

With 4kB of flash, you are wasting most of it on the software floating point library.

Also note that float is 32 bits, so quite wasteful ram-wise on small 8-bitters which often have just tens to hundreds bytes of RAM, when you can often do with a 16-bit fixed point number instead if you choose the range right.
« Last Edit: May 08, 2020, 08:10:30 pm by Siwastaja »
 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1944
  • Country: us
Re: C: can't find words
« Reply #15 on: May 08, 2020, 08:51:36 pm »
IDEngineer, I just wondered wether the compiler included everything because it reports the functions that I didn't call in LCD.c
The linker will include whatever you reference, PLUS whatever was "packaged" with that thing you referenced. This is why in some environments just touching a single floating point function can link in the entire FP library. Same thing is true for printf(). In the case of FP it's a complex library, and complexity requires a lot of code. In the case of printf(), it's a very flexible library and - you guessed it - flexibility requires a lot of code!

Other environments parcel their libraries into smaller linkable modules so you end up with less bloat. If you're really into it, and the library source is available, you can craft up your own custom mixture of the precise library functions you need so you don't link in anything but exactly what you want/need. Obviously that requires extra work on your part, and the dependencies can increase the footprint pretty fast so the "savings" can end up being smaller than you'd think at first glance.

Which raises another option: If you do have access to the library source, you could manually copy over the source code for the function(s) you need and just freshly compile them as part of your source code, rather than #including and then linking in the existing libraries. Again, the dependencies may make this less beneficial than you'd think, but it might be worth a look.

I heartily second Siwastaja's recommendation that you try to work with fixed point numerics if possible. It's both faster and has a far smaller footprint than floating point, and in many cases it works just as well. Indeed, in certain applications fixed point can be MORE ACCURATE than floating point since fixed point does not suffer from quantization errors. On the other hand, fixed point can suffer from rounding/truncation errors due to limited resolution. Like all of Engineering, it's a tradeoff that you must consider and decide.
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: C: can't find words
« Reply #16 on: May 10, 2020, 03:11:40 pm »
Brilliant, thank you DrG I'll have a go.

BTW when you remark that a couple of functions are not used - does this mean that all the functions in LCD.c are compiled not just the ones that are called or is it just that you've brought LCD.c into the main file in this case?

Not sure if that change made the program run, but I wanted to respond with respect to some of the other posts...I think that you have been given some decent advice and, in general I agree with it completely.

When you are learning PICs, and I am assuming that you are in such a stage because your OP talks about doing an exercise from a book, one of the most important aspects to learn is that there are MANY PIC chips and MANY have been around for a while. That situation can easily result in book examples not "working" any more and it can be very frustrating.

So, for instance, the example in your book may have fit and worked just fine at one time, but not anymore without some changes. Perhaps earlier versions of XC8 used, as a default, the smaller 24-bit floating point library but newer versions, as a default, use the larger 32-bit versions (note that you can even see a message about the larger 32 bit FP libraries in the output). There is no way the book example knew that at the time and for the person who later goes through the example, it can be incredibly frustrating.

There is hope... I have learned to not ignore warnings (unless I completely understand the situation) and to automatically search on errors that puzzle me.

Also, sometimes it is ok to avoid one size fits all "rules". Several times you asked about unused functions and whether they are compiled (thus adding to the program size). The answer is to check yourself - somebody mentioned researching the subject - I agree completely. In this case, comment out the unused functions and compare the program sizes. You will also find out very quickly whether there are some dependencies that exist.

You have probably gained some appreciation for how important understanding linker messages and mapping can be.

Finally, not using floating point libraries unless you really need to use them is probably sound advice since they take up so much space. That may seem daunting at first, but it is a good point to, at least, park in your mind even if you don't stop right now and figure out how to do something without the floating point libraries.

End of my two cents  :)
- Invest in science - it pays big dividends. -
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 550
  • Country: gb
Re: C: can't find words
« Reply #17 on: May 10, 2020, 04:09:21 pm »
Yes, you’re right. I had to upgrade my manual (i.e. buy a new one) when a new version of X8C came out! I think the PIC16F1827 was chosen because it has quite a few features but is limited enough so that everything isn’t easy ... like this problem(!) I, like you, do not let things pass, hence my delving into this problem rather than just blasting on through the manual. I will look properly at the messages in future.

I guess I wasn’t sure about the unused functions and so thought that some answers were contradictory I think this was my paranoia in that I’ve never seen “stdio.h” and wondered if it behaved differently from my LCD.c. This is the sort of thing that manuals don’t mention and I can’t think how to formulate a Google question for it. Still, the solution of experimenting/researching will always work, it’s true!

I hadn’t realised that the floating-point vs fixed-point was an issue ... more for me to research.

Thank you again.  ;D
You can release yourself but the only way to go is down!
RJD
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: C: can't find words
« Reply #18 on: May 10, 2020, 04:32:21 pm »
Yes, you’re right. I had to upgrade my manual (i.e. buy a new one) when a new version of X8C came out! I think the PIC16F1827 was chosen because it has quite a few features but is limited enough so that everything isn’t easy ... like this problem(!) I, like you, do not let things pass, hence my delving into this problem rather than just blasting on through the manual. I will look properly at the messages in future.

I guess I wasn’t sure about the unused functions and so thought that some answers were contradictory I think this was my paranoia in that I’ve never seen “stdio.h” and wondered if it behaved differently from my LCD.c. This is the sort of thing that manuals don’t mention and I can’t think how to formulate a Google question for it. Still, the solution of experimenting/researching will always work, it’s true!

I hadn’t realised that the floating-point vs fixed-point was an issue ... more for me to research.

Thank you again.  ;D

Yeah, there is a lot to it but I like your inquisitive approach.

Sometimes though it just does not seem fair....once using XC32, I was trying to use a 'dead' loop as a delay..

for (i = 0; i < 50000; i++)
{
}

That kind of thing. Yeah, I know how to use timers for delays but in this case I just wanted to debug using a sloppy little for-next loop. It just did not work! Didn't matter if it was 50000 or a kaziillion...just would not make any difference at all - it was driving me up a wall.

The compiler had decided, and without telling me, that I was too stupid to write reasonable code and simply did not compile the for next loop. At least it could have spit out a warning that said...Code Stupidity Error, do nothing code not compiled.  :)

Adding a __NOP in the loop restored sanity.
- Invest in science - it pays big dividends. -
 
The following users thanked this post: PerranOak

Offline chriva

  • Regular Contributor
  • *
  • Posts: 102
  • Country: se
Re: C: can't find words
« Reply #19 on: May 10, 2020, 06:34:51 pm »
Do you have optimizations enabled?
I've noticed that several compilers removes loops if no operation is performed within them.
Gcc in particular may even go next level a-hole and remove inline assembler instructions if they're not declared as volatile :)
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: C: can't find words
« Reply #20 on: May 10, 2020, 08:07:53 pm »
Do you have optimizations enabled?
I've noticed that several compilers removes loops if no operation is performed within them.
Gcc in particular may even go next level a-hole and remove inline assembler instructions if they're not declared as volatile :)

Not sure I understand. But, at the risk of thread drift....

I am using XC32 2.30 free.
Optimization is set to 1 (likely the default). The text for optimizations is as follows (not sure all those levels are available in the free version).

- 0 - Do not optimize. The compiler’s goal is to reduce the cost of compilation and to make debugging produce the expected results.
- 1 - Optimize. Optimizing compilation takes somewhat longer, and a lot more host memory for a large function. The compiler tries to reduce code size and execution time.
- 2 - Optimize even more. The compiler performs nearly all supported optimizations that do not involve a space-speed trade-off.
- 3 - Optimize yet more favoring speed (superset of O2).
- s - Optimize yet more favoring size (superset of O2).

Since I do not have it set at 0, I guess the answer is Yes, I do have optimizations set on. Can't do it right now, but it is worth checking if seting it to '0' would have made a difference.

Thanks
- Invest in science - it pays big dividends. -
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2677
  • Country: us
Re: C: can't find words
« Reply #21 on: May 10, 2020, 11:21:25 pm »
You can also set optimization levels for the free version of XC8.
Level 2 has saved enough memory space for a few of my projects.

Also, use the XC8 built-in delay() functions in the LCD library.
It also should be broken up into header and c files.

Code: [Select]
/*
 * File:   lcd.h
 */

#ifndef  __LCD_H
#define __LCD_H

#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000L
#endif
#include <xc.h>

void lcdputch( char c );               // write one character to LCD
void lcdputs( const char *s );         // write string to LCD
void lcdwrite( unsigned char c );      // write one byte to LCD
void lcdtop( unsigned char offset );   // set cursor to top line
void lcdbot( unsigned char offset );   // set cursor to bottom line
void lcdclear( void );                 // clear LCD and home cursor
void lcdinit( void );                  // initialize LCD

// define macros
#define STROBE PORTBbits.RB5=1,PORTBbits.RB5=0;
#define RS PORTBbits.RB4

#endif /* LCD_H */



/*
 * File:   lcd.c
 */

#include "lcd.h"

void lcdputch( char c )                   // write one char to the LCD
{
   RS = 1;                                // LCD to write chars
   PORTB = (PORTB & 0xF0) | (c >> 4);     // send top 4 bits
   STROBE
   __delay_us(100);
   PORTB = (PORTB & 0xF0) | (c & 0x0F);   // send bottom 4 bits
   STROBE
   __delay_us(100);
}

void lcdputs(const char *s)               // write a string to the LCD
{
   RS = 1;
   while( *s )
      lcdwrite( *s++ );
}

void lcdwrite( unsigned char c )          // write one byte to LCD
{
   PORTB = (PORTB & 0xF0) | (c >> 4);
   STROBE
   __delay_us(100);
   PORTB = (PORTB & 0xF0) | (c & 0x0F);
   STROBE
   __delay_us(100);
}

void lcdtop( unsigned char offset )       // set LCD to top line
{
   unsigned char data;                    // define local variable
   data = 0x80 | offset;
   RS = 0;                                // set LCD to COM mode
   lcdwrite( data );
}

void lcdbot( unsigned char offset )       // set LCD to bottom line
{
   unsigned char data;                    // define local variable
   data = 0xC0 | offset;
   RS = 0;                                // set LCD to COM mode
   lcdwrite( data );
}

void lcdclear( void )                     // clear LCD and home cursor
{
   RS = 0;                                // set LCD to COM mode
   lcdwrite( 0x01 );                      // write 01 to LCD
   __delay_ms(16);                        // wait for LCD to clear
}

void lcdinit( void )                      // initialise the LCD
{
   RS = 0;                                // set LCD to COM mode
   __delay_ms(15);                        // 15mS delay
   PORTB = 0x03;
   STROBE
   __delay_ms(5);                         // 5mS delay
   STROBE
   __delay_ms(5);
   lcdwrite( 0x32 );                      // set to 4 bit mode
   lcdwrite( 0x2C );                      // set for 2 lines
   lcdwrite( 0x08 );                      // display off
   lcdwrite( 0x06 );                      // set increment cursor
   lcdwrite( 0x0C );                      // display on, cur off
   lcdwrite( 0x01 );                      // clear display
   __delay_us(1600);                      // 1.6mS delay
   lcdwrite( 0x02 );                      // home cur, clear RAM
   __delay_us(1600);                      // 1.6mS delay
}



/*
 * File:   main.c
 */

#define _XTAL_FREQ 4000000L

// TODO:  Add Configuration Bits here

#include <xc.h>
#include <stdio.h>
#include "lcd.h"

void main(void)
{
   float cap = 0.1;
   float res = 2489.0;
   float pi = 3.14159;
   float freq;
   int iFreq, iFrac;
   char outstring[20];

   ANSELB = 0;
   TRISB = 0;                         // set all PORTB bits as outputs

   lcdinit();
   
   freq = 1.0 / ( 15.3906 * cap / 1000000 * res );
   iFreq = (int)freq;
   iFrac = (int)((freq - (float)iFreq) * 10.0 + 0.5);

   lcdtop( 0 );                      // cursor to top line 1st char
   lcdputs( "Phase Shift Osc" );
   lcdbot( 0 );                      // cursor to bottom line 1st char
   sprintf( outstring, "Freq = %d.%d Hz", iFreq, iFrac );
   lcdputs( outstring );

   // Main Loop
   while (1)
   {
   }

}



Please use the "code" tags (i.e. the # button while writing a reply).
« Last Edit: May 11, 2020, 07:36:21 am by MarkF »
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 550
  • Country: gb
Re: C: can't find words
« Reply #22 on: May 12, 2020, 05:07:31 pm »
Thanks all, I learned a lot from this thread.

In the end, changing to C90 solved the whole thing.
You can release yourself but the only way to go is down!
RJD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf