Converting to ASCII in C

前端 未结 9 1769
温柔的废话
温柔的废话 2021-01-05 07:26

Using a microcontroller (PIC18F4580), I need to collect data and send it to an SD card for later analysis. The data it collects will have values between 0 and 1023, or 0x0 a

9条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-05 08:04

    I've replaced my previous answer with a better one. This code creates a 4-character string in the proper order, most significant digit in output[0] to least significant in output[3] with a zero terminator in output[4]. I don't know anything about your PIC controller or C compiler, but this code doesn't require anything more than 16-bit integers, addition/subtraction, and shifting.

    int x;
    char output[5];
    output[4] = 0;
    x = 1023;
    output[3] = '0' + DivideByTenReturnRemainder(&x);
    output[2] = '0' + DivideByTenReturnRemainder(&x);
    output[1] = '0' + DivideByTenReturnRemainder(&x);
    output[0] = '0' + x;
    

    The key to this is the magical function DivideByTenReturnRemainder. Without using division explicitly it's still possible to divide by powers of 2 by shifting right; the problem is that 10 isn't a power of 2. I've sidestepped that problem by multiplying the value by 25.625 before dividing by 256, letting integer truncation round down to the proper value. Why 25.625? Because it's easily represented by powers of 2. 25.625 = 16 + 8 + 1 + 1/2 + 1/8. Again, multiplying by 1/2 is the same as shifting right one bit, and multiplying by 1/8 is shifting right by 3 bits. To get the remainder, multiply the result by 10 (8+2) and subtract it from the original value.

    int DivideByTenReturnRemainder(int * p)
    {
        /* This code has been tested for an input range of 0 to 1023. */
        int x;
        x = *p;
        *p = ((x << 4) + (x << 3) + x + (x >> 1) + (x >> 3)) >> 8;
        return x - ((*p << 3) + (*p << 1));
    }
    

提交回复
热议问题