SPI+DMA+FIFO(STM32H743+ADS127L11)

1.简述

STM32h743与adc芯片进行SPI通信,采集到的24位数据通过DMA搬运到指定的8位数组内存区,将24位数据转换成电压值后,通过两个FIFO将数据搬运到存放电压值的内存区。

2.STM32CUBMX配置

2.1 SPI配置如下

2.2 DMA配置

采用线0作为DMA触发同步信号,当线0来一个上升沿则触发一次DMA,并且一次搬运3个字节的数据,同时线0作为ADC芯片的触发信号,一个上升沿触发一次转换,SPI得到3个字节的数据.

3.DMA中断函数

3.1 发送接收半中断函数

注:SPI配置为全双工通信时,半发送和半完成是同时完成,并且半发送和半接收中断函数为同一个,则半发送和半接收都会进入半中断。

3.1.1中断函数的寻找

CUBMX配置完成后生成代码,在 it.c 文件里找到下图函数

跳入接收中断函数,找到XferHalfCpltCallback并跳入

可以看到这是DMA句柄面向对象思想的方法

但半中断函数在启动SPI_DMA传输的函数HAL_SPI_TransmitReceive_DMA中

对象DMA句柄中的半中断和全中断方法被此函数赋值,并且若定义中断函数在此函数里

3.2 中断函数的编写(使用FIFO)

半中断函数中把前一半数据存入FIFOA

全中断函数中把后一半数据存入FIFOB

/**********************************************************************************************************
*	function : HAL_SPI_TxRxHalfCpltCallback
*	brief : SPI发送接收 半 完成回调函数
*	parm : hspi
*	return : 无
**********************************************************************************************************/
void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
{
    if (hspi->Instance == SPI1)
    {
        fifoa_in(&spi_dma_Rx_buffer[0], Rx_Size/2);
        flag_A_full = 1;//可以读取 FIFO A
    }
}
/**********************************************************************************************************
*	function : HAL_SPI_TxRxCpltCallback
*	brief : SPI发送接收完成回调函数
*	parm : hspi
*	return : 无
**********************************************************************************************************/
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
    if (hspi->Instance == SPI1)
    {
        fifob_in(&spi_dma_Rx_buffer[Rx_Size/2], Rx_Size/2);
        flag_B_full = 1;//可以读取 FIFO B
    }
}

4.FIFO的实现

FIFO的实现可参考此博客:用C语言实现FIFO (简单版_c fifo-CSDN博客

4.1 while循环

while中实现读取FIFO中的数据并把其转换成电压值

判断FIFOA是否存满,若存满,则关闭全局中断,把FIFOA的数据取出数组spi_dma_Outx_FIFO_u8_A里,将其转换为电压值再开启中断,FIFOB依次推理。

    while (1)
    {
        //ads127l11  FIFO测试
        if(flag_A_full == 1){
            DISABLE_INT();             //禁止中断
            fifoa_out(spi_dma_Outx_FIFO_u8_A,Rx_Size/2);
            flag_A_full = 0;
            for (int i = 0; i < Rx_Size/3/2; i++) {
                ads127l11_32bit_data = signExtend(&spi_dma_Outx_FIFO_u8_A[i*3]);
                ads127l11_Voltage[i] = (float) (ads127l11_32bit_data * 4096) / 8388608;//计算电压值,变成mv方便观察
            }
            ENABLE_INT();              //开启中断
        }
        if(flag_B_full == 1){
            DISABLE_INT();
            fifob_out(spi_dma_Outx_FIFO_u8_B,Rx_Size/2);
            flag_B_full = 0;
            for (int i = 0; i < Rx_Size/3/2; i++) {
                ads127l11_32bit_data = signExtend(&spi_dma_Outx_FIFO_u8_B[i*3]);
                ads127l11_Voltage[i+96] = (float) (ads127l11_32bit_data * 4096) / 8388608;//计算电压值,变成mv方便观察
            }
            ENABLE_INT();
            bsp_LedToggle();
        }

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值