115 lines
4.0 KiB
C
115 lines
4.0 KiB
C
|
/**
|
||
|
* NUM2STR - Functions to handle the conversion of numeric vales to strings.
|
||
|
*
|
||
|
* @created 2014-12-18
|
||
|
* @author Neven Boyanov
|
||
|
* @version 2016-04-17 (last modified)
|
||
|
*
|
||
|
* This is part of the Tinusaur/TinyAVRLib project.
|
||
|
*
|
||
|
* Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved.
|
||
|
* Distributed as open source software under MIT License, see LICENSE.txt file.
|
||
|
* Please, as a favor, retain the link http://tinusaur.org to The Tinusaur Project.
|
||
|
*
|
||
|
* Source code available at: https://bitbucket.org/tinusaur/tinyavrlib
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
// ============================================================================
|
||
|
|
||
|
#include "num2str.h"
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
// NOTE: This implementation is borrowed from the LCDDDD library.
|
||
|
// Original source code at: https://bitbucket.org/boyanov/avr/src/default/lcdddd/src/lcdddd/lcdddd.h
|
||
|
|
||
|
uint8_t usint2decascii(uint16_t num, char *buffer)
|
||
|
{
|
||
|
const unsigned short powers[] = { 10000u, 1000u, 100u, 10u, 1u }; // The "const unsigned short" combination gives shortest code.
|
||
|
char digit; // "digit" is stored in a char array, so it should be of type char.
|
||
|
uint8_t digits = USINT2DECASCII_MAX_DIGITS - 1;
|
||
|
for (uint8_t pos = 0; pos < 5; pos++) // "pos" is index in array, so should be of type int.
|
||
|
{
|
||
|
digit = 0;
|
||
|
while (num >= powers[pos])
|
||
|
{
|
||
|
digit++;
|
||
|
num -= powers[pos];
|
||
|
}
|
||
|
|
||
|
// ---- CHOOSE (1), (2) or (3) ----
|
||
|
|
||
|
// CHOICE (1) Fixed width, zero padded result.
|
||
|
/*
|
||
|
buffer[pos] = digit + '0'; // Convert to ASCII
|
||
|
*/
|
||
|
|
||
|
// CHOICE (2) Fixed width, zero padded result, digits offset.
|
||
|
/*
|
||
|
buffer[pos] = digit + '0'; // Convert to ASCII
|
||
|
// Note: Determines the offset of the first significant digit.
|
||
|
if (digits == -1 && digit != 0) digits = pos;
|
||
|
// Note: Could be used for variable width, not padded, left aligned result.
|
||
|
*/
|
||
|
|
||
|
// CHOICE (3) Fixed width, space (or anything else) padded result, digits offset.
|
||
|
// Note: Determines the offset of the first significant digit.
|
||
|
// Note: Could be used for variable width, not padded, left aligned result.
|
||
|
if (digits == USINT2DECASCII_MAX_DIGITS - 1)
|
||
|
{
|
||
|
if (digit == 0)
|
||
|
{
|
||
|
if (pos < USINT2DECASCII_MAX_DIGITS - 1) // Check position, so single "0" will be handled properly.
|
||
|
digit = -16; // Use: "-16" for space (' '), "-3" for dash/minus ('-'), "0" for zero ('0'), etc. ...
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
digits = pos;
|
||
|
}
|
||
|
}
|
||
|
buffer[pos] = digit + '0'; // Convert to ASCII
|
||
|
|
||
|
}
|
||
|
|
||
|
// NOTE: The resulting ascii text should not be terminated with '\0' here.
|
||
|
// The provided buffer maybe part of a larger text in both directions.
|
||
|
|
||
|
return digits;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
// NOTE: The buffer should be always at least MAX_DIGITS in length - the function works with 16-bit numbers.
|
||
|
|
||
|
uint8_t usint2binascii(uint16_t num, char *buffer) {
|
||
|
uint16_t power = 0x8000; // This is the 1000 0000 0000 0000 binary number.
|
||
|
char digit; // "digit" is stored in a char array, so it should be of type char.
|
||
|
uint8_t digits = USINT2BINASCII_MAX_DIGITS - 1;
|
||
|
for (uint8_t pos = 0; pos < USINT2BINASCII_MAX_DIGITS; pos++) { // "pos" is index in an array.
|
||
|
digit = 0;
|
||
|
if (num >= power) {
|
||
|
digit++;
|
||
|
num -= power;
|
||
|
}
|
||
|
// Fixed width, space ('0', or anything else) padded result, digits offset.
|
||
|
// Note: Determines the offset of the first significant digit.
|
||
|
// Note: Could be used for variable width, not padded, left aligned result.
|
||
|
if (digits == USINT2BINASCII_MAX_DIGITS - 1) {
|
||
|
if (digit == 0) {
|
||
|
if (pos < USINT2BINASCII_MAX_DIGITS - 1) // Check position, so single "0" will be handled properly.
|
||
|
digit = 0; // Use: "-16" for space (' '), "-3" for dash/minus ('-'), "0" for zero ('0'), etc.
|
||
|
} else {
|
||
|
digits = pos;
|
||
|
}
|
||
|
}
|
||
|
buffer[pos] = digit + '0'; // Convert to ASCII
|
||
|
power = power >> 1;
|
||
|
}
|
||
|
// NOTE: The resulting ascii text should not be terminated with '\0' here.
|
||
|
// The provided buffer maybe part of a larger text in both directions.
|
||
|
return digits;
|
||
|
}
|
||
|
|
||
|
// ============================================================================
|