【发布时间】:2019-08-26 03:14:36
【问题描述】:
我正在为嵌入式微控制器 (STN1110) 开发软件。它没有 FPU 或 SFP 仿真。
有一个 SDK 方法以微秒为单位返回控制器的正常运行时间,分为两个变量: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.
这里的主要问题是,控制器最多只支持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 功能限制。
【问题讨论】:
-
建议在这样的表达式中添加括号,这样读者就不必考虑运算符优先级:
time_in_ms_lsb >> 16 & 0xFFFF。 -
另外,为什么你的函数定义标记为
extern? -
会这样做的,谢谢你的建议。至于
extern:这是断章取义,但应该与函数本身无关。我会删除它。 -
STN1110 看起来不是微控制器而是协议转换器IC?我在这里错过了什么?
-
如果除数 (value1 / disivor) << 32 会溢出。如果除数 >= 65536 则
value1 % divisor == value1。除此之外,这看起来还可以。哪些输入值会给您错误的结果,您期望得到什么结果?