关于华大F460 DMA加串口空闲接受出现的问题
各位大佬们好,本人也算是头一次使用华大单片机并选择了F460JEUA这款作为开发用。由于串口之前采用的是中断接收感觉有点问题就切换成了DMA加空闲中断接受,系统用的是RT THREAD NANO。但是目前遇到了一个极度奇葩的问题,百思不得其解,望各位大佬能抽空看看帮忙指导指导了。情况是,昨天的时候,把串口1配置成了这样的模式然后经过测试,效果非常的好。今天把串口2也配置成这样了,然后串口1当场出bug了,串口1的DMA接收正常,接收中断正常,就是串口空闲中断无论如何都进不去。而反之,串口2的一切却都正常,百试百灵。附上代码给各位参考参考吧,先感谢帮忙了。 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);
} 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);
} 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);
} TIMER0_BaseInit(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, &stcTimerCfg);
TIMER0_HardTriggerInit(M4_TMR01, Tim0_ChannelA | Tim0_ChannelB, &StcTimer0TrigInit);
你看一下这两个函数的原型,检查带进去的第二个参数值就知道问题出在哪里了。别为了图方便而想当然的认为带进去的参数就是对的。
Tim0_ChannelA | Tim0_ChannelB;你其实就是带了一个通道B的参数进去而已 软件问题 看不懂 你对照着手册和寄存器一个一个查吧,
手册中文的,很好理解 。
页:
[1]