STM32F407 使用USART+DMA方式有些小问题

2019-07-20 19:00发布

本来最近在学习STM32F407 使用USART+DMA方式接收数据。思路如下: 利用USART3的空闲中断,获取USART接收到的数据个数。

USART3配置:空闲中断 DMA配置:数据传输完成中断
现在出现的问题是:
进入USART空闲中断后: if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) {  USART_ClearITPendingBit(USART3,USART_IT_IDLE); DMA_Cmd(DMA1_Stream1, DISABLE); //关闭DMA,防止处理其间有数据 USART_ITConfig(USART3,USART_IT_IDLE,DISABLE); //关闭串口空闲中断                 DATA_LEN = MaxBufLength - DMA_GetCurrDataCounter(DMA1_Stream1);  //获取剩余长度 if(DATA_LEN > 0) { //接收到了数据的 Usart3.len = DATA_LEN; USART3_RxOneFrameFlag = 1; USART3_ProcessIRQSrc(); } DMA1_Stream1->NDTR =512; //重装填 DMA1_Stream1->M0AR = (uint32_t)USART3_RECEIVE_DATA; USART_ITConfig(USART3,USART_IT_IDLE,ENABLE); //使能串口空闲中断 //读SR后读DR清除Idle i = USART3->SR; i = USART3->DR; DMA_Cmd(DMA1_Stream1, ENABLE); //处理完,重开DMA } DMA的Buf设置为512,USART3接收的数据为10个。
当USART3中断执行完后,又进入了DMA中断,不知道是怎么进来的,而且我也测试过,进入的是数据传输完成中断。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
hhlh2l
1楼-- · 2019-07-20 19:23
这个是这样的:
1,初始化串口,允许串口接收中断
2,配置好串口的DMA,不允许中断
3,在串口的接收中断服务函数里面关闭接收中断,开启空闲中断
4,这样才会当串口总线空闲时会发生正确的空闲中断,
5,数据接收的长度是你配置的DMA最大传输长度-当前DMA->NDTR的值
串口和DMA自己配置了,中断处理的例程如下:
void USART6_ISR(void)
{
    //OS_ERR err;  
    volatile uint32_t i;
    if(USART6->CR1 & RXNEIE)                                                    //接收中断
    {  
        USART6->CR3 |= DMAR;                                                    //打开USART3的DMA接收
        USART6->CR1 &=~RXNEIE;                                               //关闭接受中断
        USART6->CR1 |= IDLEIE;                                                  //打开空闲中断
        
        DMA_ClearITPendingBit(DMA2_Stream1,DMA_IT_TCIF1);  //清除串口对应DMA的标记信息等
        DMA_Cmd(DMA2_Stream1,ENABLE);                                 //打开DMA,在串口的DMA初始化中配置好串口接收数据的存储地址,
                                                                                                 //因为之前是配置好DMA的,只不过没有打开,此时串口接收到的第一个数据已经存储到对应的位置了,
        //写一个事件标志,处于接收状态
        //OSFlagPost(&usartFlagGrp_A, usart_6_rxing, OS_OPT_POST_FLAG_SET|OS_OPT_POST_NO_SCHED, &err);
    }

    else if(USART6->CR1 & IDLEIE)                                              //空闲中断,
    {
        DMA_Cmd(DMA2_Stream1,DISABLE);                               //关闭DMA通道
        USART_RX[usart_6-1].rxLen = usartDataLength-DMA2_Stream1->NDTR;        //获取接收的数据长度    USART_RX[usart_6-1].rxLen这个换成你的数据长度接收位置 
        DMA_SetCurrDataCounter(DMA2_Stream1, usartDataLength);                          //usartDataLength是我定义的串口默认接收数据最大长度
        
        i = USART6->SR;
        i = USART6->DR;
        USART6->CR3 &=~DMAR;                                                   //关闭USART3的DMA接收
        USART6->CR1 &=~IDLEIE;                                                 //关闭空闲中断
        USART6->CR1 |= RXNEIE;                                                   //重新允许接收中断,也可以在数据处理好了后在接收
        //清除串口的接收状态
        //OSFlagPost(&usartFlagGrp_A, usart_6_rxing, OS_OPT_POST_FLAG_CLR|OS_OPT_POST_NO_SCHED, &err);
        //OSTaskQPost(&USART_RX_task_TCB, (void *)0, usart_6, OS_OPT_POST_FIFO|OS_OPT_POST_NO_SCHED, &err); 
    }
}

当需要再次转入接收时,
{
            i= USART6->SR;
            i= USART6->DR;
            USART6->CR1 |= RXNEIE; 
}
正点原子
2楼-- · 2019-07-21 00:27
 精彩回答 2  元偷偷看……
jungle1989
3楼-- · 2019-07-21 03:25
再顶。。。。有大神帮忙试下的么?
linbeithree
4楼-- · 2019-07-21 04:31
这个我建议从定时器中断做,比如10ms读取dma寄存器值,便知道现在接受多少数据,把buffer设置大一点,不需要dma满了再中断,没必要。
simplelifeNick
5楼-- · 2019-07-21 08:09
 精彩回答 2  元偷偷看……
尼泊尔123
6楼-- · 2019-07-21 11:11
回复【5楼】simplelifeNick:
---------------------------------
空闲中断 只连接 RX  TX  引脚就可以工作吗?还是需要连接 CTS  RTS 谢谢  还望回复啊

一周热门 更多>