MIMXRT1060 FLEXIO UART波特率

电子说

1.3w人已加入

描述

uart-

    OSR 最小值是 4,因此24Mhz时钟模式下,LPUART最大波特率是 24/5 = 4.8Mbps,手册中硬件的 LPUART最大的波特率是 80Mhz/4=20Mbps。80/13= 6.15Mbps波特率,这样相对于 6Mhz就有 2.5%的误差。

uart

uart

uart

    那如果用 FlexIO外设实现 UART波特率可以达到 6Mbps么?    

    将FlexIO用于UART RX时,RM参考手册的注意事项:“FlexIO数据只在每个位的中间采样一次。可以使用另一个定时器对传入数据进行毛刺过滤”。保持FlexIO时钟与RM参考手册中的波特率的倍数相同。RM参考手册中的UART接收和UART发射配置表将所使用的每个FlexIO定时器的TIMCMP设置为0xF01。这意味着波特率是FlexIO时钟频率的1/4。FlexIO不支持奇偶校验位的自动验证。

    使用了SDK中的Flexio_uart示例,并使用了flexio_uart驱动程序,只对这些频率/波特率进行了一些细微的更改。示例使用480MHz的PLL3作为FlexIO的时钟源。将FLEXIO2_CLK_PRED除法器设置为(4+1),将FLEXIO2_CLK_PODF除法器设为(3+1),从而提供 24MHz(480/5/4)的FlexIO时钟。对于驱动程序,将flexio_uart_config_t.baudRate_Bps设置为6000000。然后,驱动程序计算两个定时器的TIMCMP寄存器=0xF01。

uart

    它在IMXRT1060-EVKB板上运行,SDK v2.12.1,如下代码简单修改。SDK_2_12_1_MIMXRT1062xxxxBoardsevkbmimxrt1060driver_examplesflexiouartedma_transfer 此应用程序仅在引脚GPIO_B0_05上传输,RX设置在引脚GPIO_B0_06上。

  IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_FLEXIO2_FLEXIO05, 0U); 

  IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_FLEXIO2_FLEXIO06, 0U); 

  IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_FLEXIO2_FLEXIO05, 0x10B0U); 

  IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_FLEXIO2_FLEXIO06, 0x10B0U);

#include "pin_mux.h"

#include "clock_config.h"

#include "board.h"

#include "fsl_flexio_uart_edma.h"

#include "fsl_dmamux.h"

#define BOARD_FLEXIO_BASE  FLEXIO2

#define FLEXIO_UART_TX_PIN 5U

#define FLEXIO_UART_RX_PIN 6U

/* Select USB1 PLL (480 MHz) as flexio clock source */

#define FLEXIO_CLOCK_SELECT (3U)

/* Clock pre divider for flexio clock source */

#define FLEXIO_CLOCK_PRE_DIVIDER (4U)

/* Clock divider for flexio clock source */

#define FLEXIO_CLOCK_DIVIDER (3U)

#define FLEXIO_CLOCK_FREQUENCY

    (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / (FLEXIO_CLOCK_PRE_DIVIDER + 1U) / (FLEXIO_CLOCK_DIVIDER + 1U))

#define FLEXIO_DMA_REQUEST_BASE             kDmaRequestMuxFlexIO2Request0Request1

#define EXAMPLE_FLEXIO_UART_DMAMUX_BASEADDR DMAMUX

#define EXAMPLE_FLEXIO_UART_DMA_BASEADDR    DMA0

#define FLEXIO_UART_TX_DMA_CHANNEL          0U

#define FLEXIO_UART_RX_DMA_CHANNEL          1U

#define FLEXIO_TX_SHIFTER_INDEX             0U

#define FLEXIO_RX_SHIFTER_INDEX             2U

#define EXAMPLE_TX_DMA_SOURCE               kDmaRequestMuxFlexIO2Request0Request1

#define EXAMPLE_RX_DMA_SOURCE               kDmaRequestMuxFlexIO2Request2Request3

#define ECHO_BUFFER_LENGTH 8

void FLEXIO_UART_UserCallback(FLEXIO_UART_Type *base,

                              flexio_uart_edma_handle_t *handle,

                              status_t status,

                              void *userData);

flexio_uart_edma_handle_t g_uartHandle;

FLEXIO_UART_Type uartDev;

edma_handle_t g_uartTxEdmaHandle;

edma_handle_t g_uartRxEdmaHandle;

AT_NONCACHEABLE_SECTION_INIT(uint8_t g_tipString[]) =

    "Flexio uart edma example Board receives 8 characters then sends them out Now please input: ";

AT_NONCACHEABLE_SECTION_INIT(uint8_t g_txBuffer[ECHO_BUFFER_LENGTH]) = {0};

AT_NONCACHEABLE_SECTION_INIT(uint8_t g_rxBuffer[ECHO_BUFFER_LENGTH]) = {0};

volatile bool rxBufferEmpty                                          = true;

volatile bool txBufferFull                                           = false;

volatile bool txOnGoing                                              = false;

volatile bool rxOnGoing                                              = false;

/* UART 用户回调函数 */

void FLEXIO_UART_UserCallback(FLEXIO_UART_Type *base,

                              flexio_uart_edma_handle_t *handle,

                              status_t status,

                              void *userData)

{

    userData = userData;

    if (kStatus_FLEXIO_UART_TxIdle == status)

    {

        txBufferFull = false;

        txOnGoing    = false;

    }

    if (kStatus_FLEXIO_UART_RxIdle == status)

    {

        rxBufferEmpty = false;

        rxOnGoing     = false;

    }

}

int main(void)

{

    flexio_uart_config_t userconfig;

    flexio_uart_transfer_t xfer;

    flexio_uart_transfer_t sendXfer;

    status_t result = kStatus_Success;

    edma_config_t config;

    BOARD_ConfigMPU();

    BOARD_InitPins();

    BOARD_BootClockRUN();

    /* Flexio 时钟设置*/

    CLOCK_SetMux(kCLOCK_Flexio2Mux, FLEXIO_CLOCK_SELECT);

    CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, FLEXIO_CLOCK_PRE_DIVIDER);

    CLOCK_SetDiv(kCLOCK_Flexio2Div, FLEXIO_CLOCK_DIVIDER);

    /*

     * config.enableUart = true;

     * config.enableInDoze = false;

     * config.enableInDebug = true;

     * config.enableFastAccess = false;

     * config.bitCountPerChar = kFLEXIO_UART_8BitsPerChar;

     */

    FLEXIO_UART_GetDefaultConfig(&userconfig);

    userconfig.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;

    userconfig.enableUart   = true;

    uartDev.flexioBase      = BOARD_FLEXIO_BASE;

    uartDev.TxPinIndex      = FLEXIO_UART_TX_PIN;

    uartDev.RxPinIndex      = FLEXIO_UART_RX_PIN;

    uartDev.shifterIndex[0] = FLEXIO_TX_SHIFTER_INDEX;

    uartDev.shifterIndex[1] = FLEXIO_RX_SHIFTER_INDEX;

    uartDev.timerIndex[0]   = 0U;

    uartDev.timerIndex[1]   = 1U;

    result = FLEXIO_UART_Init(&uartDev, &userconfig, FLEXIO_CLOCK_FREQUENCY);

    if (result != kStatus_Success)

    {

        return -1;

    }

    /*初始化 DMA*/

    DMAMUX_Init(EXAMPLE_FLEXIO_UART_DMAMUX_BASEADDR);

    EDMA_GetDefaultConfig(&config);

    EDMA_Init(EXAMPLE_FLEXIO_UART_DMA_BASEADDR, &config);

    /* 为 TX&RX 设置 DMA 通道 */

    DMAMUX_SetSource(EXAMPLE_FLEXIO_UART_DMAMUX_BASEADDR, FLEXIO_UART_TX_DMA_CHANNEL, EXAMPLE_TX_DMA_SOURCE);

    DMAMUX_SetSource(EXAMPLE_FLEXIO_UART_DMAMUX_BASEADDR, FLEXIO_UART_RX_DMA_CHANNEL, EXAMPLE_RX_DMA_SOURCE);

    DMAMUX_EnableChannel(EXAMPLE_FLEXIO_UART_DMAMUX_BASEADDR, FLEXIO_UART_TX_DMA_CHANNEL);

    DMAMUX_EnableChannel(EXAMPLE_FLEXIO_UART_DMAMUX_BASEADDR, FLEXIO_UART_RX_DMA_CHANNEL);

    EDMA_CreateHandle(&g_uartTxEdmaHandle, EXAMPLE_FLEXIO_UART_DMA_BASEADDR, FLEXIO_UART_TX_DMA_CHANNEL);

    EDMA_CreateHandle(&g_uartRxEdmaHandle, EXAMPLE_FLEXIO_UART_DMA_BASEADDR, FLEXIO_UART_RX_DMA_CHANNEL);

    FLEXIO_UART_TransferCreateHandleEDMA(&uartDev, &g_uartHandle, FLEXIO_UART_UserCallback, NULL, &g_uartTxEdmaHandle, &g_uartRxEdmaHandle);

    /* 发送 g_tipString  */

    xfer.data     = g_tipString;

    xfer.dataSize = sizeof(g_tipString) - 1;

    txOnGoing     = true;

    FLEXIO_UART_TransferSendEDMA(&uartDev, &g_uartHandle, &xfer);

    /* 等待发送完成 */

    while (txOnGoing)

    {

    }

    /* 开始应答 */

    sendXfer.data        = g_txBuffer;

    sendXfer.dataSize    = ECHO_BUFFER_LENGTH;

    while (1)

    {

        /* If TX is idle and g_txBuffer is full, start to send data. */

        if ((!txOnGoing) && txBufferFull)

        {

            txOnGoing = true;

            FLEXIO_UART_TransferSendEDMA(&uartDev, &g_uartHandle, &sendXfer);

        }

        /* 如果 g_txBuffer为空,加载 g_txBuffer */

        if (!txBufferFull)

        {

            memcpy(g_txBuffer, "UUUUUUUU", ECHO_BUFFER_LENGTH);

            txBufferFull  = true;

        }

    }

}

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分