Convert DS18B20 temperature to string?

I want to convert DS18B20 temperature (4-bytes code from datasheet) to string with accuracy 0.1°C (like sprintf %.1f). AVR. C language (avr-gcc). I need for small code, so sprintf, floating-point types and round from math.h is bad idea. My following current code is bad also:

This is the date sheet of DS18B20

void reverse_string(char *s)
{
    char *p, c;

    for (p = s + strlen(s) - 1; s <= p; ++s, --p) {
        c = *p;
        *p = *s;
        *s = c;
    }
}

void ts_to_string(uint16_t ts, char *s)
{
    int8_t n = (int8_t)(ts >> 4);
    uint8_t neg = n & 0x80;
    char *p = s;
    float f;

    if (neg)
        n = -n-1;
    do {
        *p++ = n % 10 + '0';
    } while ((n /= 10) > 0);

    if (neg)
        *p++ = '-';

    *p = '\0';
    reverse_string(s);
    *p++ = '.';

    f = (float)(ts & 0xf) / 16.0;
    if (neg)
        f = 1.0-f;
    *p++ = (char)round(f * 10.0) + '0';
    *p = '\0';
}

iceng2 months ago

1 in 32768 is better then o.1%

steveastrouk2 months ago

And ?

Do you expect people to read uncommented code ?