STM32F4 UART1 DMA收发的一些问题解决

早些时间写过一篇“STM32F4 UART1 DMA发送和接收不定长度数据”的博文。很多转载的都不注明出处的。后来就没再怎么用过F4的uart  也有朋友反映过会莫名的进接受完成中断,但是实际接受的数据量并没有达到设置的DMA接受长度,应该不会进DMA接收中断,我也没搞明白就不了了之了,可看这个链接:http://www.openedv.com/forum.php?mod=viewthread&tid=76091&extra=

最近有个项目用到了这个功能。之前能接受发送到程序,下载到单片机里面怎么都不行了。很调了很久发现了以下几个问题

1.串口DMA接收中断、DMA发送中断、空闲中断的优先级是有影响。按照以下设置faxi发现不会进接收wa完成中断 

    //Usart1 NVIC 空闲中断
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;       
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        
    NVIC_Init(&NVIC_InitStructure);    

    //DMA NVIC  发送完成中断
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream5_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
    NVIC_Init(&NVIC_InitStructure); 

    //DMA NVIC  接收完成中断
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream7_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
    NVIC_Init(&NVIC_InitStructure);

 

这样看系统随时可能接收数据 所以优先级高、发送完中断次之、一般不会一次性接收超过DMA设置长度的数据量所以优先级最低。这种youx优先级发现就不会进jie接收完成中断。如果接收完成中断高于空闲中断。发现进入 空闲中断后 ,此时接收中断会打断空闲中断,清掉标志位以后读不到接收的数据长度。

 

2.空闲中断里面读取了DMA接收的数据量,在这里注意 在关闭DMA接收后 需要先读接收的数据量  再清除标志。如下:

//¿ÕÏÐÖжÏ
void USART1_IRQHandler(void)
{
    u16 data;
    if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)
    {    
        data = USART1->SR;
        data = USART1->DR;
        
        DMA_Cmd(DMA2_Stream5, DISABLE); //¹Ø±ÕDMA,·ÀÖ¹´¦ÀíÆä¼äÓÐÊý¾Ý
        UART1_ReceiveSize =RECEIVE_BUF_SIZE - DMA_GetCurrDataCounter(DMA2_Stream5);
        if(UART1_ReceiveSize !=0)
        {
            //OSSemPost(DMAReceiveSize_Sem);
        }

        DMA_ClearFlag(DMA2_Stream5,DMA_FLAG_TCIF5 | DMA_FLAG_FEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_HTIF5);//
        //DMA_SetCurrDataCounter(DMA2_Stream5, RECEIVE_BUF_SIZE);
        /*------------------------- DMAy Streamx NDTR Configuration ----------------*/
        /* Write to DMAy Streamx NDTR register */
        DMA2_Stream5->NDTR = RECEIVE_BUF_SIZE;

        /*------------------------- DMAy Streamx PAR Configuration -----------------*/
        /* Write to DMAy Streamx PAR */
    //    DMAy_Streamx->PAR = DMA_InitStruct->DMA_PeripheralBaseAddr;

        /*------------------------- DMAy Streamx M0AR Configuration ----------------*/
        /* Write to DMAy Streamx M0AR */
        DMA2_Stream5->M0AR = (u32)ReceiveBuff;
        
        DMA_Cmd(DMA2_Stream5, ENABLE);     //

    }

否则先清除标志会导致DMA的NDTR清零        读不到接收的数据量。

 

有问题再补充;

 

在使用STM32F103的DMA接收不定长度的USART数据时,可以按照以下步骤进行操作: 1. 初始化USART和DMA:首先要初始化USART和DMA的相关寄存器和配置信息。设置USART的工作模式、波特率、数据位、停止位等参数,并使能DMA接收模式,配置DMA的通道、缓冲区以及数据传输方向等。 2. 配置DMA的数据传输:通过DMA的通道选择寄存器,选择对应的USART接收通道。设置DMA的传输数据长度为一个较大的值,如1024字节(该值可根据实际需求进行调整)。设置DMA传输模式为循环传输,以便能够接收不定长度的数据。 3. 配置接收缓冲区:申请一个足够大的接收缓冲区,并使能DMA的传输完成中断。在DMA传输完成中断中,将接收的数据复制到指定的缓冲区中,并记录接收到的数据长度。 4. 启动数据传输:使用USART的接收中断或DMA传输请求来启动数据传输。当USART接收到数据或DMA传输请求发生时,DMA开始将接收到的数据传输到配置好的缓冲区中。 5. 处理接收数据:在DMA传输完成中断中,通过获取数据长度的方式来区分有效数据和无效数据。根据实际需求进行处理,比如将接收到的数据存储到内存中、发送给其他设备或进行其他操作。 需要注意的是,在DMA传输过程中,要使用合适的同步方式来确保数据的正确传输。可以选择使用FreeRTOS等操作系统或者使用信号量等方式来实现同步。此外,在接收缓冲区大小设计时要考虑到数据的最大长度以及处理数据的速度,以避免数据溢出或丢失。 总之,通过合适的配置USART和DMA,结合适当的处理方式,即可实现STM32F103的DMA接收不定长度的USART数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值