Estoy ayudando a un amigo con un pequeño proyecto de electrónica utilizando un microcontrolador PIC 16F877 (A) que estoy programando con mikroC.
Me encontré con un problema que es que tengo un número de punto flotante en una variable, digamos, por ejemplo, 1234.123456 y necesito dividirlo en variables que contienen cada número individual, así que obtengo Char1 = 1, Char2 = 2, etc. para mostrar en LCD. El número siempre se redondeará a 3 o 4 decimales, por lo que debería ser necesario rastrear la ubicación del punto decimal.
Cualquier consejo sobre cómo obtener esta división sería muy apreciado.
Hay numerosas formas de hacerlo. Puede encontrar que su compilador tiene una función de biblioteca para hacerlo por usted. Puede ser posible con:
Alternativamente, no es muy difícil escribir tu propia rutina para hacerlo. Es solo un caso de primero calcular cuántos dígitos hay antes del punto decimal, dividirlo por 10 esa cantidad de veces, luego tomar la parte entera repetidamente mientras se multiplica por 10, asegurándose de agregar el punto decimal en el lugar correcto.
Entonces, en pseudocódigo, puede verse algo como:
If the value < 0.0:
Insert - into string
Subtract value from 0.0 to make it positive.
While the value <= 10.0:
Divide by 10
Increment decimal counter
For each digit of required precision:
Take the integer portion of the value and place it in the string
Subtract the integer portion from the value
Decrement decimal counter
If decimal counter is 0:
Insert decimal point
Multiply the value by 10.
Usa sprintf(). Funciona igual que printf(), pero "imprime" en una cadena (también conocida como matriz de caracteres).
hacer: char stringvar[10]; sprintf(varcadena, "%9.4f", varflotante);
En una MCU pequeña sin soporte de punto flotante de hardware, deberíamos hacer la menor cantidad posible de matemáticas de punto flotante y, a menos que realmente necesite la familia de funciones printf, intente evitarlo porque infla y ralentiza mucho el código.
Sugiero convertir el flotante en un entero multiplicando primero el flotante por 1,000.0 (asumiendo que desea tres lugares decimales) y luego convertirlo en un entero largo, redondeando según corresponda. Si va a mostrar el resultado en una pantalla LCD de matriz de puntos o de 7 segmentos, creo que este formato es ideal.
Supongamos que el flotante puede estar en el rango de 0 a 999.999 (negar si es negativo, guardar el signo para mostrarlo más tarde). El int largo correspondiente entonces tiene el rango de 0 a 999999. Convertiremos el número comenzando con el dígito más significativo.
Pseudocódigo:
dig6 = -1 // Init MSDigit
while number >= 0
number = number - 100,000
dig6 = dig6 + 1
number = number + 100,000 // Restore number, Dig 6 is done
dig5 = -1
while number >= 0
number = number - 10,000
dig5 = dig5 + 1
number = number + 10,000 // number can be switched to 16-bit here for speed
... dig4 and 3 in similar fashion
dig2 = -1
while number >= 0
number = number - 10
dig2 = dig2 + 1
dig1 = number + 10
En este punto, tiene los seis dígitos almacenados en un byte cada uno y el signo menos guardado. Si está utilizando una pantalla LCD de 7 segmentos, pase los dígitos a una función de codificador de 7 segmentos antes de escribir en la pantalla LCD. Si está utilizando una pantalla de matriz de puntos con interfaz serial, agregue 0x30 a cada dígito para la codificación ASCII. También necesitamos recordar el punto decimal entre dig4 y dig3.
Este algoritmo es bastante rápido ya que no hay multiplicación ni división involucradas. Lo he usado en pequeñas MCU de 4 bits con buenos resultados.
Majenko
pedro bennett
Majenko
austin
Majenko
austin