打印
[技术讨论]

GD32H759 使能串口0+DMA、和串口6+DMA, 为什么不能同时发数据出去呢?

[复制链接]
79|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
NKML|  楼主 | 2024-12-17 17:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 NKML 于 2024-12-17 17:30 编辑

大佬们好,芯片是GD32H759,  DMA是使用不同的通道,同时执行串口0和串口6, 谁在前面谁执行。  是冲突了么?

这是串口0 的DMA配置:
void usart0_dma_cfg(void)  
{
                        // DMA单数据传输参数结构体
    dma_single_data_parameter_struct dma_init_struct;
    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA0);
    /* enable DMAMUX clock */
    rcu_periph_clock_enable(RCU_DMAMUX);
    /* initialize the com */
    usart0_config();
    /*configure DMA interrupt*/
    nvic_config();
    /* clean d-cache by address before DMA transmission */   //在DMA传输之前清除D-cache
    SCB_CleanDCache_by_Addr((uint32_t*)txbuffer, BUFFER_SIZE);
    /* initialize DMA channel 0 */
                dma_deinit(DMA0, DMA_CH0);
    dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.request      = DMA_REQUEST_USART0_TX;    // 请求源为USART0 TX
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPH;    // 内存到外设
    dma_init_struct.memory0_addr = (uint32_t)txbuffer;       // 内存地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // 外设数据宽度8位
    dma_init_struct.number       = ARRAYNUM(txbuffer);       // 传输数据量
    dma_init_struct.periph_addr  = (uint32_t)USART0_TDATA_ADDRESS; // 外设地址
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH; // 优先级最高
    dma_single_data_mode_init(DMA0, DMA_CH0, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH0);  // 禁用循环模式
    /* USART DMA enable for transmission and reception */
    usart_dma_transmit_config(USART0, USART_TRANSMIT_DMA_ENABLE);  
    /* enable DMA channel 0 transfer complete interrupt */
    dma_interrupt_enable(DMA0, DMA_CH0, DMA_CHXCTL_FTFIE);
    /* enable DMA channel 0 */
    dma_channel_enable(DMA0, DMA_CH0);
    /* initialize DMA channel 1 */
    dma_deinit(DMA0, DMA_CH1);
    dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.request      = DMA_REQUEST_USART0_RX;    // 请求源为USART0 RX
    dma_init_struct.direction    = DMA_PERIPH_TO_MEMORY;     // 外设到内存
    dma_init_struct.memory0_addr = (uint32_t)rxbuffer;       // 内存地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // 外设数据宽度8位
    dma_init_struct.number       = 32;                      // 传输数据量
    dma_init_struct.periph_addr  = (uint32_t)USART0_RDATA_ADDRESS; // 外设地址
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH; // 优先级最高
    dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);

    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH1); // 禁用循环模式
    /* USART DMA enable for reception */  
    usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE); // 使能USART DMA接收
    /* enable DMA channel 1 transfer complete interrupt */
    dma_interrupt_enable(DMA0, DMA_CH1, DMA_CHXCTL_FTFIE);   // 使能DMA通道1传输完成中断
    /* enable DMA channel 1 */
    dma_channel_enable(DMA0, DMA_CH1);    // 使能DMA通道1
        
               
/* waiting for the transfer to complete*/     
    while(RESET == g_transfer_complete) {     // 等待传输完成
    }

    g_transfer_complete = RESET;
   
    /* waiting for the transfer to complete*/
    while(RESET == g_transfer_complete) {   // 等待传输完成        
    }

    /* invalidate d-cache by address after DMA reception*/
    SCB_InvalidateDCache_by_Addr((uint32_t*)rxbuffer, BUFFER_SIZE);  //主要功能是使指定地址范围内的D-Cache无效。它从一个32字节对齐的地址开始,以32字节为单位进行无效化。
   // printf("\n\r%s\n\r", rxbuffer);
                //usart0_send_string(rxbuffer);
                usart0_send_string((const char*)txbuffer);
}

////////////////////////////////////////////////////////////////////////////////////////////

这是串口6的DMA配置:

void usart6_dma_cfg(void)
{
                        // DMA单数据传输参数结构体
    dma_single_data_parameter_struct dma_init_struct;
    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA0);   //??  
    /* enable DMAMUX clock */
    rcu_periph_clock_enable(RCU_DMAMUX); //??
    /* initialize the com */
    uart6_config();
    /*configure DMA interrupt*/
//    nvic6_config();

    /* clean d-cache by address before DMA transmission */   //在DMA传输之前清除D-cache
    SCB_CleanDCache_by_Addr((uint32_t*)txbuffer6, BUFFER_SIZE6);
    /* initialize DMA channel 0 */
    dma_deinit(DMA0, DMA_CH2);
    dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.request      = DMA_REQUEST_UART6_TX;    // 请求源为USART6 TX
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPH;    // 内存到外设
    dma_init_struct.memory0_addr = (uint32_t)txbuffer6;       // 内存地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // 外设数据宽度8位
    dma_init_struct.number       = ARRAYNUM6(txbuffer6);       // 传输数据量
    dma_init_struct.periph_addr  = (uint32_t)UART6_TDATA_ADDRESS; // 外设地址
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH; // 优先级最高
    dma_single_data_mode_init(DMA0, DMA_CH2, &dma_init_struct);  //
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH2);  // 禁用循环模式
    /* USART DMA enable for transmission and reception */
    usart_dma_transmit_config(UART6, USART_TRANSMIT_DMA_ENABLE);
    /* enable DMA channel 0 transfer complete interrupt */
    dma_interrupt_enable(DMA0, DMA_CH2, DMA_CHXCTL_FTFIE);
    /* enable DMA channel 0 */
    dma_channel_enable(DMA0, DMA_CH2);
    /* initialize DMA channel 1 */
    dma_deinit(DMA0, DMA_CH3);
    dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.request      = DMA_REQUEST_UART6_RX;    // 请求源为USART RX
    dma_init_struct.direction    = DMA_PERIPH_TO_MEMORY;     // 外设到内存
    dma_init_struct.memory0_addr = (uint32_t)rxbuffer6;       // 内存地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // 外设数据宽度8位
    dma_init_struct.number       = 32;                      // 传输数据量
    dma_init_struct.periph_addr  = (uint32_t)UART6_RDATA_ADDRESS; // 外设地址
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH; // 优先级最高
    dma_single_data_mode_init(DMA0, DMA_CH3, &dma_init_struct);

    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH3); // 禁用循环模式
    /* USART DMA enable for reception */  
    usart_dma_receive_config(UART6, USART_RECEIVE_DMA_ENABLE); // 使能USART DMA接收
    /* enable DMA channel 1 transfer complete interrupt */
    dma_interrupt_enable(DMA0, DMA_CH3, DMA_CHXCTL_FTFIE);   // 使能DMA通道1传输完成中断
    /* enable DMA channel 1 */
    dma_channel_enable(DMA0, DMA_CH3);    // 使能DMA通道3
        
               
/* waiting for the transfer to complete*/     
    while(RESET == g_transfer_complete6) {     // 等待传输完成
    }

    g_transfer_complete6 = RESET;
   
    /* waiting for the transfer to complete*/
    while(RESET == g_transfer_complete6) {   // 等待传输完成        
    }

    /* invalidate d-cache by address after DMA reception*/
    SCB_InvalidateDCache_by_Addr((uint32_t*)rxbuffer6, BUFFER_SIZE6);  //主要功能是使指定地址范围内的D-Cache无效。它从一个32字节对齐的地址开始,以32字节为单位进行无效化。
   
                uart6_send_string((const char*)txbuffer6);
        
}

几乎是相同的配置,但是放在main函数里面,只能执行放在前面的, 这是为啥呢?

使用特权

评论回复
评论
NKML 2024-12-17 17:29 回复TA
单独打印数据都没问题,就是放在一起,不能打印,不知道为啥 

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

3

帖子

0

粉丝