c - 将由 16 位和 32 位变量组成的 48 位数字相除

标签 c embedded

我正在为嵌入式微 Controller (STN1110) 开发软件。它没有 FPU 或 SFP 仿真。

有一个 SDK 方法可以返回 Controller 的正常运行时间(以微秒为单位),分为两个变量:uint16 (msw) 和 uint32 (lsw)。

我想将此“对”转换为具有秒精度的单个 uint32 (/1000/1000)。

SDK API 文档声明如下:

uint32 TimeGet48 (uint16 * time_msw)
-----------------------------------------   
Read the current full 48-bit system time.

Returns all 48 bits of the current value of the system's 1MHz clock. The resolution of the returned 32 bit value is one microsecond, with the most significant word returned through the pointer passed as a parameter. The clock therefore wraps after approximately 8.9 years. That should be enough for most purposes.

Parameters:
- time_msw: A pointer to store the most significant word of the current system time
Returns:
- Lower 32 bits to the current system time.

这里的主要问题是, Controller 最多仅支持uint32,因此不支持uint64

我将一些我认为可能是解决方案的代码“粘合”在一起。事实并非如此,因为一旦 uint16 值 > 0 就会出现错误,而且我无法找到它。

uint32 divide(uint32 time_in_us_lsb, uint16 time_in_us_msb, uint32 divisor)
{
    uint32 value1 = (uint32)time_in_us_msb & 0xFFFF;
    uint32 value2 = (uint32)(time_in_us_lsb >> 16) & 0xFFFF;
    uint32 value3 = (uint32)time_in_us_lsb & 0xFFFF;

    value2 += (value1 % divisor) << 16;
    value3 += (value2 % divisor) << 16;

    return (((value2 / divisor) << 16) & 0xFFFF0000) | ( value3 / divisor);
}

uint32 getUptimeSeconds() {
    uint32 time_in_us_lsb;
    uint16 time_in_us_msb;

    time_in_us_lsb = TimeGet48(&time_in_us_msb);   
    uint32 result = divide(time_in_us_lsb, time_in_us_msb, 100000);

    time_in_us_lsb = (uint32)result & 0xFFFFFFFF;
    time_in_us_msb = 0;

    return divide(time_in_us_lsb, time_in_us_msb, 10); 
}

注意:速度在​​这里不是问题,因为该函数在应用程序生命周期内不会经常调用。

编辑:添加了uint32 功能限制。

最佳答案

.. there are errors as soon as the uint16 value is > 0 and I'm not able to find it.

至少出现一个错误“ Controller 的正常运行时间(以微秒为单位)”

// uint32 result = divide(time_in_ms_lsb, time_in_ms_msb, 100000);
uint32 result    = divide(time_in_ms_lsb, time_in_ms_msb, 1000000);

简单地使用uint64_t更有意义。

uint32 divide(uint32 time_in_ms_lsb, uint16 time_in_ms_msb, uint32 divisor) {
  uint64_t sum = ((uint64_t)time_in_ms_msb << 32) | divisor;
  return (uint32)(sum / divisor);
}

建议:在微秒代码中使用ms看起来像毫秒。建议我们“μSeconds”。

关于c - 将由 16 位和 32 位变量组成的 48 位数字相除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55514680/

相关文章:

C - 以某种密度填充矩阵

c - DMA在STM32的什么地方存放ADC的值?

gcc - Cortex-M4 和 GCC - float 行为

c++ - 源代码中的 Kdbg pid() 调用

将 C 代码转换为 MIPS(数组)

php - php 扩展崩溃 - 将内存地址转换为行号

c - C中的位设置逻辑

c - 如何消除结构中未使用的元素?

c++ - 在 C++ 中拆分硬件相关类

c - 移动数据 block ——memcpy 还是 memmove?