打印
[技术问答]

关于华大F460 DMA加串口空闲接受出现的问题

[复制链接]
1519|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
duxuqi|  楼主 | 2021-11-17 15:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大佬们好,本人也算是头一次使用华大单片机并选择了F460JEUA这款作为开发用。由于串口之前采用的是中断接收感觉有点问题就切换成了DMA加空闲中断接受,系统用的是RT THREAD NANO。但是目前遇到了一个极度奇葩的问题,百思不得其解,望各位大佬能抽空看看帮忙指导指导了。情况是,昨天的时候,把串口1配置成了这样的模式然后经过测试,效果非常的好。今天把串口2也配置成这样了,然后串口1当场出bug了,串口1的DMA接收正常,接收中断正常,就是串口空闲中断无论如何都进不去。而反之,串口2的一切却都正常,百试百灵。附上代码给各位参考参考吧,先感谢帮忙了。

使用特权

评论回复
沙发
duxuqi|  楼主 | 2021-11-17 15:06 | 只看该作者
void Timer0Init(void)//这个是定时器的配置函数
{
    stc_clk_freq_t stcClkTmp;
    stc_tim0_base_init_t stcTimerCfg;
    stc_tim0_trigger_init_t StcTimer0TrigInit;

    MEM_ZERO_STRUCT(stcClkTmp);
    MEM_ZERO_STRUCT(stcTimerCfg);
    MEM_ZERO_STRUCT(StcTimer0TrigInit);

    /* Timer0 peripheral enable */
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM01, Enable);//启动Timer0 1   A通道,是串口1

    /* Clear CNTAR register for channel A */
    //TIMER0_WriteCntReg(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, 0u);
                TIMER0_WriteCntReg(M4_TMR01, Tim0_ChannelA, 0u);
    TIMER0_WriteCntReg(M4_TMR01, Tim0_ChannelB, 0u);

    /* Config register for channel A */
    stcTimerCfg.Tim0_CounterMode = Tim0_Async;
    stcTimerCfg.Tim0_SyncClockSource = 0x00u;//LRC时钟
    stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv0;//42M 8分频   5250000
    stcTimerCfg.Tim0_CmpValue = (uint16_t)32u;//一毫秒一波吧,先试试看先
    TIMER0_BaseInit(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, &stcTimerCfg);

    /* Clear compare flag */
    TIMER0_ClearFlag(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB);

    /* Config timer0 hardware trigger */
    StcTimer0TrigInit.Tim0_InTrigEnable = false;//好像是内部捕获输入无效
    StcTimer0TrigInit.Tim0_InTrigClear = true;
    StcTimer0TrigInit.Tim0_InTrigStart = true;
    StcTimer0TrigInit.Tim0_InTrigStop = false;
    TIMER0_HardTriggerInit(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, &StcTimer0TrigInit);
}

使用特权

评论回复
板凳
duxuqi|  楼主 | 2021-11-17 15:07 | 只看该作者
void Dma1_Ch0_Init(void)//DMA1 通道0的配置函数,这个配置的是给串口1的
{
                char * RxBuffer;
                RxBuffer = RxBuffer1;
       
                //TIMER0_Cmd(M4_TMR01, Tim0_ChannelA,Enable);
       
    stc_dma_config_t stcDmaInit;
    stc_irq_regi_conf_t stcIrqRegiCfg;

    /* Enable peripheral clock */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1 | PWC_FCG0_PERIPH_DMA2,Enable);

    /* Enable DMA. */
    DMA_Cmd(M4_DMA1,Enable);

    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u; /* 1 block */
    stcDmaInit.u32SrcAddr = ((uint32_t)(&M4_USART1->DR)+2ul); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)RxBuffer;     /* Set destination address. */
                //stcDmaInit.u32DesAddr = (uint32_t)(&M4_USART1->DR);
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix;  /* Set source address mode. */
    stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease;//地址自增
    stcDmaInit.stcDmaChCfg.enIntEn = Enable;       /* Enable interrupt. */
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;   /* Set data width 8bit. */
                stcDmaInit.u16TransferCnt = 256;//这里好像是传输的次数吧,先试试看了
    DMA_InitChannel(M4_DMA1, DmaCh0, &stcDmaInit);

    //选择DMA通道
    DMA_ChannelCmd(M4_DMA1, DmaCh0, Enable);

    /* 清除DMA标志 */
    DMA_ClearIrqFlag(M4_DMA1, DmaCh0, TrnCpltIrq);

    /* Enable peripheral circuit trigger function. */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);//外部触发DMA传输开启

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(M4_DMA1, DmaCh0, EVT_USART1_RI);

    /* Set DMA block transfer complete IRQ */
    stcIrqRegiCfg.enIRQn = Int009_IRQn;
    stcIrqRegiCfg.pfnCallback = &DmaBtcIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_DMA1_BTC0;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_02);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
               
                stcIrqRegiCfg.enIRQn = Int010_IRQn;//使能传输完成中断,也就是到了256个之后的中断,打算的是如果一包数据超过256个就不要了
    stcIrqRegiCfg.pfnCallback = &DmaTcIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_DMA1_TC0;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_02);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
}

使用特权

评论回复
地板
duxuqi|  楼主 | 2021-11-17 15:08 | 只看该作者
void Dma1_Ch1_Init(void)   DMA1通道1的配置函数,是给串口2的
{
                char * RxBuffer;
                RxBuffer = RxBuffer2;
       
                //TIMER0_Cmd(M4_TMR01, Tim0_ChannelA,Enable);
       
    stc_dma_config_t stcDmaInit;
    stc_irq_regi_conf_t stcIrqRegiCfg;

    /* Enable peripheral clock */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1 | PWC_FCG0_PERIPH_DMA2,Enable);

    /* Enable DMA. */
    DMA_Cmd(M4_DMA1,Enable);

    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u; /* 1 block */
    stcDmaInit.u32SrcAddr = ((uint32_t)(&M4_USART2->DR)+2ul); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)RxBuffer;     /* Set destination address. */
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix;  /* Set source address mode. */
    stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease;//地址自增
    stcDmaInit.stcDmaChCfg.enIntEn = Enable;       /* Enable interrupt. */
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;   /* Set data width 8bit. */
                stcDmaInit.u16TransferCnt = 256;//这里好像是传输的次数吧,先试试看了
    DMA_InitChannel(M4_DMA1, DmaCh1, &stcDmaInit);

    //选择DMA通道
    DMA_ChannelCmd(M4_DMA1, DmaCh1, Enable);

    /* 清除DMA标志 */
    DMA_ClearIrqFlag(M4_DMA1, DmaCh1, TrnCpltIrq);

    /* Enable peripheral circuit trigger function. */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(M4_DMA1, DmaCh1, EVT_USART2_RI);

    /* Set DMA block transfer complete IRQ */
    stcIrqRegiCfg.enIRQn = Int011_IRQn;
    stcIrqRegiCfg.pfnCallback = &DmaBtc_2_IrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_DMA1_BTC1;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_02);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
               
                stcIrqRegiCfg.enIRQn = Int012_IRQn;//使能传输完成中断,也就是到了256个之后的中断,打算的是如果一包数据超过256个就不要了
    stcIrqRegiCfg.pfnCallback = &DmaTc_2_IrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_DMA1_TC1;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_02);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
}

使用特权

评论回复
5
wubangmi| | 2021-11-17 15:39 | 只看该作者
TIMER0_BaseInit(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, &stcTimerCfg);
TIMER0_HardTriggerInit(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, &StcTimer0TrigInit);

你看一下这两个函数的原型,检查带进去的第二个参数值就知道问题出在哪里了。别为了图方便而想当然的认为带进去的参数就是对的。
Tim0_ChannelA | Tim0_ChannelB;你其实就是带了一个通道B的参数进去而已

使用特权

评论回复
6
m564522634| | 2021-11-17 17:53 | 只看该作者
软件问题

使用特权

评论回复
7
trucyw| | 2021-11-18 08:51 | 只看该作者
看不懂

使用特权

评论回复
8
fxyc87| | 2021-11-18 09:05 | 只看该作者
你对照着手册和寄存器一个一个查吧,
手册中文的,很好理解 。

使用特权

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

本版积分规则

1

主题

4

帖子

0

粉丝