Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] 16F877, 16F887 ... converting float to string

Status
Not open for further replies.

Eric_O

Advanced Member level 4
Joined
May 31, 2020
Messages
104
Helped
0
Reputation
0
Reaction score
0
Trophy points
16
Activity points
996
Bonjour !
I plan to start my first experiments with interfacing LCD 2 x 16 characters and sensors like LM35, 18DS20, and others ... ultrasonics sensors, I2C RTC, ...
I’m realizing that I will need to convert float numbers (with 1, 2 or 3 digits after decimal point) in char in order to display a characters chain on the LCD.
I would prefer not to use the converting library of MikroC at the beginning. I would like to write (or to read and understand) an open source subroutine doing this. Has some body an idea ? Or examples of code ? Or interesting and useful links ? I’m searching on my side too.
Merci beaucoup ! ?
 

ftoa() is essentially decimal fixed point scaling + itoa() decimal formatted output.

Runtime library functions ftoa(), itoa() and printf() are highly optimized code, usually written in assembly language. You can hardly beat their efficiency. Nevertheless you'll find thousands of C code examples on the internet doing decimal formatted output with %10 and /10 operations. You can can generate decimal formatted output of an integer number per digit right to left, performing repeated divide by 10, using the remainder as output digit and the quotient as input for the next iteration. You'll notice that there's no generic C syntax or generating remainder and quotient in one step, that's why you use assembly language for effective coding.
 

Hi,

I'm no software expert ... but from time to time I'm involved in timing measurements with new hardware/software designs.
Sometimes for debug outputs "sprintf" is used....
In my experience it is booring slow (mind: not sending the data ... really just the sprintf).
Doing the same in C with a lookup table may take just 1% of processing time..if I remember right.

But maybe my expectation is too "optimistic" or we do something wrong with the sprintf.

Klaus
 

Hello,


sprintf is easy to use, but consumes a lot of MCU ressources !
there many other way for using result in float format
examples

Code:
void Float_To_Ascii_2_decim(float chiffreDeci, char * pt)
{

unsigned int e=0;
unsigned int d=0;
e=(int)chiffreDeci ;                                // partie entière
d=(int)((chiffreDeci-(float)e)*100.0);                  // partie décimale(2 chiffres)
if (e/100>0) pt[0]=(char)((e/100)+0x30);                  // partie entiere de 999 a 0
else  pt[0]=' ';
e=e%100;
if (e/10>0)pt[1]=(char)((e/10)+0x30);
else    pt[1]=' ';
pt[2]=(char)((e%10)+0x30);
pt[3]=0x2C;                               // comma instead point
pt[4]=(char)((d/10)+0x30);                     // partie decimale de 99 a 0
pt[5]=(char)((d%10)+0x30);
pt[6]=0  ;
}

i mainly use this one :

Code:
void Float2Ascii (float x, unsigned char *str,char precision)
{
 // converts a floating point number to an ascii string
 // version limitée à 5 decimales maximum
 // x is stored into str, which should be at least 30 chars long
 int ie, i, k, ndig;
 double y;
 if (precision>=5) precision=5;  else precision++;
 ndig =   precision;

 ie = 0;
 // if x negative, write minus and reverse
 if ( x < 0.00000)
 {
   *str++ = '-';
   x = -x;
 }
 // put x in range 1 <= x < 10
 if (x > 0.000000) while (x < 1.000000)
 {
   x *= 10.000;                // a la place de =*
   ie--;
 }
 while (x >= 10.0000)
 {
   x = x/10.0000;
   ie++;
 }
 // in f format, number of digits is related to size
 ndig += ie;                                // a la place de =+
 //round. x is between 1 and 10 and ndig will be printed to
 // right of decimal point so rounding is ...
 for (y = i = 1; i < ndig; i++)
 y = y/10.0000;
 x += y/2.0000;
 if (x >= 10.0000) {x = 1.0000; ie++;}
 if (ie<0)
 {
   *str++ = '0'; *str++ = '.';
   if (ndig < 0) ie = ie-ndig;
   for (i = -1; i > ie; i--)  *str++ = '0';
 }
 for (i=0; i < ndig; i++)
 {
   k = x;
   *str++ = k + '0';
   if (i ==  ie ) *str++ = '.';
   x -= (y=k);
   x *= 10.0000;
  }
 *str = '\0';
}

and more simplest


Code:
  for (F1=0.0;F1<65.0;F1=F1+0.25)
   {
   F2=floor(F1 * 100.0);
                 k=(unsigned int)F2;
                 WordToStr(k,CRam1);
                 k=strlen(CRam1);
                 *(CRam1+k+1)=0;
                 *(CRam1+k)= *(CRam1+k-1);
                 *(CRam1+k-1)= *(CRam1+k-2);
                 *(CRam1+k-2)='.';
                 if (*(CRam1+k-1)==' ') *(CRam1+k-1)='0';
                 if (*(CRam1+k-3)==' ') *(CRam1+k-3)='0';
                 UART1_Write_Text(CRam1);
                 CRLF1();
      }
      while(1);

// gives this result
  0.00
  0.25
  0.50
  0.75
  1.00
  1.25
  1.50 
 63.25
 63.50
 63.75
 64.00
 64.25
 64.50
 64.75
 

    Eric_O

    Points: 2
    Helpful Answer Positive Rating
Many thanks Paul, it will help me, and with comments. ?
 
Last edited by a moderator:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top