2013-03-13 6 views
0

Извините, немного попытался придумать название.Возьмите линейный вход, преобразуйте в геометрическую последовательность и округлите?

В принципе, у меня есть фрагмент кода, который считывает значение из компаратора на моей встроенной плате (8051). Это будет значение от 0 до 255, где 0 равно 0 В, а 255 - 5 В.

Мне нужно вывести эти значения в набор из восьми светодиодов, каждый из которых назначается бит на переменной P1, с возможностью чтения человеком (IE, как измеритель уровня). Следовательно, входное значение должно быть округлено так, чтобы что-либо от 16 до 32 выводилось как 1, 33 - 48 как 2, от 49 до 80 как 4, от 81 до 112 как 8 и т. Д.

Мое единственное решение, которое я знаю будет работать до сих пор - строка инструкций if-else, но я получил два слоя, прежде чем осознать, что это просто не собирается сокращать его.

Кто-нибудь знает, как это осуществить? Мой мозг превратился в мушню, пытаясь понять, как это сделать математически.

Спасибо! Joe

EDIT: сделайте снимок моих расчетов, я надеюсь, что это станет более понятным. http://i.imgur.com/r3n8Ila.png

+0

Я не понимаю, почему вы должны 42+ быть преобразованы в 2. В каком порядке вы хотите, чтобы осветить светодиодов в зависимости от напряжения? – Aneri

+0

Первый светодиод должен загореться, когда напряжение проходит 6,25% от общего количества, второе - 18,75%, третье - 31,25. Я только заметил, что я испортил свои расчеты, поэтому я сделаю их снова. Чтобы зажечь светодиоды (которые являются обратной логикой), я просто добавляю P1 = a ;, где a - 8 бит int. Например, для освещения только msb требуется равное 0xF7h. –

+0

Итак, какие значения вам нужны? 0 -> 0, 33 ->, 65 ->, 97 ->, ... – Aneri

ответ

0
#include <stdio.h> 

int round8values(int inputVoltage) 
{ 
    return 1 + inputVoltage/32 ; 
} 

int main(void) 
{ 
    printf("31 goes to : %d \n", round8values(31)); 
    printf("31 goes to : %d \n", round8values(42)); 
    printf("31 goes to : %d \n", round8values(64)); 
    return 0; 
} 
0

Хорошо, для этого нового списка значений, вам с плавающей точкой арифметика, как

int bitno = (trunc(1 + (val/255.0 - 0.0625)/0.125)); 

Или вы можете обмануть и перейти к ИНТ арифметики с достаточной точностью:

int bitno = ((val*31372 + 515000)/1000000); 

Для такой операции вам понадобится как минимум 24-битный intigned для работы без переполнения.

После того, как вы рассчитали немного вам нужно, установить его:

int LEDval = bitno == 0 ? 0 : 1 << (bitno - 1); 

Или, чтобы избежать троичной операции

int LEDval = 0; 
if (bitno) LEDval = 1 << (bitno - 1); 
1

Я думаю математическую формулу, которая довольно точно соответствует Вашим данным могут быть

BitNumber = floor(voltage/32 + 1/2) 

где пол - это ближайшее целое число, меньшее вашего результата.

Это также может быть записана в виде

BitNumber = round(voltage/32)