请选择 进入手机版 | 继续访问电脑版
查看: 1333|回复: 4

[求助] MKV30的串口DMA问题

[复制链接]
  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
    发表于 2021-1-8 11:11:42 | 显示全部楼层 |阅读模式
    最近使用串口DMA,因为串口接收到数据之后需要做回复和数据处理,而且两次串口指令之间的间隔非常短。所以使用了DMA,但是在使用中发现启动DMA后,去让MCU干点其他事,就会因为时间不够导致数据发送不完整。好像DMA启动之后MCU并不能释放串口发送的进程。是我的启动代码有问题吗?
    /* UART user callback */
    void UART_UserCallback(UART_Type *base, uart_edma_handle_t *handle, status_t status, void *userData)
    {
        userData = userData;

        if (kStatus_UART_TxIdle == status)
        {
            txBufferFull = false;
            txOnGoing    = false;
        }

        if (kStatus_UART_RxIdle == status)
        {
            rxBufferEmpty = false;
            rxOnGoing     = false;
        }
    }

    const uart_config_t UART0_config = {
      .baudRate_Bps = 2500000,
      .parityMode = kUART_ParityDisabled,
      .txFifoWatermark = 0,
      .rxFifoWatermark = 1,
      .idleType = kUART_IdleTypeStartBit,
      .enableTx = true,
      .enableRx = true
    };

    void UART0_init(void) {
      UART_Init(UART0_PERIPHERAL, &UART0_config, UART0_CLOCK_SOURCE);
      UART_EnableInterrupts(UART0_PERIPHERAL,  kUART_RxDataRegFullInterruptEnable);
            NVIC_SetPriority(UART0_SERIAL_RX_TX_IRQN,0);
      /* Enable interrupt UART0_RX_TX_IRQn request in the NVIC */
      EnableIRQ(UART0_SERIAL_RX_TX_IRQN);
    }
        uart_transfer_t sendXfer;
    void DMA_init(void)
    {
            edma_config_t config;
            uart_transfer_t xfer;


        uart_transfer_t receiveXfer;
        /* Init DMAMUX */
        DMAMUX_Init(EXAMPLE_UART_DMAMUX_BASEADDR);
        /* Set channel for UART */
        DMAMUX_SetSource(EXAMPLE_UART_DMAMUX_BASEADDR, UART_TX_DMA_CHANNEL, UART_TX_DMA_REQUEST);
        DMAMUX_EnableChannel(EXAMPLE_UART_DMAMUX_BASEADDR, UART_TX_DMA_CHANNEL);
        /* Init the EDMA module */
        EDMA_GetDefaultConfig(&config);
        EDMA_Init(EXAMPLE_UART_DMA_BASEADDR, &config);
        EDMA_CreateHandle(&g_uartTxEdmaHandle, EXAMPLE_UART_DMA_BASEADDR, UART_TX_DMA_CHANNEL);
        /* Create UART DMA handle. */
        UART_TransferCreateHandleEDMA(UART0_PERIPHERAL, &g_uartEdmaHandle, NULL, NULL, &g_uartTxEdmaHandle,
                                      &g_uartRxEdmaHandle);


        /* Start to echo. */
        sendXfer.data        = demoRingBuffer;
        sendXfer.dataSize    = 11;
            txOnGoing     = true;


    }
    /*****************启动DMA************************/
    void DMA_Tx(uart_edma_handle_t *handle)
    {


                    edma_transfer_config_t xferConfig;
            handle->txDataSizeAll = 11;
            /* Prepare transfer. */
            EDMA_PrepareTransfer(&xferConfig, demoRingBuffer, sizeof(uint8_t), (uint32_t *)(uint32_t) & (UART0_PERIPHERAL->D),
                                 sizeof(uint8_t), sizeof(uint8_t), 11, kEDMA_MemoryToPeripheral);


            /* Submit transfer. */
            (void)EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
                   
            EDMA_StartTransfer(handle->txEdmaHandle);


            /* Enable UART TX EDMA. */
                    UART0_PERIPHERAL->C5 |= (uint8_t)UART_C5_TDMAS_MASK;
                    UART0_PERIPHERAL->C2 |= (uint8_t)UART_C2_TIE_MASK;
    }

    *******************************************************
    中断代码:
    /* UART0_RX_TX_IRQn interrupt handler */
    uint8_t data;
    void UART0_SERIAL_RX_TX_IRQHANDLER(void) {
                    data = UART0_PERIPHERAL->D;

                    if(data == 0x1A)
                    {               
                            BOARD_INITPINS_RS485EN_GPIO->PSOR = GPIO_FIT_REG(1u<<BOARD_INITPINS_RS485EN_PIN);
                            DMA_Tx(&g_uartEdmaHandle);        //*****启动DMA
                   
                            while((kUART_TransmissionCompleteFlag & UART_GetStatusFlags(UART0_PERIPHERAL) )== 0);                       
                            BOARD_INITPINS_RS485EN_GPIO->PCOR = GPIO_FIT_REG(1u<<BOARD_INITPINS_RS485EN_PIN);
    //                        ADC_VALUE_change();//数据处理,若把此处理代码放到启动DMA后面。会造成数据发送不完整,如果放在此处,会因为处理数据时间太长而导致下一次中断得不到相应。(数据处理中太多三角函数,耗时超过8us)       
                                           
                    }
                    if(data==0xAA)
                    {
                            Angle_Collection();
                    }
                    UART_ClearStatusFlags(UART0_PERIPHERAL, (uint32_t)kUART_RxDataRegFullFlag | kUART_RxOverrunFlag);
            SDK_ISR_EXIT_BARRIER;
    }

    我知道答案 目前已有4人回答
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
     楼主| 发表于 2021-1-11 13:15:52 | 显示全部楼层
    自己说明一下,芯片和代码都没问题,是我的检测设备有问题,
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    4

    帖子

    0

    新手上路

    Rank: 1

    积分
    44
    最后登录
    2022-11-28
    发表于 2021-10-2 14:42:48 | 显示全部楼层
    看了楼主发到帖子,楼主莫非在做17位磁编?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
     楼主| 发表于 2021-10-8 15:02:27 | 显示全部楼层
    edwardzch 发表于 2021-10-2 14:42
    看了楼主发到帖子,楼主莫非在做17位磁编?

    是的,但是ADC采集这边很难突破,用DMA不好处理
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    4

    帖子

    0

    新手上路

    Rank: 1

    积分
    44
    最后登录
    2022-11-28
    发表于 2021-10-11 13:18:06 | 显示全部楼层
    鹰宫璞爱惟 发表于 2021-10-8 15:02
    是的,但是ADC采集这边很难突破,用DMA不好处理

    你是想AD采样值通过DMA传输吗?
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-3-29 14:48 , Processed in 0.135105 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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