RT1064学习笔记-LPUART

各个模块需要的时钟部件在数据手册的13.5 System Clocks

串口时钟使能

设置LPUART波特率时钟

uart的时钟路径
在这里插入图片描述
管理串口时钟的寄存器CCM_CSCDR1.

在此寄存器中我们可以设置UART_CLK_ROOT的时钟

在这里插入图片描述
在这里插入图片描述
上图中,第六位UART_CLK_SEL一般设置为0,即选择pll3_80m

而UART_CLK_PODF则为一个6位的分频器,将80MHz的频率分频作为UART_CLK_ROOT

一般设置为1分频,所以UART_CLK_ROOT=80MHz

使能LPPUART1时钟

在这里插入图片描述
lpuart1_ipg_clk 时钟,这是串口 1 的外设时钟,用于驱动串口 1 的正常运行(除波特率发生器以外的时钟,都由该时钟驱动),该时钟来自 IPG_CLK_ROOT,由 CCGR5[CG12]控制。

lpuart1_ipg_clk_s 时钟,这是串口 1 的访问时钟,必须开启该时钟,才可以访问串口 1 相关寄存器,该时钟来自 IPG_CLK_ROOT,由 CCGR5[CG12]控制。

lpuart1_lpuart_baud_clk 时钟,这是串口 1 波特率发生器的时钟源,来自:UART_CLK_ROOT,可以把它看作是 lpuart1_lpuart_baud_gateed_clk 时钟的上一级,它无需开关控制。

lpuart1_lpuart_baud_gateed_clk 时钟,这是串口 1 波特率发生器的时钟,该时钟同样是来自:UART_CLK_ROOT,串口 1 的波特率生成和这个时钟直接相关,由 CCGR5[CG12]控制。

1.时钟使能

需要使能3个时钟,lpuart1_ipg_clk、lpuart1_ipg_clk_s 、lpuart1_lpuart_baud_gateed_clk 这三个时钟均由CCGR5[CG12]控制
在这里插入图片描述
设置这两位为1

2.串口波特率设置

串口波特率设置。每个串口都有一个自己独立的波特率寄存器 BAUD,通过设置该寄存器就可以达到配置不同波特率的目的。

3.串口设置

LPUART Control Register (CTRL)

在这里插入图片描述RIE 位(位 21)为接收中断使能位,设置该位为 1,则当 STAT 寄存器的 RDRF 位(接收数据寄存器满标志)为 1 时,将产生串口中断;

TE 位(位 19)为串口发送使能位,设置该位为 1,则开启串口发送功能;

RE 位(位 18)为串口接收使能位,设置该位为 1,则开启串口接收功能;

M 位(位 4)为 9/8 位模式选择位,设置该位为 0,则使用 8 位数据模式;

PE 位(位 1)为校验使能位,设置该位为 0,则不使用硬件奇偶校验。

4.数据接收和发送

LPUART Data Register (DATA)
在这里插入图片描述
当我们需要发送数据的时候,往 LPUARTx→DATA(x=1~8)寄存器写入你想要发送的数据,然后加载到 Tx Buffer,通过串口发送出去。

而当有串口数据接收到,需要读取出来的时候,通过读取 LPUARTx→DATA 寄存器,即可读取 Rx Buffer,将数据读取出来。

这里 Rx/Tx Buffer实际上上就是 RX/TX FIFO,因为我们没设置 FIFO,默认 Rx/Tx Buffer 就是 1 个字符。

5.串口状态

LPUART Status Register (STAT)

在这里插入图片描述
21位:RDRF(接收数据寄存器满标志),当该位被置 1 的时候,就是提示已经有数据被接收到了(存放在 Rx Buffer),并且可以读出来了。这时候我们要做的就是尽快去读取 LPUARTx→DATA,通过读 LPUARTx→DATA 可以将该位清零。

23位:TDRE(发送数据寄存器空标志),当该位被置位的时候,表示 Tx Buffer 里面的数据已经被发送完成了。如果设置了这个位的中断,则会产生中断。通过往 LPUARTx→DATA 寄存器写入数据可以将该位清零。

FSL库中的API函数

在fsl_lpuart.c 和 fsl_lpuart.h 中

串口初始化函数 LPUART_Init()

status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
  1. base:LPUART1~LPUART8。

  2. config 用来设置串口的初始化参数

    lpuart_config_t 定义如下:

    typedef struct _lpuart_config
    {
        uint32_t baudRate_Bps;            /*!< LPUART baud rate  波特率*/
        lpuart_parity_mode_t parityMode;  /*!< Parity mode, disabled (default), even, odd 奇偶校验*/
        lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven 数据长度*/
        bool isMsb;                       /*!< Data bits order, LSB (default), MSB 是否为MSB*/
    #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
        lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits 停止位 */
    #endif
    #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
        uint8_t txFifoWatermark; /*!< TX FIFO watermark */
        uint8_t rxFifoWatermark; /*!< RX FIFO watermark */
    #endif
    #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
        bool enableRxRTS;                         /*!< RX RTS enable 接收RTS*/
        bool enableTxCTS;                         /*!< TX CTS enable 发送RTS*/
        lpuart_transmit_cts_source_t txCtsSource; /*!< TX CTS source */
        lpuart_transmit_cts_config_t txCtsConfig; /*!< TX CTS configure */
    #endif
        lpuart_idle_type_select_t rxIdleType; /*!< RX IDLE type. */
        lpuart_idle_config_t rxIdleConfig;    /*!< RX IDLE configuration. */
        bool enableTx;                        /*!< Enable TX 使能发送*/
        bool enableRx;                        /*!< Enable RX 使能接收*/
    } lpuart_config_t;
    

    baudRate_Bps 用来设置串口波特率。

    parityMode 用来设置校验模式

    typedef enum _lpuart_parity_mode
    {
     kLPUART_ParityDisabled = 0x0U, //无奇偶校验
     kLPUART_ParityEven = 0x2U, //偶校验
     kLPUART_ParityOdd = 0x3U, //奇校验
    } lpuart_parity_mode_t;
    

    dataBitsCount 用来设置数据数据长度,可以设置为 8 位数据或者 7 位数据(不包含停止位),

    typedef enum _lpuart_data_bits
    {
     kLPUART_EightDataBits = 0x0U, //8 位数据位
    #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && 
    FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
     kLPUART_SevenDataBits = 0x1U, //7 位数据位
    #endif
    } lpuart_data_bits_t;
    

    isMsb 用来设置是否开启高位在前的传输模式。
    stopBitCount 用来设置停止位,可以设置 1 位或 2 位停止位

    typedef enum _lpuart_stop_bit_count
    {
     kLPUART_OneStopBit = 0U, //1 位停止位
     kLPUART_TwoStopBit = 1U, //2 位停止位
    } lpuart_stop_bit_count_t;
    

    enableTxenableRx 用来设置串口的收发开关的。我们一般都是收发全部打开的。

  3. srcClock_Hz 用来设置串口的根时钟频率,比如我们一般设置串口的根时钟频率为 PLL3_SW_CLK/6=80M,因此 srcClock_Hz=80000000。

LPUART_Init 函数会调用 CLOCK_EnableClock 函数来使能 LPUART 时钟的

串口默认配置函数 LPUART_GetDefaultConfig

void LPUART_GetDefaultConfig(lpuart_config_t *config)
{
    assert(NULL != config);

    /* Initializes the configure structure to zero. */
    (void)memset(config, 0, sizeof(*config));

    config->baudRate_Bps  = 115200U;				//波特率115200
    config->parityMode    = kLPUART_ParityDisabled;	//关闭奇偶校验
    config->dataBitsCount = kLPUART_EightDataBits;	//8位数据位
    config->isMsb         = false;
#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
    config->stopBitCount = kLPUART_OneStopBit;		//1位停止位
#endif
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
    config->txFifoWatermark = 0U;
    config->rxFifoWatermark = 0U;
#endif
#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
    config->enableRxRTS = false;					//关闭RTS
    config->enableTxCTS = false;					//关闭CTS
    config->txCtsConfig = kLPUART_CtsSampleAtStart;
    config->txCtsSource = kLPUART_CtsSourcePin;
#endif
    config->rxIdleType   = kLPUART_IdleTypeStartBit;
    config->rxIdleConfig = kLPUART_IdleCharacter1;
    config->enableTx     = false;					//关闭发送
    config->enableRx     = false;					//关闭接收
}

串口中断相关函数

中断使能函数 LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)

中断具体类型

enum _lpuart_interrupt_enable
{
#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
    kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */
#endif
    kLPUART_RxActiveEdgeInterruptEnable         = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */
    kLPUART_TxDataRegEmptyInterruptEnable       = (LPUART_CTRL_TIE_MASK),          /*!< Transmit data register empty. */
    kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK),         /*!< Transmission complete. */
    kLPUART_RxDataRegFullInterruptEnable        = (LPUART_CTRL_RIE_MASK),          /*!< Receiver data register full. */
    kLPUART_IdleLineInterruptEnable             = (LPUART_CTRL_ILIE_MASK),         /*!< Idle line. */
    kLPUART_RxOverrunInterruptEnable            = (LPUART_CTRL_ORIE_MASK),         /*!< Receiver Overrun. */
    kLPUART_NoiseErrorInterruptEnable           = (LPUART_CTRL_NEIE_MASK),         /*!< Noise error flag. */
    kLPUART_FramingErrorInterruptEnable         = (LPUART_CTRL_FEIE_MASK),         /*!< Framing error flag. */
    kLPUART_ParityErrorInterruptEnable          = (LPUART_CTRL_PEIE_MASK),         /*!< Parity error flag. */
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
    kLPUART_TxFifoOverflowInterruptEnable  = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */
    kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */
#endif
};

关闭中断的函数void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)

串口数据收发函数

数据发送函数

static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data)
{
    base->DATA = data;
}

base:串口

data:写入的数据

数据接收函数

static inline uint8_t LPUART_ReadByte(LPUART_Type *base)
{
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
    uint32_t ctrl = base->CTRL;
    uint8_t result;
    bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) ||
                            (((ctrl & LPUART_CTRL_M7_MASK) == 0U) && ((ctrl & LPUART_CTRL_M_MASK) == 0U) &&
                             ((ctrl & LPUART_CTRL_PE_MASK) != 0U)));

    if (isSevenDataBits)
    {
        result = (uint8_t)(base->DATA & 0x7FU);
    }
    else
    {
        result = (uint8_t)base->DATA;
    }

    return result;
#else
    return (uint8_t)(base->DATA);
#endif
}

参数 base 指定要操作的串口

函数返回值就是读取到的串口接收值,此函数就是读取串口的 DATA 寄存器。

多次数据收发

void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)

LPUART_WriteBlocking 用于多字节发送,此函数会产生阻塞,也就是每发送一个字节的数据,然后阻塞等待发送完成,发送完成以后就发送下一个字节的数据。参数 base 表明操作的哪个串口,data 是要发送的数据,length 是要发送的数据长度。

LPUART_ReadBlocking 用于多字节的接收,此函数也会产生阻塞。参数 base 表明操作的哪
个串口,data 是接收数据缓冲区,length 是要接收的数据长度。

串口工作状态相关函数

观察串口的工作状态

uint32_t LPUART_GetStatusFlags(LPUART_Type *base)
{
    uint32_t temp;
    temp = base->STAT;
#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
    temp |= (base->FIFO &
             (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >>
            16U;
#endif
    return temp;
}

LPUART初始化程序


void LPUART1_Init(uint32 bound)
{
    lpuart_config_t lpuart1_config;
    uint32 freq=0;

    CLOCK_EnableClock(kCLOCK_Lpuart1);//使能LPUART1时钟,CCM_CCGR5_CG12

    CLOCK_SetMux(kCLOCK_UartMux,0);//2路复用选择
    CLOCK_SetDiv(kCLOCK_UartDiv,0);//分频

    //set iomuxc
    IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX,0U);
    IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX,0U);

    //set io B0_12&B0_13
    //关闭 Hyst,下拉 100K Ohm,选择Keeper,使能pull/keeper,关闭开漏,100MHz_SPEED1,驱动能力R0/6,低转换速度
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX,0x10B0u);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX,0x10B0u);

    freq = BOARD_DebugConsoleSrcFreq();

    LPUART_GetDefaultConfig(&lpuart1_config);

    lpuart1_config.baudRate_Bps=bound;
    lpuart1_config.dataBitsCount=kLPUART_EightDataBits;
    lpuart1_config.stopBitCount=kLPUART_OneStopBit;
    lpuart1_config.parityMode=kLPUART_ParityDisabled;
    lpuart1_config.enableRx=true;
    lpuart1_config.enableTx=true;

    LPUART_Init(LPUART1,&lpuart1_config,freq);

    // NVIC_SetPriority(LPUART8_IRQn,15);
    // uart_rx_irq(USART_8,1);
}

本文参照正点原子RT1052 开发指南。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值