11位转14位数据缩放实现方案求评估:含特殊位格式处理
11位转14位数据缩放与字节拆分实现优化
需求与格式说明
- 输入:两个字节,可组合为11位无符号有效数
- MSB字节:
XXXXNNNN(位7-4无效,位3-0为有效位,共4位) - LSB字节:
XNNNNNNN(位7无效,位6-0为有效位,共7位)
- MSB字节:
- 输出:缩放为14位后拆分为两个字节,每个字节仅位6-0有效(位7无效)
- MSB字节:
XNNNNNNN(位6-0对应14位值的高7位) - LSB字节:
XNNNNNNN(位6-0对应14位值的低7位),且LSB需先放入发送缓冲区
- MSB字节:
原代码问题分析
LSB有效位提取错误
原代码中LSB_Temp = (RX_Data[2] <<1) | (RX_Data[2] >>1)是循环移位操作,会破坏原有效位的顺序,正确做法应直接提取低7位有效位。11位有效数组合错误
原代码直接将MSB字节左移8位后与LSB_Temp拼接,未考虑MSB仅低4位有效,导致有效位位置错误,无法正确组合出11位数值。缩放逻辑错误
原代码用(FullVal <<3)|(FullVal>>3)实现缩放,这是错误的位拼接操作,并非11位到14位的线性缩放。正确的线性缩放应将11位最大值(2047)映射到14位最大值(16383)。输出字节拆分错误
原代码提取MSB时未限制为7位有效位,会导致无效位(位7)被错误赋值,不符合输出格式要求。
优化后的实现代码
uint16_t input_11bit = 0; uint16_t output_14bit = 0; uint8_t tx_lsb = 0; uint8_t tx_msb = 0; // 提取输入字节的有效位 uint8_t msb_valid = Msg_Buff[Buff_Tail_Indx].RX_Data[1] & 0x0F; // 取MSB低4位有效位 uint8_t lsb_valid = Msg_Buff[Buff_Tail_Indx].RX_Data[2] & 0x7F; // 取LSB低7位有效位 // 组合成11位无符号数 input_11bit = (uint16_t)msb_valid << 7 | lsb_valid; // 11位缩放为14位:线性映射,精确版 output_14bit = (uint16_t)((uint32_t)input_11bit * 16383) / 2047; // 若允许近似(误差极小,最大误差7),可简化为左移3位:output_14bit = input_11bit << 3; // 拆分14位为两个7位有效字节 tx_lsb = output_14bit & 0x7F; // 低7位作为输出LSB tx_msb = (output_14bit >> 7) & 0x7F;// 高7位作为输出MSB // 放入发送缓冲区(LSB先放) TX_Data[1] = tx_lsb; TX_Data[2] = tx_msb;
说明
- 精确缩放使用
(input_11bit * 16383) / 2047,其中16383=2^14-1,2047=2^11-1,确保输入最小值0对应输出0,输入最大值2047对应输出16383。 - 近似缩放用左移3位(
input_11bit <<3),计算更快,最大误差仅7,多数场景可接受。 - 所有操作均确保有效位正确提取,无效位被屏蔽,符合输入输出格式要求。
内容的提问来源于stack exchange,提问作者nobby
相关产品推荐
相关产品推荐

