【发布时间】:2015-03-02 10:29:41
【问题描述】:
我正在用 C 语言为小型 8 位微控制器编写软件。部分代码是读取电流互感器 (ZCT) 的 ADC 值,然后计算 RMS 值。流过 ZCT 的电流是正弦的,但它可能会失真。我的代码如下:
float adc_value, inst_current;
float acc_load_current; // accumulator = (I1*I1 + I2*I2 + ... + In*In)
double rms_current;
// Calculate the real instantanous value from the ADC reading
inst_current = (adc_value/1024)*2.5; // 10bit ADC, Voltage ref. 2.5V, so formula is: x=(adc/1024)*2.5V
// Update the RMS value with the new instananous value:
// Substract 1 sample from the accumulator (sample size is 512, so divide accumulator by 512 and substract it from the accumulator)
acc_load_current -= (acc_load_current / 512);
inst_current *= inst_current; // square the instantanous current
acc_load_current += inst_current; // Add it to the accumulator
rms_current = (acc_load_current / 512); // Get the mean square value. (sample size is 512)
rms_current = sqrt(rms_current); // Get RMS value
// Now the < rms_current > is the real RMS current
但是,它有很多浮点计算。这给我的小型MCU增加了很大的负担。而且我发现sqrt() 函数在我的编译器中不起作用。
有没有可以运行得更快的代码?
【问题讨论】:
-
它需要多准确(你能找到峰值然后做
RMS = peak_adc_value/1024*2.5*0.707)吗? -
由于您似乎使用滑动窗口平均值(样本之间没有太大变化),您可以通过一步 Newton-Ralfston 实现 sqrt(),使用旧的 sqrt 作为起始值。
-
一般使用查找表来存储平方根,而不是计算平方根。(在资源匮乏的环境中访问更快)
-
@Vagish 查找表意味着二进制搜索,即 O(log N)。 Newton-Ralfston 在 4 或 5 次迭代中收敛(但具有更大的大 O)
-
@joop,对不起,我的意思是查找表是指存储在 ROM 中的简单数组。
标签: c performance algorithm microcontroller