数学函数作为二元运算

时间:2013-06-23 19:05:33

标签: c binary formula microcontroller

我有一个连接到ATmega微控制器的MP3板,它还连接到电位器。 MP3板直接通过板载扬声器播放MP3数据,因此我也可以设置输出音量。

因此,正如您可能猜到的那样,我从poti中读取值并将其转发给微控制器。不幸的是,微控制器不会以线性方式增加音量。因此,从0到128,您几乎听不到任何声音,从128到255(最大),音量会迅速增加。

我发现,以下功能可以解决这个问题:

vol = 1 - (1 - x)^4

但x必须介于0和1之间,结果也介于0和1之间。

由于我在微控制器上,我想

  1. 转换此公式,以便我可以将它与无符号整数一起使用
  2. 优化它(可能使用一些廉价的二进制函数),因为我每秒多次读取poti值。所以这个函数必须每秒计算多次,我也想把微控制器用于其他东西; - )
  3. 也许有些人有想法?太棒了!

     uint8_t linearize_volume(uint8_t value) {
         // ideas?
         // please don't use bigger data types than uint16_t
     }
    

3 个答案:

答案 0 :(得分:3)

您可以为CPU周期“支付”内存。如果您有256字节的ROM可用,那么计算此类函数的最便宜的方法是构建查找表。

创建一个程序,打印256个8位数字的列表,其中包含非线性函数的值。程序的速度并不重要,因为你只运行一次。将程序打印的数字作为数组初始化程序复制到C程序中,然后执行查找而不是计算函数。

答案 1 :(得分:1)

你可以通过将值视为8.8定点并通过平方两次提高到4的幂来得到合理的估计。

uint8_t linearize_volume(uint8_t value) {
    // Approximate 255 * (1 - (1 - x/255)^4)
    uint16_t x = 0xff - value;
    x = (x * x) >> 8;
    x = (x * x) >> 8;
    return 0xff - x;
}

答案 2 :(得分:0)

首先,请确保您使用的是线性锅,而不是音频锥形锅。

这是典型的音频输出。数据是正弦波,因此负值是必要的。您当然可以将负片转换为正片,仅用于访问其功率级别,但如果没有听到完全不同的声音,则无法更改样品。

根据输出设备的不同,较低的值可能无法提供足够的功率来为扬声器充电。

“MP3板”应包括控制音量的功能,而无需更改样品。

你说你读了锅并将它转发给微型。你不是在用micro的ADC读锅吗?