Я отвечаю на вопрос в ПОСЛЕДНЕМ предложении исходного поста, а не в заголовке. Но это правильный ответ для вашего проекта.
Вы говорите: «Мне нужно только 2 десятичных знака» — так что это должно сказать вам, что нет необходимости в математике с плавающей запятой. Физикам и инженерам нужны числа с плавающей запятой для представления очень, очень маленьких или очень, очень больших величин, но вам нужна «фиксированная точка», что означает выполнение целочисленной математики и правильный выбор единиц измерения. Фиксированная точка быстрее, точнее и уменьшает размер вашего скомпилированного двоичного файла, поскольку нет необходимости в коде с плавающей запятой.
Самое простое решение — использовать целые числа и отображать милливольты, точно так же, как функция delay(), которую вы только что использовали, принимает в качестве аргумента целое число миллисекунд, а не дробное число секунд.
#define VREF 5000
uint32_t mvolts;
.
.
mvolts=(value*VREF)>>10; // No floats here...
lcd_printf("milliVolts: %d",mvolts); // ...and no casts
Если вы должны отображать вольты, то это поможет:
lcd_printf("Volts: %d.%02d ",mvolts/1000, (mvolts%1000)/10);
Заметьте, кстати, что mvolts — это 32-битное целое число, потому что сейчас вы умножаете 10-битное число на 5000, а это не укладывается в 16-битное число. Это необходимо, потому что вам нужно сохранить точность значения при масштабировании. Я не думаю, что это заголовок не по теме, так как я полагаю, что вы хотите отображать правильное значение или нет смысла отображать эти два десятичных знака.
Если вы не будете осторожны, компилятор вычислит значение 5000/1024 — 4,8828125, а затем выполнит целочисленную арифметику, которая отсекает дробную часть и в итоге умножает результат АЦП на 4. Чтобы гарантировать правильное поведение, умножьте на 5000 потом разделить - 2 отдельные операции. Поскольку 1024 равно 2**10, сдвиг вправо на десять битов идентичен делению на 1024.
Наконец, не думайте, что чтение 1023 из АЦП на самом деле означает 5000 вольт с 4 значащими цифрами; откалибруйте проверенный вольтметр, изменив #define VREF
, чтобы получить правильный результат.
person
Peter Lister
schedule
22.11.2016
volts=(value*5)/1023
. Все это целые числа, поэтому результатом вычисления будет целое число. Это, вероятно, не то, что вы хотите. Попробуйте использоватьvolts = (value * 5f) / 1023f
. - person clstrfsck   schedule 21.11.2016unsigned volts=(value*5000L + 1024/2 /* add this value to round */)/1024;
и избегайте математики FP. - person chux - Reinstate Monica   schedule 21.11.2016lcd_printf
, которая, вероятно/возможно, предоставляется какой-то секретной библиотекой. Подробности смотрите там. - person datafiddler   schedule 21.11.2016"Volts: %.2f "
в качестве строки формата, так как.2
заставляет использовать только две десятичные цифры после запятой. - person Luis Colorado   schedule 23.11.2016