当前位置: 首页 > news >正文

32位 DMIC 数据 其中高八位为符号位扩展位的理解

核心概念分解
DMIC 的有效数据位宽 (通常为 24 位):

现代数字麦克风(尤其是 PDM 或 I²S 接口的高精度麦克风)的核心 ADC 通常是 24 位 精度的。这意味着它们能产生从 -8388608 到 +8388607 (-2²³ 到 +(2²³ - 1)) 的原始采样值。

32 位传输宽度的原因:

微控制器、DSP 或音频编解码器的数据总线或 FIFO 通常是 32 位 对齐的(或者 32 位操作更高效)。

为了简化硬件设计和数据传输,将 24 位有效数据放入一个 32 位 的“容器”中进行传输是常见的做法。

符号扩展 (Sign Extension):

符号扩展是处理 有符号整数 时,当需要将其放入一个更宽位宽的容器中,同时 保持其数值不变 的标准方法。

规则:将原始数据的 最高位(符号位) 复制到新容器中所有新增的高位上。

目的:

保持数值正确性:确保扩展后的 32 位数值与原始 24 位数值代表的十进制数完全相同。这对于负数和正数的边界值尤其重要。

简化硬件处理:CPU/DSP 可以像处理原生 32 位有符号整数一样直接处理这些数据,无需在软件中额外进行移位或掩码操作来调整符号(大部分硬件指令自动处理符号扩展)。

“32位数据,高8位为符号扩展”的含义
32 位数据 (DATA[31:0]):指的是从 DMIC 接收或通过接口(如 I²S)传输过来的完整 32 位数据字。

高 8 位 (DATA[31:24]):指的是这个 32 位数据字的最高 8 位 (Bit 31 到 Bit 24)。

符号扩展:这高 8 位的值 不是 新的信息或额外的精度,而是 由原始 24 位有效数据的最高位(Bit 23)复制而来 的。

具体结构解析
假设我们有一个 24 位的有符号采样值 S[23:0](S[23] 是符号位,S[22:0] 是数值位)。

原始 24 位数据: S[23] S[22] S[21] … S[1] S[0]

扩展到 32 位后的数据:

DATA[31:24] (高 8 位): S[23] S[23] S[23] S[23] S[23] S[23] S[23] S[23] (即符号位 S[23] 被复制了 8 次)

DATA[23:16]: S[23] S[22] S[21] S[20] S[19] S[18] S[17] S[16] (原始最高字节)

DATA[15:8]: S[15] S[14] S[13] S[12] S[11] S[10] S[9] S[8]

DATA[7:0] (低 8 位): S[7] S[6] S[5] S[4] S[3] S[2] S[1] S[0]

总结 32 位数据字的结构:
DATA[31:0] = { {8{S[23]}}, S[23:0] }

{8{S[23]}}:表示将 S[23] 重复 8 次,构成高 8 位 (DATA[31:24])。

S[23:0]:原始的 24 位有效数据,占据低 24 位 (DATA[23:0])。

为什么需要这样理解?(实际意义)
直接当作 32 位有符号整数使用:

当你的程序(C/C++等)读取这个 32 位数据并存储到一个 int32_t (或 s32) 类型的变量时,这个变量的值 自动地、正确地 就等于原始 24 位采样值的数值。

无需手动移位或掩码:因为高 8 位是符号扩展,符合 CPU/DSP 对有符号整数的存储和处理规则。例如:

c
int32_t raw_sample = ((volatile int32_t)&dmic_data_register); // 直接读取
float sample_voltage = (float)raw_sample / (1 << 23); // 直接转换为浮点电压 (假设满量程对应 2²³)
这个 raw_sample 的值就是正确的 -8388608 到 +8388607。

忽略高 8 位的具体值:

你不需要关心 DATA[31:24] 里面具体是 0xFF 还是 0x00 或者其他值。它们只是原始符号位 S[23] 的副本,没有提供新的信息。真正有用的数据在 DATA[23:0],并且它已经通过符号扩展准备好被当作 32 位整数使用了。

区分于零扩展 (Zero Extension):

如果高 8 位是用 0 填充(零扩展),那么对于负数(S[23] = 1),直接当作 32 位整数解读会得到一个巨大的正数,结果是错误的。符号扩展避免了这个问题。

图示示例
示例 1:正数 (小值)

原始 24 位: 0x000123 (十六进制,十进制值为 291)

符号位 S[23] = 0

32 位符号扩展后: 0x00000123 (高 8 位是 0x00, 值仍是 291)

示例 2:正数 (边界值,最大值)

原始 24 位: 0x7FFFFF (十六进制,十进制值为 8388607)

符号位 S[23] = 0

32 位符号扩展后: 0x007FFFFF (高 8 位是 0x00, 值仍是 8388607)

示例 3:负数 (小值)

原始 24 位: 0xFFFFFD (十六进制,二进制补码,十进制值为 -3)

符号位 S[23] = 1

32 位符号扩展后: 0xFFFFFFFD (高 8 位是 0xFF, 值仍是 -3)

示例 4:负数 (边界值,最小值)

原始 24 位: 0x800000 (十六进制,二进制补码,十进制值为 -8388608)

符号位 S[23] = 1

32 位符号扩展后: 0xFF800000 (高 8 位是 0xFF, 值仍是 -8388608)

结论
“32位DMIC数据,高8位为符号扩展”意味着:

这 32 位数据包含一个实际有效的 24 位有符号音频采样值。

低 24 位 (DATA[23:0]) 存储了这个原始采样值。

高 8 位 (DATA[31:24]) 不是独立的数据,而是原始 24 位数据最高位(符号位)的 8 份拷贝。

这样做的目的是让整个 32 位数据 可以直接当作一个标准的 32 位有符号整数 (int32_t) 来使用和处理,其数值完全等同于原始的 24 位采样值,无需额外的位操作来修正符号。在编程时,直接读取到 int32_t 变量中即可得到正确的数值

http://www.dtcms.com/a/284794.html

相关文章:

  • git merge-base查看某个分支从哪里拉出来的、主main分支上的某个时间之后某人的提交合并到特定分支(使用 cherry-pick 的场景)
  • 研发知识系统选型实战:从 Notion 到 Gitee Wiki 的迭代经验
  • Python中with的作用和用法
  • 前端之HTML学习
  • Python可迭代对象与迭代器详解 - 深入理解Python迭代机制
  • DolphinScheduler 如何高效调度 AnalyticDB on Spark 作业?
  • 【C语言】动态内存管理全解析:malloc、calloc、realloc与free的正确使用
  • AR技术赋能石化巡检:安全高效新引擎
  • linux-SSH
  • 2025年广东食品生产高级证考试题
  • Python特殊方法完全指南 | 掌握魔术方法提升编程能力
  • 性能监控(一)性能监控核心概念、核心指标
  • SGMD辛几何模态分解 直接替换Excel运行包含频谱图相关系数图 Matlab语言!
  • 藏语识别技术:让古老智慧触手可及的AI突破
  • 前缀和题目:表现良好的最长时间段
  • 快慢指针的应用
  • 5种禁止用户复制的实用方案
  • C++网络编程 4.UDP套接字(socket)编程示例程序
  • UNISOC8850平台Log工具使用说明
  • 基于python和neo4j构建知识图谱医药问答系统
  • Cursor开发步骤
  • 大模型狂想曲:当AI学会“思考”,世界如何被重塑?
  • 用aws下载NOAA的MB文件
  • 【LeetCode 热题 100】230. 二叉搜索树中第 K 小的元素——中序遍历
  • 基于邻域统计分析的点云去噪方法
  • C++ 回调函数全面指南:从基础到高级应用场景实战
  • Junit5
  • 分区表设计:历史数据归档与查询加速
  • ffmpeg转dav为mp4
  • FFmpeg 直播推流