Mike Jablonski Mike Jablonski - 1 year ago 266
C Question

printf support for MSP430 micro-controller

I am upgrading a fully tested C program for the Texas Instruments (TI) MSP430 micro-controller using a different C compiler, changing from the Quadravox, AQ430 Development Tool to the VisualGDB C compiler.

The program compiles with zero errors and zero warnings with VisualGDB. The interrupt service routines, timers, UART control, and more all seem to be working. Certain uses of sprintf, however, are not working. For example:

unsigned int duration;
float msec;

msec = (float)duration;

msec = msec / 125.0;

sprintf(glb_response,"break: %3.1f msec",msec);

This returns:
break: %3.1f msec

This is what is expected:
break: 12.5 msec

I have learned about the following (from Wikipedia):

The compiler option --printf_support=[full | minimal | nofloat] allows
you to use a smaller, feature limited, variant of printf/sprintf, and
make that choice at build time.

The valid values are:

full: Supports all format specifiers. This is the default.

nofloat: Excludes support for printing floating point values. Supports
all format specifiers except %f, %g, %G, %e, and %E.

minimal: Supports the printing of integer, char, or string values
without width or precision flags. Specifically, only the %%, %d, %o,
%c, %s, and %x format specifiers are supported

I need full support for printf. I know the MSP430 on my product will support this, as this C program has been in service for years.

My problem is that I can't figure out 1) if VisualGDB has the means to set printf support to full and 2) if so, where and to set it.

Any and all comments and answers will be appreciated.

Answer Source

I would suggest that full support for floating point is both unnecessary and ill-advised. It is a large amount of code to solve a trivial problem; and without floating-point hardware, floating point operations are usually best avoided in any case for performance, code space and memory usage reasons.

So it appears that duration is in units of 1/125000 seconds and that you wish to output a value to a precision of 0.1 milliseconds. So:

unsigned msec_x10 = duration * 10u / 125u ;

sprintf( glb_response, 
         "break: %u.%u msec", 
         msec_x10 / 10,  
         msec_x10 % 10 ) ;

If you want rounding to the nearest tenth (as opposed to rounding down), then:

unsigned msec_x10 = ((duration * 20u) + 125 ) / 250u ;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download