我对如何解决这个问题感到非常迷茫,它应该很简单。我正在使用 pic16F1526,并尝试将模拟到数字读数大致从 0-255 缩放到 50-100。我正在使用这个等式
结果 = ((user_input + 200) * 200)/800;
在代码块和我的计算器上,它适用于 0-255 之间的所有数字,无论我在代码组中使用 8 位、16 位变量,它都能完美运行。我已经验证了 AtoD 输入是否正常工作,将数据发送到 UART。即使我输入静态数字代替样本,我也得到奇怪的结果。
当 acd 读取 255 或我输入 255 时,等式会给我一个十进制的 31,而不是预期的 100。我唯一能想到的是,8位PIC的数学方式变得混乱,因为它有点微。
听起来您在 codeblack 中获得了正确的结果,因为整数提升,并且由于变量溢出而在硬件中获得了不正确的结果。
- uint8_t 可以包含 0 到 255
- int8_t 可以包含 -126 125
- uint16_t 可以包含 0 到 65635
- 。
假设你有uint16_t,微观的数学将如下:
-
((255 + 200) * 200) / 800
-
(455 * 200) / 800
:455 * 200
溢出 16 位变量! -
( 25464 ) / 800
: 请注意91000 & 0xFFFF == 25464
-
31
您可以通过简化公式来解决此问题: (user_input + 200) / 4
相当于((user_input + 200) * 200) / 800
,不会在16位时溢出,尽管您的精度不是很高,正如ImaginaryHuman072889指出的那样。
如果我正确理解您的问题,您希望将数字 0-255 线性映射到数字 50-100。
回到古老的代数y = mx + b
。
当x = 0
时,y = 50
.因此:
y = mx + b
50 = m*0 + b
b = 50
当x = 255
时,y = 100
.因此:
y = mx + 50
100 = m*255 +50
m*255 = 50
m = 50/255 = 10/51
因此,准确的答案是:
y = (10/51)*x + 50
附带说明一下,我不知道您在将100
插入公式时是如何获得31
的结果的。见下文。
(255+200)*200/800 = 113.75