cj泓 发表于 2023-3-20 20:47

M451RG6AE串口问题

你们好,我这边M451遇到个问题想咨询一下;
M451 UART问题咨询:
配置:UART2,921600bps(1ms约理论能发80字节,一秒至少8w字节吧);
发送:使用PDMA,发完一次PDMA中断一次;
接收:使能空闲中断以及FIFO满中断(UART_EnableInt(UART2, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));)
发送频率:1秒产生发送14000字节放入buffer;逻辑:任务每5毫秒取buffer,有多少发多少,算下来1秒内DMA约发送200次,每次70字节吧;
接收:不定时,上位机点击发就发;
问题:上位机发送数据到UART后,单片机容易死机;但是仿真器连着M451又复现不出来(是不是仿真单片机执行速度慢?);

cj泓 发表于 2023-3-20 20:47

初始化及配置如下
#define UART2_TX_DMA_CH 6

//初始化
SYS_ResetModule(UART2_RST);
PDMA_UART2_Init();
UART_Open(UART2, u32baudrate);
UART2->FIFO = (UART2->FIFO & (~ UART_FIFO_RFITL_Msk)) | UART_FIFO_RFITL_14BYTES;
UART_SetTimeoutCnt(UART2, 60);
UART_EnableInt(UART2, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
NVIC_EnableIRQ(UART2_IRQn);//打开接收中断


void PDMA_UART2_Init(void){
    PDMA_Open( /*(1 << UART2_RX_DMA_CH) | */ (1 << UART2_TX_DMA_CH));
        /* UART Tx PDMA channel configuration */
        PDMA->DSCT.CTL =
      (1 - 1) << PDMA_DSCT_CTL_TXCNT_Pos | /* Transfer count */
      PDMA_WIDTH_8 |/* Transfer width 8 bits */
      PDMA_DAR_FIX| /* Fixed destination address */
      PDMA_SAR_INC| /* Increment source address */
      PDMA_DSCT_CTL_TBINTDIS_Msk        | /* Table interrupt disabled */
      PDMA_REQ_SINGLE| /* Single request type */
      PDMA_OP_BASIC;        /* Basic mode */
        PDMA->DSCT.SA = (uint32_t)uart2_dma_buffer;/* Source address */
        PDMA->DSCT.DA = (uint32_t)&UART2->DAT;/* Destination address */
        /* Request source selection */
        PDMA_SetTransferMode(UART2_TX_DMA_CH, PDMA_UART2_TX, FALSE, 0);
        /* Enable PDMA Transfer Done Interrupt */
        PDMA_EnableInt(UART2_TX_DMA_CH, PDMA_INT_TRANS_DONE);

    NVIC_EnableIRQ(PDMA_IRQn);
    NVIC_SetPriority(PDMA_IRQn,4);
}

void PDMA_UART2_TxTest(uint16_t num){
        /* UART Tx PDMA channel configuration */
        PDMA->DSCT.CTL =
      (num - 1) << PDMA_DSCT_CTL_TXCNT_Pos | /* Transfer count */
      PDMA_WIDTH_8 |/* Transfer width 8 bits */
      PDMA_DAR_FIX| /* Fixed destination address */
      PDMA_SAR_INC| /* Increment source address */
      PDMA_DSCT_CTL_TBINTDIS_Msk        | /* Table interrupt disabled */
      PDMA_REQ_SINGLE| /* Single request type */
      PDMA_OP_BASIC;        /* Basic mode */
        PDMA->DSCT.SA = (uint32_t)uart2_dma_buffer;/* Source address */
        PDMA->DSCT.DA = (uint32_t)&UART2->DAT;/* Destination address */
        /* Request source selection */
        UART2->INTEN = UART2->INTEN | (1<<14);//UARTO DMA send enable
}

void PDMA_IRQHandler(void){   
    /* Get PDMA interrupt status */
    uint32_t status = PDMA_GET_INT_STATUS();
    if (status & PDMA_INTSTS_ABTIF_Msk){ /* Target Abort */
      PDMA_CLR_ABORT_FLAG(PDMA_ABTSTS_ABTIFn_Msk);   
    }
    else if(status & PDMA_INTSTS_TDIF_Msk){ /* Transfer Done */   
      /* UART Tx PDMA transfer done interrupt flag */      
      if (PDMA_GET_TD_STS() & (1<<UART3_TX_DMA_CH)){
            /* Clear PDMA transfer done interrupt flag */
            PDMA_CLR_TD_FLAG( (1<<UART3_TX_DMA_CH) );
            /* Disable UART Tx PDMA function */
            UART3->INTEN &= ~UART_INTEN_TXPDMAEN_Msk;
      }
                if (PDMA_GET_TD_STS() & (1<<UART2_TX_DMA_CH)){
            /* Clear PDMA transfer done interrupt flag */
            PDMA_CLR_TD_FLAG( (1<<UART2_TX_DMA_CH) );
            /* Disable UART Tx PDMA function */
            UART2->INTEN &= ~UART_INTEN_TXPDMAEN_Msk;
      }
    }      
}

void UART2_IRQHandler(void){
        uint32_t u32IntSts = UART2->INTSTS;
        uint8_t i;
    memset(rx_buff, 0, UART_RX_BUFF_SIZE_MAX);

        if(u32IntSts & UART_INTSTS_RXTOINT_Msk){//空闲中断
      rx_buff = UART_READ(UART2);
      if((bsp_uart_ctx.uart2_rx_cb != NULL)){
            bsp_uart_ctx.uart2_rx_cb(rx_buff, 1);
      }
      /*i = 0;
      while(UART_GET_RX_EMPTY(UART2) == 0){
            if(i >= UART_RX_BUFF_SIZE_MAX){
                //正常不可能进入这里,因为FIFO是14字节
                i = 0;
                if(bsp_uart_ctx.uart2_rx_cb != NULL){
                  bsp_uart_ctx.uart2_rx_cb(rx_buff, UART_RX_BUFF_SIZE_MAX);
                }
                memset(rx_buff, 0, UART_RX_BUFF_SIZE_MAX);
            }else{
                rx_buff = UART_READ(UART2);
            }
      }
      if((i > 0) && (bsp_uart_ctx.uart2_rx_cb != NULL)){
            bsp_uart_ctx.uart2_rx_cb(rx_buff, i);
      }*/
    }
        if(u32IntSts & UART_INTSTS_RDAINT_Msk){//14字节FIFI 满的中断
      i = 0;
      for(i=0; i<13; i++){
            if(UART_GET_RX_EMPTY(UART2) != 0){//再判断一下fifo是否为空吧
                break;
            }
            rx_buff = UART_READ(UART2);
      }
      if((i > 0) && (bsp_uart_ctx.uart2_rx_cb != NULL)){
            bsp_uart_ctx.uart2_rx_cb(rx_buff, i);
      }
    }
}
页: [1]
查看完整版本: M451RG6AE串口问题