硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1041|回复: 7
收起左侧

[UART] 请教个问题 rxne和dma接收同时打开能进rxne中断吗

[复制链接]

13

主题

54

回帖

93

积分

初级会员

积分
93
发表于 2022-12-9 21:07:23 | 显示全部楼层 |阅读模式
我这边同时打开了rxne和idle中断,接收数据使用dma做接收,然后触发空闲中断进去处理一帧数据。  现在我想打开rxne中断,然后对包头进行判断,但是我测试了下貌似不进rxne中断,所以我猜测原因是不是dma把串口dr寄存器提取了数据,导致rxne的标志位被清除,无法进入中断。如果这种方法可行的话,有没有例子可以参考。
下面是我的代码:
[C] 纯文本查看 复制代码

//初始化-----------------------------------------------------------------
        __HAL_RCC_GPIOD_CLK_ENABLE();			//使能GPIO时钟
        __HAL_RCC_USART3_CLK_ENABLE();			//使能USART时钟
        GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_9; 
        GPIO_Initure.Alternate=GPIO_AF7_USART3;	
        HAL_GPIO_Init(GPIOD,&GPIO_Initure);	   	//初始化
        //USART3_RTS
        GPIO_Initure.Pin=GPIO_PIN_12;
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;
        GPIO_Initure.Pull=GPIO_PULLUP;//GPIO_PULLDOWN
        GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_Initure.Alternate=GPIO_AF7_USART3;
        HAL_GPIO_Init(GPIOD,&GPIO_Initure);	   	//初始化
        USART3_EN(0);
        HAL_NVIC_SetPriority(USART3_IRQn,5,0);			        //抢占优先级
        USARTx_Set_Parameter(&TEST_USART_Handler,USARTx,bound,9,1,2);
        __HAL_UART_CLEAR_IT(&TEST_USART_Handler,UART_CLEAR_TCF);
        __HAL_UART_CLEAR_IDLEFLAG(&TEST_USART_Handler);
        __HAL_UART_ENABLE_IT(&TEST_USART_Handler,UART_IT_IDLE);//开启中断
      __HAL_UART_ENABLE_IT(&TEST_USART_Handler,UART_IT_RXNE);//开启中断
        HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 6, 0);//
        HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);//使能DAC中断通道
//中断--------------------------------------------------------------------

void USART3_IRQHandler(void)
{
    u16 len;
    BaseType_t xHigherPriorityTaskWoken;
    if(__HAL_UART_GET_IT(&TEST_USART_Handler,UART_IT_RXNE)!=RESET)  
    {
      __HAL_UART_DISABLE_IT(&TEST_USART_Handler,UART_IT_RXNE);
    }
    if(__HAL_UART_GET_IT(&TEST_USART_Handler,UART_IT_IDLE)!=RESET)  //接收中断
    {
        __HAL_UART_CLEAR_IDLEFLAG(&TEST_USART_Handler);                     //清除空闲中断标志(否则会一直不断进入中断)
        HAL_UART_DMAStop(&TEST_USART_Handler);			//11us,10us

        len  =  TEST_BUF_LEN - __HAL_DMA_GET_COUNTER(&UART3RxDMA_Handler);// 获取DMA中未传输的数据个数
        if(len>=TEST_BUF_LEN)
        {
            TESTRxFIFO.len[TESTRxFIFO.index] = 0;
        }
        else
        {
            if(len != 0)
            {
              __HAL_UART_ENABLE_IT(&TEST_USART_Handler,UART_IT_RXNE);
                TESTRxFIFO.len[TESTRxFIFO.index] = len;
                //发送消息
                if(uxQueueSpacesAvailable(TEST_RX_Msg))	//得到队列剩余大小
                {
                    xQueueSendFromISR(TEST_RX_Msg,&TESTRxFIFO.index,&xHigherPriorityTaskWoken);//向队列中发送数据pdTRUE
                    TESTRxFIFO.index++;
                    TESTRxFIFO.index%=FIFO_NUM;
                    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换
                }
            }
        }
        HAL_UART_Receive_DMA(&TEST_USART_Handler,TESTRxFIFO.buf[TESTRxFIFO.index],FIFO_BUF_LEN);
    }
    if(__HAL_UART_GET_IT(&TEST_USART_Handler,UART_IT_TC)!=RESET)  //发送完成中断
    {
      __HAL_UART_CLEAR_FLAG(&TEST_USART_Handler,UART_IT_TC);
      SET_BIT(TEST_USART_Handler.Instance->ICR,USART_ICR_TCCF);
      
      CLEAR_BIT(TEST_USART_Handler.Instance->CR1, USART_CR1_TCIE);

      /* Tx process is ended, restore huart->gState to Ready */
      TEST_USART_Handler.gState = HAL_UART_STATE_READY;

      xSemaphoreGiveFromISR(BinTEST_USART,&xHigherPriorityTaskWoken);
      portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
    
    if((USART3->ISR&0x000f)!=0)
    {
        USART3->ICR |= 0x0f;//1<<3
        HAL_UART_DMAStop(&TEST_USART_Handler);
        USARTx_DMA_Config(&TEST_USART_Handler,DMA2_Stream7,DMA2_Stream4);
        HAL_UART_Receive_DMA(&TEST_USART_Handler,TESTRxFIFO.buf[TESTRxFIFO.index],FIFO_BUF_LEN);
    }
}

回复

使用道具 举报

210

主题

1045

回帖

1685

积分

至尊会员

More we do, more we can do.

积分
1685
发表于 2022-12-10 00:36:57 | 显示全部楼层
手册中没写太明白,只说了常规用法,建议问下技术支持:
The RXP triggers an interrupt if the RXPIE bit is set or a DMA request if RXDMAEN is set
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106974
QQ
发表于 2022-12-10 11:19:13 | 显示全部楼层
是的,SPI,串口等,加入DMA接收后都是这样的。

image.png
回复

使用道具 举报

5

主题

65

回帖

80

积分

初级会员

积分
80
发表于 2022-12-10 16:06:40 | 显示全部楼层
可以进去,rxne当数据接受,IDLE当数据结束收尾
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-12-16 17:30:45 | 显示全部楼层
我去掉了dma 然后使用rxne判断包头 idle判断一帧数据,波特率9600实现了通信  但是在19200的时候 接收数据再判断返回就好像太慢
回复

使用道具 举报

210

主题

1045

回帖

1685

积分

至尊会员

More we do, more we can do.

积分
1685
发表于 2022-12-18 23:15:54 | 显示全部楼层
楼主的疑问也是我想弄明白的,于是写了代码测试。
结论:启用DMA接收数据又同时启用RXNE中断时,会触发中断,但不能检测到RXNE置位。

中断代码(说明,gUART4_RXE_Int_Cnt表示检测到RXNE标志次数,gUART4_Other_Int_Cnt表示进中断次数):
[C] 纯文本查看 复制代码
void UART4_IRQHandler(void)
{
  /* USER CODE BEGIN UART4_IRQn 0 */
  if(LL_USART_IsActiveFlag_RXNE(UART4) != 0)
  {
    gUART4_RXE_Int_Cnt++;
    Rx_Data <<= 8;
    Rx_Data += LL_USART_ReceiveData8(UART4);
  }
  /* USER CODE END UART4_IRQn 0 */
  /* USER CODE BEGIN UART4_IRQn 1 */
  gUART4_Other_Int_Cnt++;
  /* USER CODE END UART4_IRQn 1 */
}


动图(图中gUart4_Rx_Buf为DMA接收缓冲区):
DMA和RNXNE同时启用时会不会进中断.gif
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106974
QQ
发表于 2022-12-19 12:19:24 | 显示全部楼层
emwin 发表于 2022-12-18 23:15
楼主的疑问也是我想弄明白的,于是写了代码测试。
结论:启用DMA接收数据又同时启用RXNE中断时,会触发中 ...

很有意义的测试。
回复

使用道具 举报

13

主题

54

回帖

93

积分

初级会员

积分
93
 楼主| 发表于 2022-12-21 19:49:28 | 显示全部楼层
emwin 发表于 2022-12-18 23:15
楼主的疑问也是我想弄明白的,于是写了代码测试。
结论:启用DMA接收数据又同时启用RXNE中断时,会触发中 ...

我也是测试后 不行 然后把dma关了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-12 14:53 , Processed in 0.190446 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表