对于 8 位 MCU,用 C 语言进行除法运算最快的方法是什么?

发布于 2024-08-30 17:39:48 字数 442 浏览 8 评论 0原文

我正在为使用 8 位 MCU(8051 架构)的设备开发固件。我正在使用 SDCC(小型设备 C 编译器)。我有一个函数用于设置电路驱动的步进电机的速度。通过将所需值加载到定时器的重载寄存器中来设置速度。我有一个变量 MotorSpeed,其范围为 0 到 1200,表示电机每秒的脉冲数。我将 MotorSpeed 转换为正确的 16 位重载值的函数如下所示。我知道浮点运算非常慢,我想知道是否有更快的方法......

void SetSpeed()
{
    float t = MotorSpeed;
    unsigned int j = 0;
    t = 1/t ;
    t = t / 0.000001;
    j = MaxInt - t;
    TMR3RL = j;      // Set reload register for desired freq
    return;
}

I am working on the firmware for a device that uses an 8bit mcu (8051 architecture). I am using SDCC (Small Device C Compiler). I have a function that I use to set the speed of a stepper motor that my circuit is driving. The speed is set by loading a desired value into the reload register for a timer. I have a variable, MotorSpeed that is in the range of 0 to 1200 which represents pulses per second to the motor. My function to convert MotorSpeed to the correct 16bit reload value is shown below. I know that float point operations are pretty slow and I am wondering if there is a faster way of doing this...

void SetSpeed()
{
    float t = MotorSpeed;
    unsigned int j = 0;
    t = 1/t ;
    t = t / 0.000001;
    j = MaxInt - t;
    TMR3RL = j;      // Set reload register for desired freq
    return;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黒涩兲箜 2024-09-06 17:39:48

如果我理解正确的话,您想要计算表达式

MaxInt - 1000000/MotorSpeed

,其中 MotorSpeed 是 0 到 1200 之间的数字,表示每秒的脉冲数。

如果您的编译器支持浮点运算,它必须支持整数除法。你为什么不尝试一下呢。如果速度> 15 没有问题,但对于 0 到 15 范围内的速度,结果为负。这意味着如果计数器是 16 位宽并且以 1MHz 的速率递增,则根本不可能生成频率低于 16 Hz 的脉冲。您是否有额外的预分频器可以降低增量频率? (我不知道8051)。

If I understand correctly what's going on You want to calculate the expression

MaxInt - 1000000/MotorSpeed

where MotorSpeed is a number form 0 to 1200 and represents number of pulses per second.

If Your compiler supports floating point arithmetic it must support integer division. Why don't You try that. If the speed is > 15 There is no problem, but for speeds in the range 0 to 15 the result is negative. It means that it's simply impossible to generate pulses with lower frequency than 16 Hz, if the counter is 16 bit wide and it's incremented at the rate of 1MHz. Do you have an additional prescaler that allows to reduce the frequency of increments? (I don't know 8051).

榕城若虚 2024-09-06 17:39:48

经典的方法是使用定点,在除法之前按比例放大,并将其全部作为整数进行。

j = (MotorSpeed * 65536) / 1200;

这仍然需要实际除法(除以 1200),但至少是全整数。缩放应该非常快,因为可以使用移位来实现。

The classic way is to use fixed-point, by scaling up before dividing, and doing it all as integer.

j = (MotorSpeed * 65536) / 1200;

This still requires actual division (by 1200), but at least it's all-integer. The scaling should be very quick, since it's possible to implement using a shift.

最终幸福 2024-09-06 17:39:48

unwind 关于定点是正确的。

我在 8051 上为 SDCC 编写了一个使用 32 位数字的固定库。只需确定您想要的分数精度,并对值应用适当的移位即可。

例如,我的定点库使用 2 个字节作为小数空间。

因此每个数字 x 都表示为 x * 65535。您可以使用正常的有符号长加法和减法。

对于乘法和除法,您需要调整偏移量。简单的乘法将得到(x * 65535) * (y * 65535)。只需分解并分解出数字每个部分的偏移量并将它们全部相加即可。

只需将定点数分解为字节或 16 位整数,然后分段处理它们即可。

请查看embedded.com 上的这篇文章

unwind is right about fixed point.

I wrote a fixed library for SDCC on the 8051 that uses 32 bit numbers. Simply determine what precision you want in your fractions and apply the appropriate shift to the values.

For example, my fixed point library uses 2 bytes for fractional space.

So each number x is represented as x * 65535. You can use normal signed long addition and subraction.

For multiplication and division you need to adjust for the offset. Simple multiplication would give (x * 65535) * (y * 65535). Just break up and factor out the offset for each part of the numbers and add them all up.

Just break up your fixed point number into bytes or 16 bit ints and work on them in pieces.

Take a look at this article on embedded.com.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文