前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >同步STM32的SAI外设传输普通数据

同步STM32的SAI外设传输普通数据

作者头像
云深无际
发布2024-11-04 13:52:58
780
发布2024-11-04 13:52:58
举报
文章被收录于专栏:云深之无迹

FreeEEG32-32通道同步ADC生物电采集系统

关于32通道同步ADC采集系统答疑

一般同步ADC都是使用的FPGA,但是单片机也可以采集!虽然I2S和SAI都是传音频数据的,但其实可以传普通数据,本质都是二进制数据流嘛!(全网都没有相关的文章)

就是一个中断来了,然后通过SD线进来,DMA外设从SD搬到了内存,就是这么简单。

可以串行的从这里进去,4个SD口,4个ADC,数据太多还可以通过FIFO来缓冲,然后把FIFO的数据传到DMA里面。

我给了三个demo段:

  1. 实现了一个双通道SAI(串行音频接口)的DMA数据采集功能。也就是说,它会同时从两个SAI通道(Block B2和Block A1)采集数据,并将采集到的数据分别存储到两个不同的缓冲区中。
  2. 当ADC的引脚就绪,启动SAI模块读取数据,并通过UART7以二进制形式输出。
  3. 实现了一个多通道SAI(串行音频接口)的DMA数据采集功能,并且使用了中断来处理DMA完成事件。它可以同时从四个SAI通道(Block B2, Block A1, Block B1, Block A2)采集数据,并将采集到的数据分别存储到不同的缓冲区中。
    1. 多通道同时采集: 通过同时启动四个SAI通道的DMA传输,实现了多通道的数据同时采集。
    2. DMA高效传输: 使用DMA方式进行数据传输,可以减轻CPU的负担,提高数据传输效率。
    3. 中断处理: 通过DMA中断,可以在DMA传输完成后立即进行后续处理,提高系统响应速度。
    4. 灵活配置: 可以根据需要选择是否启用DMA中断。
    5. 缓冲区存储: 将采集到的数据分别存储到不同的缓冲区中,方便后续的处理。

采集使用的ADC是AD777x,他们不是单纯的SPI输出,而是并行的输出接口,在官方给出的代码里面有着不同数据输出的方式:

这里使用了SAI的外设,就使用这个模式

串行的输出

一帧数据

三个宏

三个宏,用于配置AD7779模数转换器(ADC)的寄存器。这些宏可以用来设置数据的输出格式、数据头格式和时钟分频系数。

  1. AD7779_DOUT_FORMAT(x)
    • (x) & 0x3: 取出输入值x的低两位。
    • ((x) & 0x3) << 6: 将提取的两位左移6位,放到寄存器中的指定位置。
    • 最终的结果用来配置AD7779寄存器中的数据输出格式。
    • 作用: 定义数据输出格式,决定每个采样点的位数。
  2. AD7779_DOUT_HEADER_FORMAT
    • (1 << 5): 将值的第5位设置为1,其他位为0。
    • 这个值用来在AD7779寄存器中启用数据头格式。
    • 作用: 定义数据头格式,包括同步和帧同步等信息。

这么多数据要加CRC的,也就是要加个头

AD7779、AD7771都是这样的

为了快速的移动数据使用了大量的DMA外设

SAI外设使用中断来启动

SD数据线

模式是非同步的从设备,就是等着数据来

这个就是一些设置,数据深度开到了最大

两个FIFO全开

FIFO在APB的下面

这个是中断的地址

这个函数就是就是接收DMA的数据

使用这样的结构直接获取来自SAI外设上面的数据

实现了一个双通道SAI(串行音频接口)的DMA数据采集功能。也就是说,它会同时从两个SAI通道(Block B2和Block A1)采集数据,并将采集到的数据分别存储到两个不同的缓冲区中。

条件判断:

  • if (FREESMARTEEG_ADC & FREESMARTEEG_ADC_SAI_READ_DMAMUX): 这一行代码首先检查了两个宏定义:FREESMARTEEG_ADCFREESMARTEEG_ADC_SAI_READ_DMAMUX
  • 只有当这两个宏定义都为真时,才会执行后续的代码。这意味着,只有当ADC功能和SAI读取DMA复用功能都开启时,才会进行数据采集。

启动DMA传输:

  • 这行代码启动了SAI Block B2的DMA接收。它会将从SAI Block B2接收到的32位数据存储到datas[0]这个缓冲区中。
  • HAL_SAI_Receive_DMA(&hsai_BlockB2, datas[0], SAI_DATASIZE_32):

同样,这行代码启动了SAI Block A1的DMA接收,并将数据存储到datas[1]缓冲区中。

  • HAL_SAI_Receive_DMA(&hsai_BlockA1, datas[1], SAI_DATASIZE_32)

等待DMA传输完成:

  • 这行代码会一直等待,直到SAI Block B2的DMA传输完成。
  • while (HAL_SAI_GetState(&hsai_BlockB2) != HAL_SAI_STATE_READY)
  • 这行代码会一直等待,直到SAI Block A1的DMA传输完成。
  • while (HAL_SAI_GetState(&hsai_BlockA1) != HAL_SAI_STATE_READY)

检查条件: 确保ADC和DMA复用功能开启。

启动DMA: 同时启动两个SAI通道的DMA接收。

等待完成: 等待两个DMA传输都完成。

  • 双通道同时采集: 通过同时启动两个SAI通道的DMA传输,实现了双通道的数据同时采集。
  • 缓冲区存储: 将采集到的数据分别存储到不同的缓冲区中,方便后续的处理。
  • 等待机制: 通过循环等待DMA传输完成,确保数据采集的完整性。

在ADC的数据传输的时候是有个信号的

条件判断:

  • 检查是否开启了ADC和SAI读取功能。
  • FREESMARTEEG_ADC & FREESMARTEEG_ADC_SAI_READ

数据读取循环:

  • 循环等待DMA传输完成。
  • HAL_SAI_GetState(&hsai_BlockB1) != HAL_SAI_STATE_READY:
  • 启动DMA方式接收32位的数据,并将数据存储到datasBuffer[0]中。
  • HAL_SAI_Receive_DMA(&hsai_BlockB1, datasBuffer[0], SAI_DATASIZE_32):
  • 读取DRDY引脚的状态。
  • HAL_GPIO_ReadPin(AD_DRDY_GPIO_Port, AD_DRDY_Pin):
  • 循环等待DRDY引脚变为高电平,表示数据准备就绪。
  • 等待数据就绪:
  • 启动SAI接收:
  • 等待DMA传输完成:

数据打印:

  • 遍历接收到的数据,逐字节打印成二进制形式。
  • print7_binary函数:用于打印一个字节的二进制表示。
  • print7_symbol(';'): 用于打印分隔符';'。
  • print7_line(): 用于打印换行符。
  • 检查是否开启了UART7文本输出。
  • FREESMARTEEG_OUT & FREESMARTEEG_SAI_TEXT_UART7:
  • 检查输出模式:
  • 循环打印数据:
  • SAI (Serial Audio Interface): 一种高速串行音频接口,用于音频数据的传输。
  • DMA (Direct Memory Access): 一种数据传输方式,可以高效地直接将数据从外设传输到内存,减轻CPU的负担。
  • DRDY (Data Ready): 数据就绪信号,表示新的数据已经准备好可以读取。
  • 二进制输出: 将数据以二进制的形式打印出来。

条件判断:

  • 这一行代码首先检查了两个宏定义:FREESMARTEEG_ADCFREESMARTEEG_ADC_SAI_READ_INT。只有当这两个宏定义都为真时,才会执行后续的代码。这意味着,只有当ADC功能和SAI读取中断功能都开启时,才会进行数据采集。
  • if (FREESMARTEEG_ADC & FREESMARTEEG_ADC_SAI_READ_INT):

启动数据采集:

  • 如果启用了DMA中断:
  • 如果没有启用DMA中断:
  • HAL_SAI_Receive_DMA: 启动四个SAI通道的DMA接收,并将数据分别存储到datas[0]datas[1]datas[2]datas[3]这四个缓冲区中。
  • 程序会等待每个DMA传输完成,然后设置SAI_RxCplt标志位,表示数据采集周期结束。
  • 程序直接等待每个DMA传输完成,然后设置SAI_RxCplt标志位。
  • if (SAI_RxStart): 这行代码检查了一个标志位SAI_RxStart,用于判断是否需要开始新的数据采集周期。
  • SAI_DMA_INT_SHIFT: 这个标志位表示是否启用了DMA中断。

等待DMA传输完成:

  • 无论是否启用了DMA中断,程序都会通过HAL_SAI_GetState函数来等待每个DMA传输完成。
  1. 检查条件: 确保ADC和SAI读取中断功能开启,并且需要开始新的数据采集周期。
  2. 启动DMA: 启动四个SAI通道的DMA接收。
  3. 等待完成: 等待所有DMA传输完成。
  4. 设置标志位: 设置SAI_RxCplt标志位,表示数据采集周期结束。

第一个的连接是这样的,全连接

第二个也是

然后时钟线就两个,外设4个,然后可以把时钟给到别人

音频子模块既可作为接收器,又可作为发送器;既可与另一模块同步,又可以不同步。SAI 可与其它 SAI 相连接来同步运行。

音频数据的量化位数可能不同,控制器支持16bit、24bit和32bit三种数据长度, 因为数据寄存器是16bit的,所以对于24bit和32bit数据长度需要发送两个。为此,可以产生四种数据和帧格式组合:

  • 将16位数据封装在16位帧中
  • 将16位数据封装在32位帧中
  • 将24位数据封装在32位帧中
  • 将32位数据封装在32位帧中

当使用32位数据包中的16位数据时,前16位(MSB)为有效位,16位LSB被强制清零,无需任何软件操作或DMA请求(只需一个读/写操作)。如果程序使用DMA传输(一般都会用),则24位和32位数据帧需要对数据寄存器执行两次DMA操作。24位的数据帧,硬件会将8位非有效位扩展到带有0位的32位。对于所有数据格式和通信标准而言,始终会先发送最高有效位(MSB优先)。

另外的外设,就没有时钟线了

是使用的第一个的时钟线

同理

这个是时钟树上面的位置

这个就是IO的输入的口

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档