Question

I need to convert a number to a percentage of my DAC's max value (0x0FFF) so my code to do that would be like this:

double percent;
short pct;

percent = (0x0FFF * pct)/100;

but I need a 16-bit value to send to the DAC not a 32-bit one. What is the quickest way to convert it to a 16-bit number? Can I shift it in?

Était-ce utile?

La solution

There is no need to use floating point for this:

uint16_t val = 0x0fffU * pct / 100U; // convert 0..100 value to 0..4095

Autres conseils

If your percentage has just 101 values from 0-100 then it's much faster to use a lookup table than doing multiplication/division, especially in microcontrollers where hardware mul/div instructions are not available.

Most MCUs have plenty of flash/EEPROM available but lack of RAM so the table can just be saved in ROM. Reading the table from ROM is probably slower than from RAM but still a lot faster than doing a division. However some MCUs have long reading cycles so you may need to prefetch or load the table into RAM if there's enough, or simply use the multiply-and-divide method above. You can also pack the table (because you only need 12 bits) or doing other tricks

#define PCT(n) (0x0fffU * (n) / 100U)

#define PCTROW(n) (PCT(10*n),   PCT(10*n+1), PCT(10*n+2), PCT(10*n+3), PCT(10*n+4),\
                   PCT(10*n+5), PCT(10*n+6), PCT(10*n+7), PCT(10*n+8), PCT(10*n+9))

const uint16_t percent_tbl[] = {
    PCTROW(0), PCTROW(1), PCTROW(2), PCTROW(3), PCTROW(4),
    PCTROW(5), PCTROW(6), PCTROW(7), PCTROW(8), PCTROW(9), 0x0fffU
}

return percent_tbl[pct];
uint16_t percent;
uint16_t pct;

percent = (0x0FFFU * pct)/100U; //Gives you in unsigned 16 number.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top