-
OSR 最小值是 4,因此24Mhz時鐘模式下,LPUART最大波特率是 24/5 = 4.8Mbps,手冊中硬件的 LPUART最大的波特率是 80Mhz/4=20Mbps。80/13= 6.15Mbps波特率,這樣相對于 6Mhz就有 2.5%的誤差。
那如果用 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。
它在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;
}
}
}
-
寄存器
+關注
關注
31文章
5336瀏覽量
120230 -
定時器
+關注
關注
23文章
3246瀏覽量
114720 -
uart
+關注
關注
22文章
1235瀏覽量
101354 -
波特率
+關注
關注
2文章
307瀏覽量
34115 -
SDK
+關注
關注
3文章
1035瀏覽量
45900
原文標題:MIMXRT1060 FLEXIO UART 波特率
文章出處:【微信號:嵌入式 MCU,微信公眾號:嵌入式 MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論