c - 在操作受限的微 Controller 上生成对数间隔值

标签 c embedded microcontroller logarithm

我最近遇到一个问题,使用廉价的 16 位 uC(MSP430 系列),我必须根据 10 位 ADC 读取生成对数间隔的输出值。这样做的原因是我需要在整数空间的低端进行细粒度控制,同时要求使用较大的值,尽管精度较低(对我来说,2^15 之间的差异而我的反馈循环中的 2^16 影响不大)。我以前从未这样做过,而且我也没有运气在网上找到示例,所以我想出了一个小方案来在我的操作受限的 uC 上执行此操作。

使用我这里的方法,ADC 结果仅通过整数乘法/加法/求和以及按位移位在两个最接近的整数幂之间进行线性插值(概述如下)。

我的问题是,是否有比这更好的(更快/更少的操作)方法来生成在整数分辨率上以对数间隔排列的平滑(或平滑)数据集?我在网上没有找到任何东西,因此我首先尝试从头开始想出一些东西。

N是微 Controller 的对数分辨率(这里假设为16位)。 M是ADC的整数分辨率(这里假设为10位)。 ADC_READ 是 ADC 在给定时间读取的值。在支持浮点运算的 uC 上,执行此操作很简单:

x = N / M  #16/1024
y = (float) ADC_READ / M   #ADC_READ/1024
result = 2 ^ ( x * y )  

在下面的所有图中,这是“理想”值集。 “结果”值由以下变量生成:

unsigned int returnValue( adcRead ){

    unsigned int e;
    unsigned int a;
    unsigned int rise;
    unsigned int base;
    unsigned int xoffset;
    unsigned int yoffset;

    e = adcRead >> 6;
    a = 1 << e;

    rise = ( 1 << (e + 1) )  - ( 1 << e );
    base = e << 6;

    xoffset = adcRead - base;
    yoffset = ( rise >>  rise_shift ) * (xoffset >> offset_shift);  //this is an operation to prevent rolling over.   rise_shift + offset_shift = M/N, here = 6

    result = a + yoffset;
    return result;
}

额外的声明和不声明的内容仅供阅读。假设最终产品是浓缩的。基本上,它按照预期进行,根据rise_shift 和offset_shift 的值,在低端有不同程度的离散化,在高端有平滑度。这里,它们都等于 3: rise >> 3, offset >> 3 这里rise_shift = 2,offset_shift = 4 rise >> 2, offset >> 4 这里rise_shift = 4,offset_shift = 2 rise >> 4, offset >> 2 我很想看看是否有人想出或知道更好的东西。目前,我只需每秒运行此代码约 20-30 次,因此显然我没有遇到任何延迟。但是,使用 16MHz 时钟并使用 here 中的信息,我估计整个操作最多需要约 110 个时钟周期,或约 7us。这是 ADC 读取时间的尺度,约为 4us。

谢谢

编辑:我所说的“更好”并不一定意味着更快(显然,它已经相当快了)。立即,人们会发现低端对 2 的整数次方具有相当大的离散化,这是由于防止滚动的移位操作造成的。除了查找表(下面建议)之外,如何改进这一问题的答案并不是立竿见影的。

最佳答案

based on the 10 bit ADC read.

该 ADC 只能输出 1024 个不同的值 (0-1023),因此您可以使用 1024 个 16 位值的表,这将消耗 2KB 闪存:

const uint16_t LogarithmicTable[1024] = { 0, 1, ... , 64380};

计算对数输出现在是一个简单的数组访问:

result =  LogarithmicTable[ADC_READ];

您可以使用 Excel 等工具为您生成此表中的常量。

关于c - 在操作受限的微 Controller 上生成对数间隔值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18175373/

相关文章:

arm - 加载符号后 GDB 自动执行命令

embedded - Udacity : Functional Hardware Verification. 有哪些实现?

c - 头指针指向指针

c - HTTP 服务器未将完整文件发送到 WGET、Firefox。连接被对等方重置?

c - 是否调整您的 (u)ints 大小?

c - Proteus 中伺服电机无法正常转动

microcontroller - 使用 Openocd 烧写 nrf52 芯片的问题

c - 函数 'saving progress' 的问题

c - 将char插入char数组C(string)

microcontroller - i2c 协议(protocol) NACK 歧义