模数输入缩放公式适用于代码块,但不适用于微控制器



我对如何解决这个问题感到非常迷茫,它应该很简单。我正在使用 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) / 800455 * 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

最新更新