问答

汇集网友智慧,解决技术难题

21ic问答首页 - MM32G0001清除不了空闲中断

发送 函数 空闲中断 MM32G0001 MM32 串口空闲中断

MM32G0001清除不了空闲中断

桑有槐2024-07-03
用户手册说读取寄存器后会将标志位清零,但是在中断函数中读取了SR和DR寄存器还是会一直进入空闲中断,一直在发数据。串口发送函数注释掉也没用,应该和发送函数没有关系
回答 +关注 9
10608人浏览 8人回答问题 分享 举报
8 个回答
  • 我用别家MCU 空闲中断是收到正常数据后才使能空闲中断。空闲中断一次就禁止空闲中断。
    void USART1_IRQHandler(void)
    {
      uint16_t status = USART1->SR;  //read SR only once
      if ( status & USART_IT_RXNE )
    {
       RX_one[i ++ ] = USART1->>DR;
       USART1->CR1 |= USART_CR1_IDLEIEN; //启用空闲中断
        //......
    }
      if ((  status & USART_IT_IDLE )&&(USART1->CR1 & USART_CR1_IDLEIEN ) )
    {
        USART1->CR1 &= ~USART_CR1_IDLEIEN; //禁止空闲中断
        USART1->DR;
      //....................
    }
    }
    xch 2024-7-4 12:14 回复TA
    @桑有槐 :禁止空闲中断了怎么还进去? 
    桑有槐 2024-7-4 10:23 回复TA
    @xch :现在是按照你的这个写的,发现空闲中断是,接收数据前进入了一次,接收完数据后又进入了一次。不管在接收数据前有没有开启空闲中断都是这样 
    xch 2024-7-4 10:02 回复TA
    @桑有槐 :初始化时不开空闲中断。仅收到一个字符后才开空闲中断。 
    桑有槐 2024-7-4 09:46 回复TA
    MM32G0001用户手册里面写的是“空闲状态为总线在开始发送或者开始接收前的初始状态。”,好像每次接受前都会进入一次空闲中断 
  • void USART1_IRQHandler(void)
    {
      uint16_t status = USART1->SR;  //read SR only once
      if ( status & USART_IT_RXNE )
    {
       RX_one[i ++ ] = USART1->>DR;
        //......
    }
      if (  status & USART_IT_IDLE )
    {
        USART1->DR;
        volatile uint16_t test_sr =0;
       test_sr = USART1->SR; //给寄存器照个快照
      while(1)
    {
       test_sr  &= USART_IT_IDLE ;
    }
      //....................
    }
    }

    桑有槐 2024-7-4 09:38 回复TA
    我没太看懂这个....为什么要写一个while(1)啊 
  • 寄存器打扰了
    桑有槐 2024-7-4 08:49 回复TA
    是因为有别的地方读取了SR和DR吗? 
  • void USART1_IRQHandler(void)
    {
      uint16_t status = USART1->SR;  //read SR only once
      if ( status & USART_IT_RXNE )
    {
       RX_one[i ++ ] = USART1->>DR;
        //......
    }
      if (  status & USART_IT_IDLE )
    {
        USART->DR;
      //....................
    }
    }

    试试。
    xch 2024-7-4 09:10 回复TA
    @桑有槐 :可能是又空闲了会再次中断。 
    桑有槐 2024-7-4 08:48 回复TA
    还是不行,一直在进空闲中断 
  • 桑有槐 发表于 2024-7-3 16:22
    void USART1_IRQHandler(void)
    {
        int a=0;

    可能读多次SR 再读DR就没法清除了。
  • void USART1_IRQHandler(void)
    {
        int a=0;

        if ((RESET != USART_GetITStatus(USART1, USART_IT_PE)) ||
            (RESET != USART_GetITStatus(USART1, USART_IT_ERR)))
        {
            a=USART1->SR;
            a=USART1->DR;//软件序列清除IDLE标志位
            USART_SendData(USART1,52);
        }

        if (RESET != USART_GetITStatus(USART1, USART_IT_RXNE))
        {
            RX_one[i] = USART_ReceiveData(USART1);
            RX_flat = 0;
            USART_SendData(USART1,RX_one[i]);
            i++;
        }

        if (RESET != USART_GetITStatus(USART1, USART_IT_IDLE))
        {
            a=USART1->SR;
            a=USART1->DR;//软件序列清除IDLE标志位

            RX_one[i] = '\0';USART_SendData(USART1,53);
            RX_flat = 1;

        }   
    }

您需要登录后才可以回复 登录 | 注册