嵌入式技术论坛
直播中

訾存贵

7年用户 920经验值
私信 关注
[问答]

怎样去修改HC32F460串口DMA的接收方式呢

以前用STM32F1的时候串口DMA接收方式解决断帧的问题需要修改一个地方

1.jpg

但是用HC32F460没有这两个函数不知道怎么弄了

问题解决了,改了3个地方

1.jpg

回帖(4)

张伟

2022-12-5 13:41:32
用DMA链表 头尾相接
2个buffer进行乒乓

stc_dma_llp_descriptor_t AudioDmaLLP[2] = {
    {
        .SARx = (uint32_t)(&Sin1K32767[0]),
        .DARx = (uint32_t)(&I2S_CH->TXBUF),
        .DTCTLx_f.CNT = 960,
        .DTCTLx_f.BLKSIZE = 1,
        .LLPx = (uint32_t)(&AudioDmaLLP[1]),
        .CHxCTL_f.SINC = AddressIncrease,
        .CHxCTL_f.DINC = AddressFix,
        .CHxCTL_f.HSIZE = Dma16Bit,
        .CHxCTL_f.LLPEN = Enable,
        .CHxCTL_f.LLPRUN = LlpWaitNextReq,
        .CHxCTL_f.IE = Enable,
    },
    {
        .SARx = (uint32_t)(&Sin1K32767[0]),
        .DARx = (uint32_t)(&I2S_CH->TXBUF),
        .DTCTLx_f.CNT = 960,
        .DTCTLx_f.BLKSIZE = 1,
        .LLPx = (uint32_t)(&AudioDmaLLP[0]),
        .CHxCTL_f.SINC = AddressIncrease,
        .CHxCTL_f.DINC = AddressFix,
        .CHxCTL_f.HSIZE = Dma16Bit,
        .CHxCTL_f.LLPEN = Enable,
        .CHxCTL_f.LLPRUN = LlpWaitNextReq,
        .CHxCTL_f.IE = Enable,
    }};
static void I2S2_DMATxCplt(void)
{
    rt_interrupt_enter(); /* enter interrupt */
    DMA_ClearIrqFlag(DMA_UNIT, DMA_CH, TrnCpltIrq);
    if (BufferEndCallBack && BufferEndParam)
    {
        uint32_t index;
        if (DMA_UNIT->LLP2 == (uint32_t)&AudioDmaLLP[0])
        {
            index = 1;
        }
        else
        {
            index = 0;
        }
        BufferEndCallBack(BufferEndParam, index);
    }
    rt_interrupt_leave(); /* leave interrupt */
}
static void FirstDMAConfig(stc_dma_llp_descriptor_t *first)
{
    stc_dma_config_t stcDmaCfg;
    MEM_ZERO_STRUCT(stcDmaCfg);
    /* Disable DMA1. */
    // DMA_Cmd(DMA_UNIT, Disable);
    DMA_ClearIrqFlag(DMA_UNIT, DMA_CH, BlkTrnCpltIrq);
    DMA_ClearIrqFlag(DMA_UNIT, DMA_CH, TrnCpltIrq);
    stcDmaCfg.u16BlockSize = 1u; // uint16
    stcDmaCfg.u16TransferCnt = first->DTCTLx_f.CNT;
    stcDmaCfg.u32SrcAddr = first->SARx;
    stcDmaCfg.u32DesAddr = (uint32_t)(&I2S_CH->TXBUF);
    stcDmaCfg.stcDmaChCfg.enLlpEn = Enable;
    stcDmaCfg.stcDmaChCfg.enLlpMd = LlpWaitNextReq;
    stcDmaCfg.u32DmaLlp = first->LLPx;
    stcDmaCfg.stcDmaChCfg.enSrcRptEn = Disable;
    stcDmaCfg.stcDmaChCfg.enDesRptEn = Disable;
    stcDmaCfg.stcDmaChCfg.enSrcInc = AddressIncrease;
    stcDmaCfg.stcDmaChCfg.enDesInc = AddressFix;
    stcDmaCfg.stcDmaChCfg.enIntEn = Enable;
    stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma16Bit;
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1, Enable);
    DMA_Cmd(DMA_UNIT, Enable);
    DMA_InitChannel(DMA_UNIT, DMA_CH, &stcDmaCfg);
    DMA_ChannelCmd(DMA_UNIT, DMA_CH, Enable);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);
    DMA_SetTriggerSrc(DMA_UNIT, DMA_CH, EVT_I2S2_TXIRQOUT);
    stc_irq_regi_conf_t stcIrqRegiCfg;
    MEM_ZERO_STRUCT(stcIrqRegiCfg);
    stcIrqRegiCfg.enIRQn = I2S2_DMA_TXC_INT_IRQn;
    stcIrqRegiCfg.pfnCallback = I2S2_DMATxCplt;
    stcIrqRegiCfg.enIntSrc = I2S2_DMA_TXC_INT_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
}
举报

张伟

2022-12-5 13:41:43
1
举报

訾存贵

2022-12-5 13:42:09
你这是裸机程序,我用的是rt-thread的dma驱动,裸机都好处理,rt-thread驱动不知道修改
举报

张伟

2022-12-5 13:42:29
我看你的截图以为你要实现像stm32的半完成中断 和完成中断的样子
举报

更多回帖

发帖
×
20
完善资料,
赚取积分