找回密码
 立即注册
查看: 26|回复: 5

SPI_DMA接收到的数据能否直接读取 | 已解决

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-10-21 10:01:54
已绑定手机

2

主题

7

回帖

50

积分

注册会员

积分
50
发表于 昨天 10:01 | 显示全部楼层 |阅读模式
一个很有意思的现象:

截图202510210953073159.jpg

我用spi的dma先读取了200个字节,判断wav的前四个字节,读取是ok的,在不清除缓存的情况下,定义了一个32位的变量,来进行逻辑运算,结果确实错误的。
如下 52 49 46 46是wave前四个字节,验证ok   0 8 9a 24  是大端下的字节长度,我的32位变量应该也是 089a24 。
但是我要是将屏蔽的代码打开,printf的数据就是对的 输出089a24.好奇怪,
截图202510210953399423.jpg

回复

使用道具 举报 送花

3

主题

1861

回帖

570

积分

等待验证会员

积分
570
发表于 昨天 10:03 | 显示全部楼层
你观察到的现象非常典型,涉及了SPI+DMA接收数据后如何正确访问内存数据的问题,尤其是当使用DMA传输后,是否可以直接通过指针或变量访问DMA缓冲区中的数据。

我们来一步步分析你的问题:

一、现象简述

你使用 SPI + DMA 接收了200个字节的数据,其中前几个字节是标准WAV文件的头部信息,例如:
前4字节为 'RIFF'(对应十六进制为 52 49 46 46),验证是正确的。
接下来的4个字节是文件长度,为大端格式(Big-endian):00 08 9A 24,理论上应组合为 0x00089A24。

你尝试用一个32位变量(如 uint32t)来读取这4个字节的数据,结果得到错误值。但当你使用 printf 输出时却得到了正确的值。

二、可能的原因分析

1. DMA传输完成后缓存未刷新(Cache Coherency)

如果你的MCU/MPU支持数据缓存(D-Cache),而DMA写入的内存区域是被缓存的区域,那么CPU读取该区域时可能会读到缓存中的旧数据,而不是DMA写入的最新数据。
🔍 关键点:DMA写入的是物理内存,而CPU可能从缓存中读取旧值。

解决办法:
在DMA传输完成之后,手动刷新或无效化缓存(Cache Invalidate)相关内存区域。
例如在STM32 HAL中可以使用:
  1. c
  2.   SCBInvalidateDCachebyAddr((uint32t )buffer, size);
复制代码
或者在设计DMA缓冲区时将其设置为非缓存(Non-cacheable)区域。

2. 内存对齐问题(Unaligned Access)

某些架构(如ARM Cortex-M7)在访问非对齐的32位数据时会触发硬件异常或返回错误值。

例如你这样读取:
  1. c
  2. uint32t p = &buffer[4];
  3. value = p;
复制代码

如果 buffer 是 uint8t 类型数组,且 buffer[4] 没有按4字节对齐,则可能导致未对齐访问错误。

解决办法:
使用 memcpy 强制复制4个字节到变量中:
  1. c
  2.   uint32t value;
  3.   memcpy(&value, &buffer[4], 4);
复制代码
或者使用联合体(union)方式处理。

3. 大小端(Endianness)转换问题

你在描述中提到是大端(Big-endian)数据,但MCU通常是小端(Little-endian)。如果你直接用指针访问4个字节组成一个 uint32t,那结果会是错误的,除非你手动做大小端转换。

解决办法:
手动拼接:
  ```c
  value = (buffer[4]

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-10-21 10:01:54
已绑定手机

2

主题

7

回帖

50

积分

注册会员

积分
50
发表于 昨天 10:03 | 显示全部楼层
使用的芯片是stc32g8k64
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-10-21 10:01:54
已绑定手机

2

主题

7

回帖

50

积分

注册会员

积分
50
发表于 昨天 10:10 | 显示全部楼层
妖怪罗*** 发表于 2025-10-21 10:03
使用的芯片是stc32g8k64

再次尝试下,清除缓存也没有正确输出了。。。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-10-21 10:01:54
已绑定手机

2

主题

7

回帖

50

积分

注册会员

积分
50
发表于 昨天 11:05 | 显示全部楼层
发现了一个低级错误 截图202510211104239010.jpg ,然后直接用查赋值了,也不进行逻辑运算了。这样就不会出错了
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2025-10-21 10:01:54
已绑定手机

2

主题

7

回帖

50

积分

注册会员

积分
50
发表于 昨天 11:15 | 显示全部楼层
截图202510211114296736.jpg
重新优化了一下,应该是因为printf的位置放在while里,导致,第一次数据是异常的,测试了5次,没再出现这个问题了。。。
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-22 01:24 , Processed in 0.128959 second(s), 76 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表