以16 kHz的速率将16位数据记录到SD卡

时间:2014-02-04 10:45:31

标签: embedded sd-card fat

我正在使用带有microSD卡的STM32F4微控制器。我正在通过DMA捕获模拟数据。

我正在使用双缓冲器,一次采集1280(10 * 128 - 10个FFT)样本。 当一个缓冲区已满时,我设置了一个标志,然后我一次查看128个样本并对其进行FFT计算。所有这一切都运行良好。

正在以我想要的速率对数据进行采样,并且FFT计算正如我所期望的那样。如果我让程序运行一秒钟,我发现它运行FFT约343次(44000/128)。

但问题是我想将64个值从此FFT保存到SD卡。

  • 我正在使用HCC胖文件系统库。
  • FFT计算的每个循环我将64个值复制到一个数组中。
  • 每10次计算后,我将此数组的内容写入文件并重新开始。
  • 数组存储640个float_32值(10 * 64)。

这适用于一秒钟的测试运行。我将22,000个值存储到SD卡中。

但是当我增加时间时,我开始丢失样本,因为SD卡需要更长时间才能写入。我需要SD卡一直存储超过87 kbit / s(4字节* 64 * 343 = 87808)。我已经尝试增加DMA缓冲区样本大小,然后增加它写入的次数,但没有发现它有帮助。

我使用的是8G microSD卡,第4类。我将SD卡格式化为默认的FAT32分配单元大小2048.

我应该如何组织缓冲数据以实现此目的?我认为使用较少的写入可能有所帮助排队会有帮助吗?我将如何实现这一点,并且任何人都有一个例子吗?

我看到clifford遇到了类似的问题而他正在使用队列 How can I use an SD card for logging 16-bit data at 48 ksamples/s?

3 个答案:

答案 0 :(得分:0)

在我的情况下,我通过尝试大量不同的卡来实现它 - 它们变化很大。如果我有足够的RAM可用于更长的缓冲区也可以工作。

如果您没有使用RTOS,可能无法使用队列缓冲选项,或者至少实现这一点非常简单。

使用RTOS队列,我建议您创建一个长度为64*sizeof(float_32)的消息队列,队列中的消息数量将由您需要处理的卡延迟数量决定;例如,长度为343,将维持1秒的卡停顿,并将需要87Kb的RAM。然后,应用程序将具有执行FFT并将数据放入队列的高优先级线程,而低优先级线程从队列中获取数据并写入文件。

通过在启动写入之前在DMA缓冲区中累积多个消息块,可以进一步提高性能,并且仔细选择最佳DMA缓冲区长度可能会有一些好处。

答案 1 :(得分:0)

Flash对覆盖非常非常敏感。写入3kB然后再写入3kB可能会计入前4 kB的覆盖。在你的情况下,没有充分的理由为什么你想要这么小的写作。我建议16 kB写入(32帧/写* 64样本/帧* 4字节/样本)。你需要每秒5或6次写入,这应该是任何旧SD卡的规格。

现在很有可能在写作时你会得到另外1280个样本;你将不得不在另一个线程上处理它。应该没问题,因为写入应该在不使用CPU的情况下阻塞(这是一个低级别的Flash延迟)

答案 2 :(得分:0)

问题的最可能原因可能是您通过库连接卡的方式。

SPI协议上的SD卡(我假设在这里使用)可以用512字节扇区单元读取或写入,一些SD命令可以流式传输(更快地执行顺序扇区访问)。 SD卡SPI协议的一个重要元素是各种延迟,您必须轮询卡是否可以启动操作(例如将数据写入扇区)。

您应该阅读库的API以了解其编写过程如何工作。您需要执行一些常规操作,最终会轮询卡片以了解写入过程是否可以继续。某些卡可能需要一定数量的访问才能为操作做好准备,其他一些卡可能会使用超时进行状态转换。将相对较少的功能(例如一次在2-3毫秒内)预期卡同时准备就好可能效果不佳。无论是否已经完成,你都要继续唠叨。

仅凭自己的SD接口经验。