这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K146】S32K146直接使用寄存器配置UART

共1条 1/1 1 跳转至

【S32K146】S32K146直接使用寄存器配置UART

高工
2025-06-12 09:11:24     打赏

【简介】

          S32K146 的SDK的串口配置使用起来相对还是很容易的,SDK的软件相对会依赖性会更强。某些场景我们不能直接使用SDK来配置串口只需要一段hard code 来配置串口打印,我们基于此场景直接操作寄存器来实现uart 的printf 打印。对应芯片的UART 的框图如下

image.png

【PINMUX 配置】

在S32K146 芯片中PIN MUX 配置port 的功能配置的寄存器为PORT->PORT_PCRn 每个pin  都有一个寄存器来配置,寄存器描述如下。

image.png

MUX 信号用来控制功能选择

image.png

DSE 用来配置端口的驱动能力

image.png

【UART 参数配置】

我们本次实验UART 的参数使用115200 8N1 的配置,本地的UART的IP 输入时钟为16MHZ,S32K146 的波特率配置通过LPUART Baud Rate Register (BAUD) 寄存器来配置,对应配置说明如下

image.png

image.png

从上面的描述 通过配置OSR/SBR 信号来配置通信的波特率,根据公式我们配置115200 的波特率 16000000/((22+1)*6) = 115942 我们按照上述计算配置更新OSR/SDR寄存器配置波特率参数。

image.png

LPUART Control Register (CTRL) 寄存器的TE 发送使能,PE/PT 用来配置检验位配置,M 位配置发送数据的长度。

image.png

image.png

image.png

PE/PT 信号控制校验位的输出

image.png

我们编写如下的代码配置uart,并验证uart 的printf 输出功能。

#include "clock_config.h"
#include <stddef.h>
#include <stdio.h>

int main(void)
{
      /* Initialize and configure clocks
     *  -   Setup system clocks, dividers
     *  -   see clock manager component for more details
     */
    CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
                   g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
       
    /* config PTC9-LPUART1_TX */
    uint32_t regValue = PORTC->PCR[9];
    regValue &= ~(PORT_PCR_MUX_MASK);
    regValue |= PORT_PCR_MUX(2);
    regValue &= ~(PORT_PCR_DSE_MASK);
    regValue &= ~(PORT_PCR_PE_MASK);
    regValue &= ~(PORT_PCR_PFE_MASK);
    PORTC->PCR[9] = regValue;
    
    /* reset lpuart1 register */
    /* Set the default oversampling ratio (16) and baud-rate divider (4) */
    LPUART1->BAUD = ((uint32_t)((FEATURE_LPUART_DEFAULT_OSR << LPUART_BAUD_OSR_SHIFT) | \
                 (FEATURE_LPUART_DEFAULT_SBR << LPUART_BAUD_SBR_SHIFT)));
    /* Clear the error/interrupt flags */
    LPUART1->STAT = FEATURE_LPUART_STAT_REG_FLAGS_MASK;
    /* Reset all features/interrupts by default */
    LPUART1->CTRL = 0x00000000;
    /* Reset match addresses */
    LPUART1->MATCH = 0x00000000;
    /* Reset IrDA modem features */
    LPUART1->MODIR = 0x00000000;
    /* Reset FIFO feature */
    LPUART1->FIFO = FEATURE_LPUART_FIFO_RESET_MASK;
    /* Reset FIFO Watermark values */
    LPUART1->WATER = 0x00000000;
    
    /* config lpuart1 15200 8n1 */
    /* config 115200 */
    regValue = LPUART1->BAUD;
    regValue &= ~(LPUART_BAUD_OSR_MASK);
    regValue |= LPUART_BAUD_OSR(22);
    LPUART1->BAUD = regValue;
    
    regValue = LPUART1->BAUD;
    regValue &= ~(LPUART_BAUD_SBR_MASK);
    /* Removed the shift operation as the SBR field position is zero; shifting with 0 violates MISRA */
    regValue |= (6) & LPUART_BAUD_SBR_MASK;
    LPUART1->BAUD = regValue;
    
    /* config 8-bit (M=0) */
    /* config 8-bit (M=0) or 9-bits (M=1) */
    LPUART1->CTRL = (LPUART1->CTRL & ~LPUART_CTRL_M_MASK) | (0 << LPUART_CTRL_M_SHIFT);
    /* clear M10 to make sure not 10-bit mode */
    LPUART1->BAUD &= ~LPUART_BAUD_M10_MASK;
    
    LPUART1->BAUD = (LPUART1->BAUD & ~LPUART_BAUD_SBNS_MASK) | ((uint32_t)0 << LPUART_BAUD_SBNS_SHIFT);
    
    /* Enable lpuart tx */
    LPUART1->CTRL = (LPUART1->CTRL & ~LPUART_CTRL_TE_MASK) | ((1UL) << LPUART_CTRL_TE_SHIFT);
    /* Wait for the register write operation to complete */
    while((bool)((LPUART1->CTRL & LPUART_CTRL_TE_MASK) != 0U) != 1) {}
    
    
    while(1)
    {
        printf("hello world\r\n");
    }
    
}


size_t __write(int handle, const unsigned char *buffer, size_t size)
{
    for(int i = 0;i < size;i++)
    {
         while(!(LPUART1->STAT & LPUART_STAT_TDRE_MASK));
         volatile uint8_t * dataRegBytes = (volatile uint8_t *)(&(LPUART1->DATA));
         dataRegBytes[0] = buffer[i];
    }
    return size;
}


上述运行验证发送hello world 可以从串口持续输出

image.png






共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]