GameCounter/Source/lib/ssd1306xled/num2str.c
Mark van Renswoude b20ce09a2c Initial commit
OLED worked, displaying large digits worked, reading VCC level worked, started refactoring. Does not currently build, but I'm too tired to figure it out right now.
2017-08-01 23:29:57 +02:00

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;
}
// ============================================================================