为什么我在以下代码中没有得到正常结果?
void Motors::setCycleDutyA(int percentage) {
Serial.println(percentage);
Serial.println(pwmCycleDutyA);
float x=percentage/100;
Serial.print(x);
pwmCycleDutyA = int(255*x);
Serial.println(pwmCycleDutyA);
}
当我调用该函数时:
Motors::setCycleDutyA(45);
我得到了这些结果:
45 255 0.000
45 0 0.000
45 0 0.000
我想念什么?
答案 0 :(得分:5)
下面:
float x=percentage/100;
您正在执行整数除法(因为两个操作数都是整数)。这意味着,每当0
小于percentage
时,结果将为100
。这解释了你得到的结果。
将其更改为:
float x=percentage/static_cast<float>(100);
或者:
float x=percentage/100.f;
答案 1 :(得分:3)
问题是float x = percentage / 100
,其中percentage
的类型为int
。这意味着/
的两个参数都是整数,因此执行整数除法。然后,结果将转换为float
。
你想要这个:
float x = percentage / 100.f;
或者只需将percentage
的类型更改为float
。
答案 2 :(得分:1)
对于这种情况,我倾向于避免使用浮点数。控制这样的电机的代码通常在不支持浮点的小型微控制器上运行,因此浮点计算通常在软件中进行仿真,这很慢并且可以添加相当多的额外代码。
因此,我会尝试考虑是否可以在整数数学中完成。看看序列:
float x=percentage/100;
pwmCycleDutyA = int(255*x);
这基本上相当于:
pwbCycleDutyA = percentage * 2.55;
出于很多目的,将其视为percentage * 2.5
就足够了,这在整数数学中很容易呈现:
pwbCycleDutyA = (percentage * 5) / 2;
这会将我们可以生成的值的范围缩小到0..250而不是0..255 - 但请记住,由于百分比从int
开始,我们只能生成100个离散值无论如何,所以很少会产生太大的(如果有的话)差异。
但是,如果您确定乘数确实需要为2.55而不是2.5,那么您也可以这样做。最明显的是简单地重新排列你的等式 - 而不是除以100然后乘以255,先乘以255,再除以100:
pwbCycleDutyA = (percentage * 255) / 100;
重新排列这样的等式时要记住的主要事情是确保防止溢出。假设percentage
永远不会超过100,我们就相当安全 - 中间结果永远不会超过25500
,这很容易适合签名的16位int(C允许的最小值)。