基于 BPS LKS32MC45X 的 UART 模块

日期2024-12-23

        最近在做一个便携式储能的 BMS 项目,使用的主控芯片是晶丰明源的 LKS32MC45x 系列 MCU。应串口通信和低功耗唤醒的需求,在 LKS32MC45x 的 UART 上做了一些测试,以下是关于 UART 模块的驱动说明。

先说明 LKS32MC45x 的 UART 模块主要特征如下:

  • 支持全双工、半双工;
  • 支持 8/9 bit 数据位
  • 支持 1/2 bit 停止位
  • 支持奇/偶/无校验模式
  • 带 1 Byte 发送/接收缓存
  • 支持 LIN 模式 break character 收发
  • 支持一主多从的 Multi-drop Slave/Master 模式

一、UART 功能配置

        UART 的配置主要有:GPIO 的初始化配置、UART 模块的初始化配置、中断的初始化配置、DMA 的初始化配置。

1、GPIO 的初始化配置

        以 UART1 的 P2_5(RXD)和 P2_6(TXD)为例,LKS32MC45x 系列 MCU 要求将 TXD 的 IO 配置为输出(OUTPUT),将 RXD 的 IO 配置为输入(INPUT)。

    GPIO_StructInit(&uart1_gpio_config);

    uart1_gpio_config.GPIO_Pin    = GPIO_Pin_6;       // 要配置的PIN

    uart1_gpio_config.GPIO_Mode   = GPIO_Mode_OUT;    // GPIO模式:输入、输出、模拟

    uart1_gpio_config.GPIO_PuPd   = GPIO_PuPd_NOPULL; // 上拉/下拉

    uart1_gpio_config.GPIO_PODEna = DISABLE;          // 开漏使能

    uart1_gpio_config.GPIO_PFLT   = DISABLE;          // 滤波使能

    GPIO_Init(GPIO2, &uart1_gpio_config);

 

    GPIO_StructInit(&uart1_gpio_config);

    uart1_gpio_config.GPIO_Pin    = GPIO_Pin_5;       // 要配置的PIN

    uart1_gpio_config.GPIO_Mode   = GPIO_Mode_IN;     // GPIO模式:输入、输出、模拟

    uart1_gpio_config.GPIO_PuPd   = GPIO_PuPd_NOPULL; // 上拉/下拉

    uart1_gpio_config.GPIO_PODEna = DISABLE;          // 开漏使能

    uart1_gpio_config.GPIO_PFLT   = DISABLE;          // 滤波使能

    GPIO_Init(GPIO2, &uart1_gpio_config);


接着要把 P2_5(RXD)和 P2_6(TXD)两个管脚配置成复用 UART 模式。

    GPIO_PinAFConfig(GPIO2, GPIO_PinSource_5, GPIO_AF_UART);

    GPIO_PinAFConfig(GPIO2, GPIO_PinSource_6, GPIO_AF_UART);



2
、UART 模块的初始化配置

       UART 模块的初始化配置如下,这些参数中首先要注意将波特率(BAUDRATE)配置成正确的值。其它参数配置可根据自己的需求来修改。

    uart1_config.DUPLEX       = DISABLE;   // 半双工模式使能,tx_data

    uart1_config.MD_EN        = DISABLE;   // Multi-drop 使能

    uart1_config.CK_EN        = DISABLE;   // 数据校验使能

    uart1_config.CK_TYPE      = 0;         // 奇偶校验配置       0: 偶校验(EVEN); 1: 奇校验(ODD)

    uart1_config.BIT_ORDER    = 0;         // 数据发送顺序配置   0: LSB; 1: MSB

    uart1_config.STOP_LEN     = 0;         // 停止位长度配置     0: 1-Bit; 1: 2-Bit

    uart1_config.BYTE_LEN     = 0;         // 数据长度配置       0: 8-Bit; 1: 9-Bit

    uart1_config.BAUDRATE     = 9600;    // 波特率

    uart1_config.ADR          = 0;         // 多机通讯时的从机地址

    uart1_config.TX_BUF_EMPTY = DISABLE;   // 发送缓冲区空 DMA 请求使能

    uart1_config.RX_DONE      = DISABLE;   // 接收完成 DMA 请求使能

    uart1_config.TX_DONE      = DISABLE;   // 发送完成 DMA 请求使能

    uart1_config.TXD_INV      = DISABLE;   // TXD 输出极性取反

    uart1_config.RXD_INV      = DISABLE;   // RXD 输入极性取反

uart1_config.IE           = DISABLE;   // 中断配置

 

    UART_Init(UART1, &uart1_config);



3
、中断的初始化配置

       如果需要用到中断功能,首先要在前面描述的 UART 初始化中,使能 IE 的相应位,比如:发送完成中断(UART_IRQEna_SendOver)、接收完成中断(UART_IRQEna_RcvOver)、发送缓冲区空中断(UART_IRQEna_SendBuffEmpty),等等。

uart1_config.IE  = UART_IRQEna_SendOver | UART_IRQEna_RcvOver;  // 使能发送&接收完成中断



另外,还需要开启 UART 中断,并设置其中断优先级,比如:

NVIC_SetPriority(UART1_IRQn, 1);  // 设置 UART1 中断优先级

NVIC_EnableIRQ(UART1_IRQn);   // 使能 UART1 中断



4
、DMA 的初始化配置

       如果需要用到 DMA 功能,首先要在前面描述的 UART 初始化中,使能相应的 DMA 功能,比如:TX_BUF_EMPTY、RX_DONE、TX_DONE。

uart1_config.TX_DONE  = ENABLE;   // 发送完成 DMA 请求使能

二、UART 数据发送和接收

1、数据发送

在发送数据之前,需要等待上一个数据已发送完成,即发送缓冲区空才能发送下一个数据。

       在没有开启“发送完成”中断时,需要调用函数 UART_DelaySendOver(UART1) 等待发送缓冲区空。

UART_DelaySendOver(UART1);    // 发送数据前需要等待之前的数据发送完成

UART_SendData(UART1, num);    // 发送数据



如果开启“发送完成”中断,可以在中断处理函数 UART1_IRQHandler 中处理。

void UART1_IRQHandler(void)

{

    if (UART_GetIRQFlag(UART1, UART_IF_SendOver))

    {

        UART_SendData(UART1, num); // 发送数据

        UART_ClearIRQFlag(UART1, UART_IF_SendOver);

    }

}



如果使用 DMA 发送,则只需要指定发送数据的长度和数据的源地址,然后使能 DMA。

void uart1_dma_senddata(u8 *t, u16 len)

{

    DMA_InitTypeDef uart1_dma_config;

    uart1_dma_config.DMA_Channel_EN = ENABLE;           /* DMA 通道使能*/

    uart1_dma_config.DMA_IRQ_EN     = DISABLE;          /* DMA 中断使能 */

    uart1_dma_config.DMA_RMODE      = ENABLE;           /* 多轮传输使能 */

    uart1_dma_config.DMA_CIRC       = DISABLE;          /* 循环模式使能 */

    uart1_dma_config.DMA_SINC       = ENABLE;           /* 源地址递增使能 */

    uart1_dma_config.DMA_DINC       = DISABLE;          /* 目的地址递增使能 */

    uart1_dma_config.DMA_SBTW       = 0;                /* 源地址访问位宽, 0:byte, 1:half-word, 2:word */

    uart1_dma_config.DMA_DBTW       = 0;                /* 目的地址访问位宽, 0:byte, 1:half-word, 2:word */

    uart1_dma_config.DMA_REQ_EN     = DMA_REQ_UART1_TX; /* 通道 x 硬件 DMA 请求使能,高有效 */

    uart1_dma_config.DMA_TIMES      = len;              /* DMA 通道 x 数据搬运次数 */

    uart1_dma_config.DMA_SADR       = (u32)t;           /* DMA 通道 x 源地址 */

    uart1_dma_config.DMA_DADR       = 0;               /* DMA 通道 x 目的地址 */

 

    DMA_Init(DMA_CH0, &uart1_dma_config);

    DMA_CH0->REN |= DMA_REQ_SW;

}



2
、数据接收

       在接收数据之前,需要等待接收完成,才能读取数据。如果开启“接收完成”中断,可以在中断处理函数 UART1_IRQHandler 中处理。

void UART1_IRQHandler(void)

{

    if (UART_GetIRQFlag(UART1, UART_IF_RcvOver))

    {

        uart_buffer[uart_buffer_p] = UART_ReadData(UART1);

        uart_buffer_p++;

        UART_ClearIRQFlag(UART1, UART_IF_RcvOver);

    }

}



如果使用 DMA 接收,则只需要指定接收数据的长度和目标地址,然后使能 DMA。

       这里要注意的是:每一个 DMA 通道一般在同一时间通常只使能一个硬件 DMA 请求,所以如果发送和接收同时使用 DMA 的时候,就需要设置 2 个 DMA 通道。

DMA_InitTypeDef uart1_dma_config;

uart1_dma_config.DMA_Channel_EN = ENABLE;           /* DMA 通道使能*/

uart1_dma_config.DMA_IRQ_EN     = DISABLE;          /* DMA 中断使能 */

uart1_dma_config.DMA_RMODE      = ENABLE;           /* 多轮传输使能 */

uart1_dma_config.DMA_CIRC       = DISABLE;          /* 循环模式使能 */

uart1_dma_config.DMA_SINC       = ENABLE;           /* 源地址递增使能 */

uart1_dma_config.DMA_DINC       = DISABLE;          /* 目的地址递增使能 */

uart1_dma_config.DMA_SBTW       = 0;                /* 源地址访问位宽, 0:byte, 1:half-word, 2:word */

uart1_dma_config.DMA_DBTW       = 0;                /* 目的地址访问位宽, 0:byte, 1:half-word, 2:word */

uart1_dma_config.DMA_REQ_EN     = DMA_REQ_UART1_RX; /* 通道 x 硬件 DMA 请求使能,高有效 */

uart1_dma_config.DMA_TIMES      = len;              /* DMA 通道 x 数据搬运次数 */

uart1_dma_config.DMA_SADR       = 0;                /* DMA 通道 x 源地址 */

uart1_dma_config.DMA_DADR       = (u32)&UART1_BUFF; /* DMA 通道 x 目的地址 */

 

DMA_Init(DMA_CH1, &uart1_dma_config);

 

三、总结

       以上是关于晶丰明源的 LKS32MC45x 的 UART 模块软件驱动的说明。如果想了解更多,可以在下方评论区留言,或者发邮件给我们:atu.sh@wpi-group.com

四、参考资料

LKS32M45x 用户手册:LKS32MC45x_UM_v1.52.pdf。
LKS32M45x 外设示例工程:lks32mc45x_demo_prj_v2.9。


欢迎在博文下方留言评论,我们会及时回复您的问题。

如有更多需求,欢迎联系大联大世平集团 ATU 部门:atu.sh@wpi-group.com   
作者:五月小姐姐

更多资讯,请扫码关注我们!


★方案内容均由个人提供,与平台无关,如有违法或侵权,请联系大大芯方案专属信箱