Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
void float_to_ASCII_with_2_decimal_v5(float fx, char *pt)
{
unsigned long e = 0; // 0 to more than 65535.
unsigned long d = 0; // 0 to more than 65535.
float f0, chiffre_decimal=0.0;
int k=0;
if (fx < 0)
{
*(pt) = '-'; // 0cx2D
chiffre_decimal=-fx;
}
else
{
*(pt) = '+'; // 0x2B signe +
chiffre_decimal=fx;
}
e =(unsigned long) floor(chiffre_decimal); // Partie entière.
d =(chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres);
// Partie entière de 99999 à 0 :
if (e/100000L >= 0) *(pt+1) =(unsigned char) (e/100000L) + 0x30;
e = e%100000L;
if (e/10000L >= 0) *(pt+2) =(unsigned char) (e/10000L) + 0x30;
e = e%10000L...
Bonjour Susan,Which compiler are you using?
If you are using XC8 then you can use the 'ltoa' library function but it assumes a long value only. There is also the 'ftoa' function for floating point values.
I'm also confused by some aspects of your question. In the title you mention 'double long'; do you mean 'long long'? On the other hand, the values you give seem to imply 2 decimal places (using the European convention for the decimal point); are you using floating point values (hence the 'double' in the title perhaps) or are you using a scaled integer?
A 'long' (in XC8 at least) is 32 bits (as is 'long long') and the signed variant that will hold either the scaled version or the unscaled (excluding the decimal part) version easily (in fact you can use the 24-bit 'short long' and still get a domain of well over +/-1,000,000).
If you really are using floating point (and I would certainly recommend that you don't with these lower range MCUs as everything has to be done in software and that can be very slow) then you may run into problems with the precision you can get - you seem to imply that you want 7 (or perhaps 9) digits.
Susan
void float_to_ASCII_with_2_decimal_v5(float fx, char *pt)
{
unsigned long e = 0; // 0 to more than 65535.
unsigned long d = 0; // 0 to more than 65535.
float f0, chiffre_decimal=0.0;
int k=0;
if (fx < 0)
{
*(pt) = '-'; // 0cx2D
chiffre_decimal=-fx;
}
else
{
*(pt) = '+'; // 0x2B signe +
chiffre_decimal=fx;
}
e =(unsigned long) floor(chiffre_decimal); // Partie entière.
d =(chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres);
// Partie entière de 99999 à 0 :
if (e/100000L >= 0) *(pt+1) =(unsigned char) (e/100000L) + 0x30;
e = e%100000L;
if (e/10000L >= 0) *(pt+2) =(unsigned char) (e/10000L) + 0x30;
e = e%10000L;
if (e/1000 >= 0) *(pt+3) = (unsigned char) (e/1000) + 0x30 ;
e = e%1000L;
if (e/100L >= 0) *(pt+4) = (unsigned char) (e/100L) + 0x30;
e = e%100L;
if (e/10L >= 0) *(pt+5) =(unsigned char) (e/10L) + 0x30;
*(pt+6) = (unsigned char) (e%10L) + 0x30;
*(pt+7) = 0x2C ; // Virgule au lieu d' un point.
*(pt+8)= (unsigned char) (d/10) + 0x30; // Partie décimale de 99 à 0 :
*(pt+9) = (unsigned char) (d%10) + 0x30;
*(pt+10)= 0;
// maintenant on arrange en supprimant les zeros inutiles
if (*(pt+1)=='0')
{
*(pt+1)=' ';
if (*(pt+2)=='0')
{
*(pt+2)=' ';
if (*(pt+3)=='0')
{
*(pt+3)=' ';
if (*(pt+4)=='0')
{
*(pt+4)=' ';
if (*(pt+5)=='0')
{
*(pt+5)=' ';
}
}
}
}
}
}
//=== Zone de test =======================
f1=-999999.98;
pt=&TEXTE[0];
CPrint(" Test float_to_ASCII_with_2_decimal_v5(f1,pt) gamme -999 999 à + 999 999;\r\n");
float_to_ASCII_with_2_decimal_v5(f1,pt) ;
CPrint("Valeur de depart = "); Print(pt);
CPrint(" Increment = 10000.01;\r\n");
CRLF1();
do
{
float_to_ASCII_with_2_decimal_v5(f1,pt) ;
Print(pt);CRLF1();
f1=f1+10000.01;
}
while(f1<999999.99);
CRLF1();
CRLF1();
f1=-10.00;
float_to_ASCII_with_2_decimal_v5(f1,pt) ;
CPrint("Valeur de depart = "); Print(pt);
CPrint(" Increment =0.01;\r\n");
CRLF1();
do
{
float_to_ASCII_with_2_decimal_v5(f1,pt) ;
Print(pt);CRLF1();
f1=f1+0.01;
}
while(f1<10.0);
while(1);
(16:03:59.982) Directory: C:\_MikroC\_MesProjets_MikroC\_18F26K22_LCD_2x16_Classic_mode4bits
(16:04:00.127) Projet : Base_18F26K22_for_Tests_UART1_LCD1602_4bits_2021-06.mcppi
(16:04:00.266) Alim. = >4.5V
(16:04:00.374) Config : P18F26K22_FOSC_interne_16Mhz.cfgsch
(16:04:00.501) FOSC interne 16MHz
(16:04:00.612) Port Hard UART1 19200,N,8,1 (RC6=TX RC7=RX)
(16:04:00.738) Init RA0 as Analog Input
(16:04:00.857) Source Base_18F26K22_for_Tests_UART_LCD1602_4bits_2021_0708.c
(16:04:00.990) LCD 2x16 car 4bits data + 2 cdes
(16:04:01.110) RA5 = choix mode ADC via lib MikroC ou simili ASM
(16:04:01.143)
(16:04:02.340) Test Toggle Led Rouge RA4
(16:04:06.355) -:00000,00 <--- ":" ?????
(16:04:06.379) -989999,93
.....
(16:04:07.328) -109996,00
(16:04:07.339) - 99995,98
....
(16:04:07.415) - 29995,89
(16:04:07.426) - 19995,88
(16:04:07.437) - 9995,87
(16:04:07.449) + 4,13
(16:04:07.459) + 10004,14
.....
(16:04:07.547) + 90004,21
(16:04:07.558) +100004,21
.......
(16:04:08.545) +980004,25
(16:04:08.545) +990004,25
Zoom autour de zero :
Valeur de depart = - 10,00 Increment =0.01;
- 10,00
- 9,98
- 9,97
- 9,96
- 9,95
- 9,94
.......
- 0,11
- 0,10
- 0,09
- 0,08
- 0,07
- 0,06
- 0,05
- 0,04
- 0,03
- 0,02
- 0,01
- 0,00 <---- les aleas du flottant et les problemes d'arrondi avec
+ 0,00 <---- des nombres NON FINIs ...
+ 0,01
+ 0,02
+ 0,03
+ 0,04
+ 0,05
+ 0,06
+ 0,07
+ 0,08
+ 0,09
+ 0,10
+ 0,11
+ 0,12
Merci Paul !hello,
i extended the last function to _999999.99 up to +999999.99
Code:void float_to_ASCII_with_2_decimal_v5(float fx, char *pt) { unsigned long e = 0; // 0 to more than 65535. unsigned long d = 0; // 0 to more than 65535. float f0, chiffre_decimal=0.0; int k=0; if (fx < 0) { *(pt) = '-'; // 0cx2D chiffre_decimal=-fx; } else { *(pt) = '+'; // 0x2B signe + chiffre_decimal=fx; } e =(unsigned long) floor(chiffre_decimal); // Partie entière. d =(chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres); // Partie entière de 99999 à 0 : if (e/100000L >= 0) *(pt+1) =(unsigned char) (e/100000L) + 0x30; e = e%100000L; if (e/10000L >= 0) *(pt+2) =(unsigned char) (e/10000L) + 0x30; e = e%10000L; if (e/1000 >= 0) *(pt+3) = (unsigned char) (e/1000) + 0x30 ; e = e%1000L; if (e/100L >= 0) *(pt+4) = (unsigned char) (e/100L) + 0x30; e = e%100L; if (e/10L >= 0) *(pt+5) =(unsigned char) (e/10L) + 0x30; *(pt+6) = (unsigned char) (e%10L) + 0x30; *(pt+7) = 0x2C ; // Virgule au lieu d' un point. *(pt+8)= (unsigned char) (d/10) + 0x30; // Partie décimale de 99 à 0 : *(pt+9) = (unsigned char) (d%10) + 0x30; *(pt+10)= 0; // maintenant on arrange en supprimant les zeros inutiles if (*(pt+1)=='0') { *(pt+1)=' '; if (*(pt+2)=='0') { *(pt+2)=' '; if (*(pt+3)=='0') { *(pt+3)=' '; if (*(pt+4)=='0') { *(pt+4)=' '; if (*(pt+5)=='0') { *(pt+5)=' '; } } } } } }
Test programme
Code://=== Zone de test ======================= f1=-999999.98; pt=&TEXTE[0]; CPrint(" Test float_to_ASCII_with_2_decimal_v5(f1,pt) gamme -999 999 à + 999 999;\r\n"); float_to_ASCII_with_2_decimal_v5(f1,pt) ; CPrint("Valeur de depart = "); Print(pt); CPrint(" Increment = 10000.01;\r\n"); CRLF1(); do { float_to_ASCII_with_2_decimal_v5(f1,pt) ; Print(pt);CRLF1(); f1=f1+10000.01; } while(f1<999999.99); CRLF1(); CRLF1(); f1=-10.00; float_to_ASCII_with_2_decimal_v5(f1,pt) ; CPrint("Valeur de depart = "); Print(pt); CPrint(" Increment =0.01;\r\n"); CRLF1(); do { float_to_ASCII_with_2_decimal_v5(f1,pt) ; Print(pt);CRLF1(); f1=f1+0.01; } while(f1<10.0); while(1);
results
// LCD module connections :
// VSS (pin 1) -> GND
// VDD (pin 2) -> VCC
// VEE (pin 3) -> middle pin contrast potentiometer
sbit LCD_RS at RB4_bit; // RS (pin 4) -> portB.b4 (pin 37)
// RW not used. // RW (pin 5) -> GND
sbit LCD_EN at RB5_bit; // EN (pin 6) -> portB.b5 (pin 38)
// D0 (pin 7) -> GND
// D1 (pin 8) -> GND
// D2 (pin 9) -> GND
// D3 (pin 10) -> GND
sbit LCD_D4 at RB0_bit; // D4 (pin 11) -> portB.b0 (pin 33)
sbit LCD_D5 at RB1_bit; // D5 (pin 12) -> portB.b1 (pin 34)
sbit LCD_D6 at RB2_bit; // D6 (pin 13) -> portB.b2 (pin 35)
sbit LCD_D7 at RB3_bit; // D7 (pin 14) -> portB.b3 (pin 36)
// (pin 15) -> GND
// (pin 16) -> GND
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
/******************************************************************************/
// Declaration of variables :
float chiffre_decimal, sec; // - 1.5 x 10 puissance 45 to + 3.4 x 10 puissance 38
char texte[64], *pt; // 0 to 255
/******************************************************************************/
// Routines :
void LCD_E_pulse(void)
{
LCD_EN = 1;
Delay_us(5);
LCD_EN = 0;
Delay_us(5);
}
void LCD_Write_Cmd(unsigned char octet)
{
LCD_RS = 0; // Select Command Register.
// Send upper nibble.
LCD_D4 = ((octet & 0x10) == 0x10) ? 1 : 0; // Si ((octet & 0x10) == 0x10) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x20) == 0x20) ? 1 : 0; // Si ((octet & 0x20) == 0x20) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x40) == 0x40) ? 1 : 0; // Si ((octet & 0x40) == 0x40) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x80) == 0x80) ? 1 : 0; // Si ((octet & 0x80) == 0x80) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
// Send lower nibble.
LCD_D4 = ((octet & 0x01) == 0x01) ? 1 : 0; // Si ((octet & 0x01) == 0x01) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x02) == 0x02) ? 1 : 0; // Si ((octet & 0x02) == 0x02) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x04) == 0x04) ? 1 : 0; // Si ((octet & 0x04) == 0x04) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x08) == 0x08) ? 1 : 0; // Si ((octet & 0x08) == 0x08) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
}
void LCD_Write_Data(char octet)
{
LCD_RS = 1; // Select Data Register.
// Send upper nibble.
LCD_D4 = ((octet & 0x10) == 0x10) ? 1 : 0; // Si ((octet & 0x10) == 0x10) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x20) == 0x20) ? 1 : 0; // Si ((octet & 0x20) == 0x20) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x40) == 0x40) ? 1 : 0; // Si ((octet & 0x40) == 0x40) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x80) == 0x80) ? 1 : 0; // Si ((octet & 0x80) == 0x80) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
// Send lower nibble.
LCD_D4 = ((octet & 0x01) == 0x01) ? 1 : 0; // Si ((octet & 0x01) == 0x01) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x02) == 0x02) ? 1 : 0; // Si ((octet & 0x02) == 0x02) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x04) == 0x04) ? 1 : 0; // Si ((octet & 0x04) == 0x04) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x08) == 0x08) ? 1 : 0; // Si ((octet & 0x08) == 0x08) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
}
void strConstRamCpy(unsigned char *dest, const code char *source) // Copie le texte de la FLASH ROM vers la RAM.
{
while (*source)*dest ++ = *source ++;
*dest = 0; // Terminateur "0" fin de chaine de caractère.
}
void LCD_Write_CString_v2(char *msg) // Variante avec pointeur msg non modifié.
{
int k;
k = 0;
//while(*(msg) > 0) // FAIL.
while(*(msg + k) > 0) // OK.
{
LCD_Write_Data(*(msg + k)); // Data pointée par (msg + k).
k++;
if (k > 15) break; // Si k > 15 sortie de la boucle while ...
}
}
void LCD_CString_Position_v2(char row, char col, char *msg) //
{
if (row == 1)
{
LCD_Write_Cmd((col & 0x0F)|0x80); // Print message on 1st row and desired location.
}
else if (row == 2)
{
LCD_Write_Cmd((col & 0x0F)|0xC0); // Print message on 2nd row and desired location.
}
LCD_Write_CString_v2(msg); // OK.
}
void float_to_ASCII_with_2_decimal_v7(float fx, char *pt)
{
unsigned long e = 0; // 0 to 4294967295.
unsigned long d = 0; // 0 to 4294967295.
float chiffre_decimal = 0.0;
if (fx < 0)
{
*(pt) = '-';
chiffre_decimal = - fx;
}
else
{
*(pt) = ' ';
chiffre_decimal = fx;
}
e = (unsigned long) floor(chiffre_decimal); // Partie entière.
d = (chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres).
*(pt + 1) = ' ';
if (e/1000000 >= 0) *(pt + 2) = (unsigned char) (e/1000000) + 0x30; // Partie entière de 9999999 à 0.
e = e%1000000;
if (e/100000 >= 0) *(pt + 3) = (unsigned char) (e/100000) + 0x30;
e = e%100000;
if (e/10000 >= 0) *(pt + 4) = (unsigned char) (e/10000) + 0x30;
e = e%10000;
if (e/1000 >= 0) *(pt + 5) = (unsigned char) (e/1000) + 0x30;
e = e%1000;
if (e/100 >= 0) *(pt + 6) = (unsigned char) (e/100) + 0x30;
e = e%100;
if (e/10 >= 0) *(pt + 7) = (unsigned char) (e/10) + 0x30;
*(pt + 8) = (unsigned char) (e%10) + 0x30;
*(pt + 9) = 0x2C; // Virgule au lieu d'un point.
*(pt + 10) = (unsigned char) (d/10) + 0x30; // Partie décimale de 00 à 99.
*(pt + 11) = (unsigned char) (d%10) + 0x30;
*(pt + 12) = 0;
if (*(pt + 2) == '0') // Suppression des zéros inutiles.
{
*(pt + 2) = ' ';
if (*(pt + 3) == '0')
{
*(pt + 3) = ' ';
if (*(pt + 4) == '0')
{
*(pt + 4) = ' ';
if (*(pt + 5) == '0')
{
*(pt + 5) = ' ';
if (*(pt + 6) == '0')
{
*(pt + 6) = ' ';
if (*(pt + 7) == '0')
{
*(pt + 7) = ' ';
}
}
}
}
}
}
}
void LCD_Init_v4 (void) // OK.
{
Delay_ms(15); // LCD power ON initialization time >= 15 mS.
LCD_Write_Cmd(0x30); // 4 datas bits > Initialization of LCD with nibble method (4 datas bits).
LCD_Write_Cmd(0x02); // 4 datas bits > Initialization of LCD with nibble method (4 datas bits).
LCD_Write_Cmd(0x28); // 4 datas bits > 2 lines display, 5 × 8 dot character font.
LCD_Write_Cmd(0x0C); // 4 datas bits > Display ON. Cursor OFF.
LCD_Write_Cmd(0x06); // 4 datas bits > Auto increment cursor.
LCD_Write_Cmd(0x01); // 4 datas bits > Clear display.
Delay_ms(1); // Ajustable ...
}
/******************************************************************************/
// Main program :
void main()
{
ANSEL = 0; // Configure AN pins as digital I/O.
ANSELH = 0;
C1ON_bit = 0; // Disable Comparator 1.
C2ON_bit = 0; // Disable Comparator 2.
PORTB = 0;
TRISB = 0;
PORTC = 0;
TRISC = 0;
// Essai 16.1 : ALMOST OK ...
Lcd_Init_v4(); // Initialize LCD.
while(1) // Endless loop.
{
unsigned char *pointeur_de_char; // Déclaration d'un pointeur (*) de char "pointeur_de_char".
//char texte[] = "Counting ..."; // Déclaration d'un tableau "texte" de type char et initialisé avec la chaine de caractères "Counting ..." :
// En n'indiquant aucun chiffre entre les cochets [], le compilateur ajustera automatiquement la taille du
// tableau, et allouera en mémoire RAM, le bon nombre d'éléménts, soit 13 ...
char txt[13];
pointeur_de_char = &texte[0]; // pointeur_de_char pointe sur le premier élément du tableau "texte", soit texte[0].
// Autrement dit, pointeur_de_char contient l'adresse (&) de texte[0].
//for(sec = -1000000; sec <= 1000000; sec = sec + 0.5) // sec déclarée en float. OK.
//for(sec = -8000000; sec <= 8000000; sec = sec + 0.5) // sec déclarée en float. OK.
//for(sec = -8379999; sec <= 8379999; sec = sec + 0.5) // sec déclarée en float. OK (maxi).
for(sec = -9000000; sec <= 9000000; sec = sec + 0.5) // sec déclarée en float. FAIL.
{
portc.b2 = 1; // LED yellow ON.
strConstRamCpy(pointeur_de_char, "Counting ..."); // OK.
LCD_CString_Position_v2(1, 0, pointeur_de_char); // OK. Voir dans void LCD_Write_CString_v2(char *msg), le while(*(msg + k) > 0).
float_to_ASCII_with_2_decimal_v7(sec, txt);
LCD_CString_Position_v2(2, 0, txt); // Write txt in 2nd row, starting at 1st digit.
LCD_CString_Position_v2(2, 13, "uS"); // Write "uS" in 2nd row, starting at 14th digit
Delay_us(1);
//Delay_ms(1000);
}
portc.b2 = 0; // LED yellow OFF.
portc.b3 = 1; // LED green ON.
portc.b4 = 1; // BUZZER ON.
Delay_ms(5000);
portc.b3 = 0; // LED green OFF.
portc.b4 = 0; // BUZZER OFF.
}
}
void float_to_ASCII_with_2_decimal_v5(float fx, char *pt)
{
unsigned long e = 0; // 0 to <= 9 999 999
unsigned long d = 0;
float f0, chiffre_decimal=0.0;
int k=0;
if (fx < 0)
{
*(pt) = '-'; // 0cx2D
chiffre_decimal=-fx;
}
else
{
*(pt) = '+'; // 0x2B signe +
chiffre_decimal=fx;
}
e =(unsigned long) floor(chiffre_decimal); // Partie entière.
d =(chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres);
// Partie entière de 9 999 999 à 0 :
if (e/1000000L >= 0) *(pt+1) =(unsigned char) (e/1000000L) + 0x30;
e = e%1000000L; // 1 000 000
if (e/100000L >= 0) *(pt+2) =(unsigned char) (e/100000L) + 0x30;
e = e%100000L; // 100 000
if (e/10000 >= 0) *(pt+3) = (unsigned char) (e/10000) + 0x30 ;
e = e%10000L; // 10 000
if (e/1000L >= 0) *(pt+4) = (unsigned char) (e/1000L) + 0x30;
e = e%1000L;
if (e/100L >= 0) *(pt+5) =(unsigned char) (e/100L) + 0x30;
e = e%100L;
if (e/10L >= 0) *(pt+6) =(unsigned char) (e/10L) + 0x30;
*(pt+7) = (unsigned char) (e%10L) + 0x30;
*(pt+8) = 0x2C ; // Virgule au lieu d' un point.
*(pt+9)= (unsigned char) (d/10) + 0x30; // Partie décimale de 99 à 0 :
*(pt+10) = (unsigned char) (d%10) + 0x30;
*(pt+11)= 0;
// maintenant on arrange en supprimant les zeros inutiles
if (*(pt+1)=='0')
{
*(pt+1)=' ';
if (*(pt+2)=='0')
{
*(pt+2)=' ';
if (*(pt+3)=='0')
{
*(pt+3)=' ';
if (*(pt+4)=='0')
{
*(pt+4)=' ';
if (*(pt+5)=='0')
{
*(pt+5)=' ';
}
if (*(pt+6)=='0')
{
*(pt+6)=' ';
}
}
}
}
}
}
hello,
i digit more needs to shift all the other calculus..
Code:void float_to_ASCII_with_2_decimal_v5(float fx, char *pt) { unsigned long e = 0; // 0 to <= 9 999 999 unsigned long d = 0; float f0, chiffre_decimal=0.0; int k=0; if (fx < 0) { *(pt) = '-'; // 0cx2D chiffre_decimal=-fx; } else { *(pt) = '+'; // 0x2B signe + chiffre_decimal=fx; } e =(unsigned long) floor(chiffre_decimal); // Partie entière. d =(chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres); // Partie entière de 9 999 999 à 0 : if (e/1000000L >= 0) *(pt+1) =(unsigned char) (e/1000000L) + 0x30; e = e%1000000L; // 1 000 000 if (e/100000L >= 0) *(pt+2) =(unsigned char) (e/100000L) + 0x30; e = e%100000L; // 100 000 if (e/10000 >= 0) *(pt+3) = (unsigned char) (e/10000) + 0x30 ; e = e%10000L; // 10 000 if (e/1000L >= 0) *(pt+4) = (unsigned char) (e/1000L) + 0x30; e = e%1000L; if (e/100L >= 0) *(pt+5) =(unsigned char) (e/100L) + 0x30; e = e%100L; if (e/10L >= 0) *(pt+6) =(unsigned char) (e/10L) + 0x30; *(pt+7) = (unsigned char) (e%10L) + 0x30; *(pt+8) = 0x2C ; // Virgule au lieu d' un point. *(pt+9)= (unsigned char) (d/10) + 0x30; // Partie décimale de 99 à 0 : *(pt+10) = (unsigned char) (d%10) + 0x30; *(pt+11)= 0; // maintenant on arrange en supprimant les zeros inutiles if (*(pt+1)=='0') { *(pt+1)=' '; if (*(pt+2)=='0') { *(pt+2)=' '; if (*(pt+3)=='0') { *(pt+3)=' '; if (*(pt+4)=='0') { *(pt+4)=' '; if (*(pt+5)=='0') { *(pt+5)=' '; } if (*(pt+6)=='0') { *(pt+6)=' '; } } } } } }
mistake was here, so after
*(pt + 1) = ' ';
if (e/1000000 >= 0) *(pt + 2) = (unsigned char) (e/1000000) + 0x30; // Partie entière de 9999999 à 0.
*(p+2); <-- bad must be *(p+1) .. and so on for other pointer value
It indicates the value should be interpreted as a 'long'. A hint to the compiler that even if the number is small, it should still reserve enough space for a 'long' sized number.What is aim of the « L » after zeros ?
Bonjour Brian,It indicates the value should be interpreted as a 'long'. A hint to the compiler that even if the number is small, it should still reserve enough space for a 'long' sized number.
Brian.
Bonsoir Paul,hello,
if you want to add a space between '-' and first digit , you must shift all other pointers values
for the digits, and increase the size of buffer by 1 ...
Bonsoir Paul,If it was working without the additional space , no reason to fail .. except an additonnal bug
Are you also adding a space for positive number ?
between signe + and 1rst digit
nota : my tests were made with UART -> terminal , not with LCD..
post your code ... i will have a look ..
// LCD module connections :LCD module connections :
// VSS (pin 1) -> GND
// VDD (pin 2) -> VCC
// VEE (pin 3) -> middle pin contrast potentiometer
sbit LCD_RS at RB4_bit; // RS (pin 4) -> portB.b4 (pin 37)
// RW not used. // RW (pin 5) -> GND
sbit LCD_EN at RB5_bit; // EN (pin 6) -> portB.b5 (pin 38)
// D0 (pin 7) -> GND
// D1 (pin 8) -> GND
// D2 (pin 9) -> GND
// D3 (pin 10) -> GND
sbit LCD_D4 at RB0_bit; // D4 (pin 11) -> portB.b0 (pin 33)
sbit LCD_D5 at RB1_bit; // D5 (pin 12) -> portB.b1 (pin 34)
sbit LCD_D6 at RB2_bit; // D6 (pin 13) -> portB.b2 (pin 35)
sbit LCD_D7 at RB3_bit; // D7 (pin 14) -> portB.b3 (pin 36)
// (pin 15) -> GND
// (pin 16) -> GND
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
/******************************************************************************/
// Declaration of variables :
float chiffre_decimal, sec; // - 1.5 x 10 puissance 45 to + 3.4 x 10 puissance 38
char texte[64], *pt; // 0 to 255
/******************************************************************************/
// Routines :
void LCD_E_pulse(void)
{
LCD_EN = 1;
Delay_us(5);
LCD_EN = 0;
Delay_us(5);
}
void LCD_Write_Cmd(unsigned char octet) // Version 3 : OK.
{
LCD_RS = 0; // Select Command Register.
// Send upper nibble.
LCD_D4 = ((octet & 0x10) == 0x10) ? 1 : 0; // Si ((octet & 0x10) == 0x10) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x20) == 0x20) ? 1 : 0; // Si ((octet & 0x20) == 0x20) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x40) == 0x40) ? 1 : 0; // Si ((octet & 0x40) == 0x40) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x80) == 0x80) ? 1 : 0; // Si ((octet & 0x80) == 0x80) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
// Send lower nibble.
LCD_D4 = ((octet & 0x01) == 0x01) ? 1 : 0; // Si ((octet & 0x01) == 0x01) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x02) == 0x02) ? 1 : 0; // Si ((octet & 0x02) == 0x02) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x04) == 0x04) ? 1 : 0; // Si ((octet & 0x04) == 0x04) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x08) == 0x08) ? 1 : 0; // Si ((octet & 0x08) == 0x08) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
}
void LCD_Write_Data(char octet) // Version 2 : OK.
{
LCD_RS = 1; // Select Data Register.
// Send upper nibble.
LCD_D4 = ((octet & 0x10) == 0x10) ? 1 : 0; // Si ((octet & 0x10) == 0x10) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x20) == 0x20) ? 1 : 0; // Si ((octet & 0x20) == 0x20) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x40) == 0x40) ? 1 : 0; // Si ((octet & 0x40) == 0x40) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x80) == 0x80) ? 1 : 0; // Si ((octet & 0x80) == 0x80) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
// Send lower nibble.
LCD_D4 = ((octet & 0x01) == 0x01) ? 1 : 0; // Si ((octet & 0x01) == 0x01) alors LCD_D4 = 1 sinon = 0.
LCD_D5 = ((octet & 0x02) == 0x02) ? 1 : 0; // Si ((octet & 0x02) == 0x02) alors LCD_D5 = 1 sinon = 0.
LCD_D6 = ((octet & 0x04) == 0x04) ? 1 : 0; // Si ((octet & 0x04) == 0x04) alors LCD_D6 = 1 sinon = 0.
LCD_D7 = ((octet & 0x08) == 0x08) ? 1 : 0; // Si ((octet & 0x08) == 0x08) alors LCD_D7 = 1 sinon = 0.
LCD_E_Pulse();
}
void strConstRamCpy(unsigned char *dest, const code char *source) // Copie le texte de la FLASH ROM vers la RAM.
{
while (*source)*dest ++ = *source ++;
*dest = 0; // Terminateur "0" fin de chaine de caractère.
}
void LCD_Write_CString_v2(char *msg) // Variante avec pointeur msg non modifié.
{
int k;
k = 0;
//while(*(msg) > 0) // FAIL.
while(*(msg + k) > 0) // OK.
{
LCD_Write_Data(*(msg + k)); // Data pointée par (msg + k).
k++;
if (k > 15) break; // Si k > 15 sortie de la boucle while ...
}
}
void LCD_CString_Position_v2(char row, char col, char *msg) //
{
if (row == 1)
{
LCD_Write_Cmd((col & 0x0F)|0x80); // Print message on 1st row and desired location.
}
else if (row == 2)
{
LCD_Write_Cmd((col & 0x0F)|0xC0); // Print message on 2nd row and desired location.
}
LCD_Write_CString_v2(msg); // OK.
}
void float_to_ASCII_with_2_decimal_v7(float fx, char *pt)
{
unsigned long e = 0; // 0 to 4294967295.
unsigned long d = 0; // 0 to 4294967295.
float chiffre_decimal = 0.0;
if (fx < 0)
{
*(pt) = '-';
chiffre_decimal = - fx;
}
else
{
*(pt) = ' ';
chiffre_decimal = fx;
}
e = (unsigned long) floor(chiffre_decimal); // Partie entière.
d = (chiffre_decimal - (float)e) * 100; // Partie décimale (2 chiffres).
*(pt + 1) = ' '; // Keep a space between sign and first digit.
if (e/1000000 >= 0) *(pt + 2) = (unsigned char) (e/1000000) + 0x30; // Partie entière de 9999999 à 0.
e = e%1000000;
if (e/100000 >= 0) *(pt + 3) = (unsigned char) (e/100000) + 0x30;
e = e%100000;
if (e/10000 >= 0) *(pt + 4) = (unsigned char) (e/10000) + 0x30;
e = e%10000;
if (e/1000 >= 0) *(pt + 5) = (unsigned char) (e/1000) + 0x30;
e = e%1000;
if (e/100 >= 0) *(pt + 6) = (unsigned char) (e/100) + 0x30;
e = e%100;
if (e/10 >= 0) *(pt + 7) = (unsigned char) (e/10) + 0x30;
*(pt + 8) = (unsigned char) (e%10) + 0x30;
*(pt + 9) = 0x2C; // Virgule au lieu d'un point.
*(pt + 10) = (unsigned char) (d/10) + 0x30; // Partie décimale de 00 à 99.
*(pt + 11) = (unsigned char) (d%10) + 0x30;
*(pt + 12) = 0;
if (*(pt + 2) == '0') // Suppression des zéros inutiles.
{
*(pt + 2) = ' ';
if (*(pt + 3) == '0')
{
*(pt + 3) = ' ';
if (*(pt + 4) == '0')
{
*(pt + 4) = ' ';
if (*(pt + 5) == '0')
{
*(pt + 5) = ' ';
if (*(pt + 6) == '0')
{
*(pt + 6) = ' ';
if (*(pt + 7) == '0')
{
*(pt + 7) = ' ';
}
}
}
}
}
}
}
void LCD_Init_v4 (void) // OK.
{
Delay_sms(15); // LCD power ON initialization time >= 15 mS.
LCD_Write_Cmd(0x30); // 4 datas bits > Initialization of LCD with nibble method (4 datas bits).
LCD_Write_Cmd(0x02); // 4 datas bits > Initialization of LCD with nibble method (4 datas bits).
LCD_Write_Cmd(0x28); // 4 datas bits > 2 lines display, 5 × 8 dot character font.
LCD_Write_Cmd(0x0C); // 4 datas bits > Display ON. Cursor OFF.
LCD_Write_Cmd(0x06); // 4 datas bits > Auto increment cursor.
LCD_Write_Cmd(0x01); // 4 datas bits > Clear display.
Delay_ms(1); // Ajustable ...
}
/******************************************************************************/
// Main program :
void main()
{
ANSEL = 0; // Configure AN pins as digital I/O.
ANSELH = 0;
C1ON_bit = 0; // Disable Comparator 1.
C2ON_bit = 0; // Disable Comparator 2.
PORTB = 0;
TRISB = 0;
PORTC = 0;
TRISC = 0;
// Essai 16.2 : DEBUGGING ...
Lcd_Init_v4(); // Initialize LCD.
while(1) // Endless loop.
{
unsigned char *pointeur_de_char; // Déclaration d'un pointeur (*) de char "pointeur_de_char".
//char texte[] = "Counting ..."; // Déclaration d'un tableau "texte" de type char et initialisé avec la chaine de caractères "Counting ..." :
// En n'indiquant aucun chiffre entre les cochets [], le compilateur ajustera automatiquement la taille du
// tableau, et allouera en mémoire RAM, le bon nombre d'éléménts, soit 13 ...
char txt[13];
pointeur_de_char = &texte[0]; // pointeur_de_char pointe sur le premier élément du tableau "texte", soit texte[0].
// Autrement dit, pointeur_de_char contient l'adresse (&) de texte[0].
//for(sec = -1000000; sec <= 1000000; sec = sec + 0.5) // sec déclarée en float. OK.
//for(sec = -8000000; sec <= 8000000; sec = sec + 0.5) // sec déclarée en float. OK.
//for(sec = -8379999; sec <= 8379999; sec = sec + 0.5) // sec déclarée en float. OK (maxi).
for(sec = -9000000; sec <= 9000000; sec = sec + 0.5) // sec déclarée en float. FAIL.
{
portc.b2 = 1; // LED yellow ON.
strConstRamCpy(pointeur_de_char, "Counting ..."); // OK.
LCD_CString_Position_v2(1, 0, pointeur_de_char); // OK. Voir dans void LCD_Write_CString_v2(char *msg), le while(*(msg + k) > 0).
float_to_ASCII_with_2_decimal_v7(sec, txt);
LCD_CString_Position_v2(2, 0, txt); // Write txt in 2nd row, starting at 1st digit.
LCD_CString_Position_v2(2, 13, "uS"); // Write "uS" in 2nd row, starting at 14th digit
Delay_us(1);
//Delay_ms(1000);
}
portc.b2 = 0; // LED yellow OFF.
portc.b3 = 1; // LED green ON.
portc.b4 = 1; // BUZZER ON.
Delay_ms(5000);
portc.b3 = 0; // LED green OFF.
portc.b4 = 0; // BUZZER OFF.
}
}