硬汉嵌入式论坛

 找回密码
 立即注册
查看: 76|回复: 3
收起左侧

[技术讨论] GD32h7 spi+dma求助

[复制链接]

2

主题

5

回帖

11

积分

新手上路

积分
11
发表于 前天 15:34 | 显示全部楼层 |阅读模式
在使用spi+DMA通信时只配置使能一次DMA接收函数可以正常接收数据,若重置DMA收发消息只有第一次可以在缓冲区看到数据,后续能进入接收中断但缓冲区数据无变化,示波器可以捕获到接收数据波形。以下是部分代码请问哪里配置有误。


void spi_dma_config(void)
{
                dma_single_data_parameter_struct dma_init_struct;
    /* deinitialize DMA registers of a channel */
    dma_deinit(DMA1, DMA_CH4);
    dma_deinit(DMA1, DMA_CH5);
    dma_deinit(DMA1, DMA_CH6);
    dma_single_data_para_struct_init(&dma_init_struct);
   
    /* SPI1 transmit DMA config: DMA_CH4 */
    dma_init_struct.request = DMA_REQUEST_SPI1_TX;
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;   
    dma_init_struct.memory0_addr = (uint32_t)spi1_send_array;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = 16;
    dma_init_struct.periph_addr = (uint32_t)&SPI_TDATA(SPI1);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.priority = DMA_PRIORITY_HIGH;
    dma_single_data_mode_init(DMA1, DMA_CH4, &dma_init_struct);
   dma_circulation_disable(DMA1, DMA_CH4);
   dma_interrupt_enable(DMA1,DMA_CH4,DMA_INT_FTF);
               
       
    /* SPI1 receive DMA config: DMA_CH5 */
    dma_init_struct.request = DMA_REQUEST_SPI1_RX;
    dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;   
    dma_init_struct.memory0_addr = (uint32_t)ad7606.ad_buff;
    dma_init_struct.periph_addr = (uint32_t)&SPI_RDATA(SPI1);
    dma_init_struct.priority = DMA_PRIORITY_HIGH;
    dma_init_struct.number = 16;
    dma_single_data_mode_init(DMA1, DMA_CH5, &dma_init_struct);   
    dma_circulation_disable(DMA1, DMA_CH5);       
    dma_interrupt_enable(DMA1,DMA_CH5,DMA_INT_FTF);
               
    /* SPI4 transmit DMA config: DMA_CH6 */
    dma_init_struct.request = DMA_REQUEST_SPI4_TX;
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;   
    dma_init_struct.memory0_addr = (uint32_t)spi4_send_array;
    dma_init_struct.periph_addr = (uint32_t)&SPI_TDATA(SPI4);
    dma_init_struct.priority = DMA_PRIORITY_HIGH;
    dma_single_data_mode_init(DMA1, DMA_CH6, &dma_init_struct);
    dma_circulation_disable(DMA1, DMA_CH6);       
        //        dma_interrupt_enable(DMA1,DMA_CH6,DMA_INT_FTF);
               
    /* enable DMA channel */
    dma_channel_enable(DMA1, DMA_CH4);
    dma_channel_enable(DMA1, DMA_CH5);
    dma_channel_enable(DMA1, DMA_CH6);
               
    spi_dma_enable(SPI1, SPI_DMA_TRANSMIT);
    spi_dma_enable(SPI1, SPI_DMA_RECEIVE);
    spi_dma_enable(SPI4, SPI_DMA_TRANSMIT);
}


//中断重置spi、dma收发消息

void EXTI5_9_IRQHandler(void)
{
        if(RESET != exti_interrupt_flag_get(EXTI_5)) {
//      ad7670_read();

                dma_channel_disable(DMA1,DMA_CH4);
                //重置发送地址
                dma_memory_address_config(DMA1, DMA_CH4, DMA_MEMORY_0, (uint32_t)spi1_send_array);
                //重置发送长度
                dma_transfer_number_config(DMA1, DMA_CH4, 16);
                gpio_bit_reset(SPI1__CS_PORT, SPI1_CS_PIN);
                //启动DMA发送
                dma_channel_enable(DMA1, DMA_CH4);
               
               exti_interrupt_flag_clear(EXTI_5);
               //此部分重置DMA接收,地址、数据长度都重置,但在缓冲区看不到数据变化,可以正常进去接收数据满中断,示波器也可以看到真实数据的波形
                dma_channel_disable(DMA1,DMA_CH5);
                dma_memory_address_config(DMA1, DMA_CH5, DMA_MEMORY_0, (uint32_t)ad7606.ad_buff);
                dma_transfer_number_config(DMA1, DMA_CH5, 16);
                dma_channel_enable(DMA1,DMA_CH5);
               
                spi_master_transfer_start(DMA1, SPI_TRANS_START);
    }
}


//清中断

void DMA1_Channel4_IRQHandler(void)
{
        if(RESET != dma_interrupt_flag_get(DMA1,DMA_CH4,DMA_INT_FLAG_FTF)){
                dma_interrupt_flag_clear(DMA1,DMA_CH4,DMA_INT_FLAG_FTF);
        }
}


//清中断

void DMA1_Channel5_IRQHandler(void)
{
        if(RESET != dma_interrupt_flag_get(DMA1,DMA_CH5,DMA_INT_FLAG_FTF)){
                dma_interrupt_flag_clear(DMA1,DMA_CH5,DMA_INT_FLAG_FTF);
                gpio_bit_set(SPI1__CS_PORT, SPI1_CS_PIN);
        }
}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 前天 16:06 | 显示全部楼层
1、从楼主的代码来看,如果是触发一次,SPI DMA读取一次,那不建议用DMA了,DMA此时没优势。
2、如果继续使用SPI DMA,  试试复位初始化SPI和DMA,然后重新配置再启动,看看正常不,正常后,再看看那些是重新启动必须配置的。
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 前天 16:48 | 显示全部楼层
1.是触发一次读一次的  虽然底层库直接操作寄存器的但不知道为什么还是太慢速率达不到 dma方式我看波形速率可以满足我的需求
回复

使用道具 举报

2

主题

5

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 前天 16:58 | 显示全部楼层
eric2013 发表于 2025-8-12 16:06
1、从楼主的代码来看,如果是触发一次,SPI DMA读取一次,那不建议用DMA了,DMA此时没优势。
2、如果继续 ...

1. 确实是触发一次 spi dma读取一次  虽然底层库是直接操作寄存器的但不知道为什么连续读多个字节时速率还是太慢脉冲不连续 中间有较大间隔(与dma方式抓取时间相差百倍以上) 我抓spi dma数据速率可以满足要求
2.在数据中断中直接重新初始化spi和dma配置仍然不行 和单独重置DMA接收现象一致  这个逻辑我看着好像没什么问题 串口的DMA接收我也是在空闲中断中使用一样的逻辑重置DMA相应通道可以正常使用
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 00:50 , Processed in 0.038501 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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