View previous topic :: View next topic |
Author |
Message |
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
printf and LCD |
Posted: Thu Apr 07, 2005 9:11 am |
|
|
I am not using LCD.C but I am doing something very similar...
The chip is 18F452.
Compiler is 3.217.
The problem is printf does not send a decimal point to lcd_putc so %03.1lu will only print 805° instead of 180.5°
%04.1lu will print 1805°
I know it must be something simple.....
Code: |
void lcd_putc( char c) {
switch (c) {
case '\c' : send_cmd(1);
delay_ms(2);
break;
case '\t' : send_cmd(0x80); break; //home top line
case '\b' : send_cmd(0xc0); break; //home second line
default : send_char(c);
}
}
main(){
position = 1805;
printf(lcd_putc,"POSITION: %03.1lu%c",position,0xdf);
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Thu Apr 07, 2005 9:28 am |
|
|
'lu', signifies a long unsigned _integer_. Integers don't have a decimal point.....
Best Wishes |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Thu Apr 07, 2005 9:55 am |
|
|
The compiler is doing what you tell him:
position = 1805; // assign 1805 to the long int variable position
then convert it to printf
printf(lcd_putc,"POSITION: %03.1lu%c",position,0xdf);
To solve your problem and print 180.5 you must use a float
at expenses of memory use.
Change:
int16 position
by
float position;
position = 180.5;
printf(lcd_putc,"POSITION: %03.1f%c",position,0xdf);
Keep well,
Humberto |
|
|
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Thu Apr 07, 2005 10:22 am |
|
|
My mistake.
I assumed %03.1 would format any number just by inserting a decimal point where you ask. I will probably write a subroutine to print the way I want instead of using float..... |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Thu Apr 07, 2005 12:30 pm |
|
|
Quote: |
I assumed %03.1 would format any number just by inserting a decimal point where you ask
|
Yes you can do that casting in this way:
printf(lcd_putc,"POSITION: %03.1f%c",(float)position,0xdf);
The number you are formating must have an arithmetic meaning, it is a
little more than accomodating a point.
If you are dealing with integers, the format 03.1 doesn´t have any sense.
Keep well,
Humberto |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Apr 07, 2005 1:00 pm |
|
|
Just div by 10 and print the number
Print a "."
then print the modulus 10 |
|
|
Ttelmah Guest
|
|
Posted: Thu Apr 07, 2005 3:04 pm |
|
|
ljbeng wrote: | My mistake.
I assumed %03.1 would format any number just by inserting a decimal point where you ask. I will probably write a subroutine to print the way I want instead of using float..... |
You can use ldiv.
So:
Code: |
int16 val;
ldiv_t result;
result=ldiv(val,10);
printf("%02lu.%1lu",result.quot,result.rem);
|
Best Wishes |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Apr 07, 2005 5:09 pm |
|
|
Ttelmah wrote: | ljbeng wrote: | My mistake.
I assumed %03.1 would format any number just by inserting a decimal point where you ask. I will probably write a subroutine to print the way I want instead of using float..... |
You can use ldiv.
So:
Code: |
int16 val;
ldiv_t result;
result=ldiv(val,10);
printf("%02lu.%1lu",result.quot,result.rem);
|
Best Wishes |
Today I learned somethin |
|
|
Kieran
Joined: 28 Nov 2003 Posts: 39 Location: Essex UK
|
|
Posted: Fri Apr 08, 2005 5:42 am |
|
|
Quote: |
Code: |
int16 val;
ldiv_t result;
result=ldiv(val,10);
printf("%02lu.%1lu",result.quot,result.rem);
|
|
Is ldiv a built in function? I can't find it (Vn 3.219). |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Fri Apr 08, 2005 5:54 am |
|
|
Look in the current CCS manual page 93 |
|
|
ljbeng
Joined: 10 Feb 2004 Posts: 205
|
|
Posted: Fri Apr 08, 2005 8:03 am |
|
|
Mark,
Version 3.217 gives me an error when I use your example.
Code: | int16 val;
ldiv_t result;
result=ldiv(val,10);
printf("%02lu.%1lu",result.quot,result.rem); |
It stops at the "rem" on the printf line and says "printf format type is invalid". If I change "lu" to "u" it compiles but does not print the correct result if quot > 255. Otherwise, it works, 1805 was printed 180.5 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Apr 08, 2005 8:11 am |
|
|
Not my example but after reading the manual:
Code: |
signed int16 val;
ldiv_t result;
result=ldiv(val,10);
printf("%02ld.%1ld",result.quot,result.rem);
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 08, 2005 8:25 am |
|
|
Sorry about putting 'unsigned' in the printf.
It is in the manual under 'div', rather than 'ldiv' The first is for short integers only, while the latter handles 'longs'.
Best Wishes |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Fri Apr 08, 2005 10:20 am |
|
|
I often have programs that require decimal points in the calculations but I like to use integers instead of floats. When it comes time to format the output for a display I will use a code like this:
Code: |
int16 position = 1805;
char[10] text;// temporary text variable
sprintf(text, "%lu", position);// convert integer to a string
text[5] = text[4];// move string terminator
text[4] = text[3];// move characters to insert a decimal
text[3] = text[2];
text[2] = text[1];
text[1] = 0x2E;// decimal point
printf(lcd_putc,"POSITION: %S%c",position,0xdf);
|
This will convert the integer to a string that can then be shifted around to insert the decimal to wherever you need it. If the integer value will vary greatly then I will use an if() statement to determine just how many numbers will need to be shifted. You could use strlen() as well. Floats use up a lot of ram and decimals, quite often, only need to be used for formatting an output for somebody to read. The internal code can be written to account for the larger number (1805 vs. 180.5).
Ronald |
|
|
|