Funpack5-1 - 用UART实现串口输出
该项目使用了MCXA346开发板,实现了串口输出“Hello, DigiKey Funpack 5-1”的设计,它的主要功能为:使用硬件UART模块,输出“Hello, DigiKey Funpack 5-1”到串口上位机助手。
标签
UART
Funpack S5 #1
MCXA346
Funpack5-1
littlestudent
更新2026-03-02
13

项目和设计思路介绍

非常开心能够参与并顺利完成Funpack 5-1的活动,本次项目的方向是任务1:串口通信

基础题目:使用MCXA346开发板的UART串口输出“Hello, DigiKey Funpack 5-1”。


项目的整体开发方向是

  • 先熟悉恩智浦MCU的开发环境
  • 熟悉MCXA346的UART模块
  • 初始化UART,并输出“Hello, DigiKey Funpack 5-1”到上位机串口助手。

硬件系统框图

软件流程图

硬件介绍(控制器及使用外设)

主控制器MCXA346介绍

FRDM-MCXA346 是一款紧凑且可扩展的开发板,可让你快速基于FRDM-MCXA346微控制器单元(MCU)开展原型设计。它们提供行业标准的接口,可轻松访问MCU的I/O,配备集成的开放标准串行接口、外部闪存和板载MCU-Link调试器。通过 MCUXpresso Developer Experience提供其他工具,如面向附加板的扩展板中心和面向软件示例的应用代码中心


板卡特性:

  • 微控制器
    • MCX A346 Arm® Cortex®-M33内核,运行频率高达180MHz
    • 高达1MB的闪存,高达256KB的RAM,带8KB的纠错码(ECC),支持乘法累加单元(MAU)和SmartDMA、控制器局域网灵活数据速率(CAN-FD)、低功耗通用异步收发器(LPUART)、低功耗串行外设接口(LPSPI)、低功耗内部集成电路(LPI2C)、DMA和低压差稳压器(LDO)
  • 连接
    • 高速通用串行总线(HS USB) Type-C连接器(板载MCU-Link调试器)
    • 控制器局域网(CAN)/I3C/串行外设接口(SPI)/I²C/UART连接器(Arduino,外设模块(PMOD)/微控制器总线(mikroBUS),未安装(DNP))
    • Wi-Fi连接器(Arduino,外设模块(PMOD)/微控制器总线(mikroBUS),未安装(DNP))
    • 摄像头连接器(SmartDMA)
  • 调试器
    • 板载MCU-Link调试器,带有CMSIS-DAP
    • JTAG/SWD/SWD连接器
  • 扩展选项
    • Arduino®接头
    • FRDM接头
    • Pmod™ *DNP
    • mikroBUS™
    • SmartDMA/摄像头接头
    • 通用输入/输出1 (GPIO1)接头
    • 通用输入/输出2 (GPIO2)接头



UART外设

本次项目使用的LPUART模块是LPUART2。它与MCU-LINK连接,可以把字符串打印到上位机。


开发环境搭建

系统的开发使用的是恩智浦的MCUXPRESSO IDE,其内置了SDK下载,编译,调试等多个功能。一站式完成项目开发。


官方SDK可以选择从恩智浦SDK Builder网站自行制作:

也可以打开MCUXPRESSO后,在Installed SDKs一栏中,点击“Download and Install SDKs”:

image.png


然后输入开发板型号:


之后会自动从官网服务器下载并安装SDK:

硬件实现功能展示

按下开发板RST复位,然后观察串口助手:

image.png


关键代码

LPUART2相关宏定义:

#define BOARD_DEBUG_UART_TYPE     kSerialPort_Uart

#define BOARD_DEBUG_UART_CLK_FREQ 12000000U



#ifndef BOARD_DEBUG_UART_BAUDRATE

#define BOARD_DEBUG_UART_BAUDRATE 115200U

#endif



#define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART2

#define BOARD_DEBUG_UART_INSTANCE 2U

#define BOARD_DEBUG_UART_CLK_ATTACH kFRO_LF_DIV_to_LPUART2

#define BOARD_DEBUG_UART_RST kLPUART2_RST_SHIFT_RSTn

#define BOARD_DEBUG_UART_CLKSRC kCLOCK_LPUART2

#define BOARD_UART_IRQ_HANDLER LPUART2_IRQHandler

#define BOARD_UART_IRQ LPUART2_IRQn


初始化LPUART2引脚:

void BOARD_InitDEBUG_UARTPins(void)

{

/* PORT2: Peripheral clock is enabled */

CLOCK_EnableClock(kCLOCK_GatePORT2);

/* LPUART2 peripheral is released from reset */

RESET_ReleasePeripheralReset(kLPUART2_RST_SHIFT_RSTn);

/* PORT2 peripheral is released from reset */

RESET_ReleasePeripheralReset(kPORT2_RST_SHIFT_RSTn);



const port_pin_config_t port2_2_pin35_config = {/* Internal pull-up resistor is enabled */

.pullSelect = kPORT_PullUp,

/* Low internal pull resistor value is selected. */

.pullValueSelect = kPORT_LowPullResistor,

/* Fast slew rate is configured */

.slewRate = kPORT_FastSlewRate,

/* Passive input filter is disabled */

.passiveFilterEnable = kPORT_PassiveFilterDisable,

/* Open drain output is disabled */

.openDrainEnable = kPORT_OpenDrainDisable,

/* Low drive strength is configured */

.driveStrength = kPORT_LowDriveStrength,

/* Normal drive strength is configured */

.driveStrength1 = kPORT_NormalDriveStrength,

/* Pin is configured as LPUART2_TXD */

.mux = kPORT_MuxAlt3,

/* Digital input enabled */

.inputBuffer = kPORT_InputBufferEnable,

/* Digital input is not inverted */

.invertInput = kPORT_InputNormal,

/* Pin Control Register fields [15:0] are not locked */

.lockRegister = kPORT_UnlockRegister};

/* PORT2_2 (pin 35) is configured as LPUART2_TXD */

PORT_SetPinConfig(PORT2, 2U, &port2_2_pin35_config);



const port_pin_config_t port2_3_pin36_config = {/* Internal pull-up resistor is enabled */

.pullSelect = kPORT_PullUp,

/* Low internal pull resistor value is selected. */

.pullValueSelect = kPORT_LowPullResistor,

/* Fast slew rate is configured */

.slewRate = kPORT_FastSlewRate,

/* Passive input filter is disabled */

.passiveFilterEnable = kPORT_PassiveFilterDisable,

/* Open drain output is disabled */

.openDrainEnable = kPORT_OpenDrainDisable,

/* Low drive strength is configured */

.driveStrength = kPORT_LowDriveStrength,

/* Normal drive strength is configured */

.driveStrength1 = kPORT_NormalDriveStrength,

/* Pin is configured as LPUART2_RXD */

.mux = kPORT_MuxAlt3,

/* Digital input enabled */

.inputBuffer = kPORT_InputBufferEnable,

/* Digital input is not inverted */

.invertInput = kPORT_InputNormal,

/* Pin Control Register fields [15:0] are not locked */

.lockRegister = kPORT_UnlockRegister};

/* PORT2_3 (pin 36) is configured as LPUART2_RXD */

PORT_SetPinConfig(PORT2, 3U, &port2_3_pin36_config);

}


初始化时钟 180MHz:

void BOARD_BootClockFROHF180M(void)

{

uint32_t coreFreq;

spc_active_mode_core_ldo_option_t ldoOption;

spc_sram_voltage_config_t sramOption;



/* Get the CPU Core frequency */

coreFreq = CLOCK_GetCoreSysClkFreq();



/* The flow of increasing voltage and frequency */

if (coreFreq <= BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK) {

/* Set the LDO_CORE VDD regulator level */

ldoOption.CoreLDOVoltage = kSPC_CoreLDO_OverDriveVoltage;

ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength;

(void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption);

/* Configure Flash to support different voltage level and frequency */

FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x4U));

/* Specifies the operating voltage for the SRAM's read/write timing margin */

sramOption.operateVoltage = kSPC_sramOperateAt1P2V;

sramOption.requestVoltageUpdate = true;

(void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption);

}





/*!< Set up system dividers */

CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set SYSCON.AHBCLKDIV divider to value 1 */

CLOCK_SetClockDiv(kCLOCK_DivFRO_HF, 1U); /* !< Set SYSCON.FROHFDIV divider to value 1 */

CLOCK_SetupFROHFClocking(180000000U); /*!< Enable FRO HF(180MHz) output */

CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */



CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to kFRO_HF */



/* The flow of decreasing voltage and frequency */

if (coreFreq > BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK) {

/* Configure Flash to support different voltage level and frequency */

FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x4U));

/* Specifies the operating voltage for the SRAM's read/write timing margin */

sramOption.operateVoltage = kSPC_sramOperateAt1P2V;

sramOption.requestVoltageUpdate = true;

(void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption);

/* Set the LDO_CORE VDD regulator level */

ldoOption.CoreLDOVoltage = kSPC_CoreLDO_OverDriveVoltage;

ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength;

(void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption);

}



/*!< Set up clock selectors - Attach clocks to the peripheries */

CLOCK_AttachClk(kCPU_CLK_to_TRACE); /* !< Switch TRACE to CPU_CLK */



/*!< Set up dividers */

CLOCK_SetClockDiv(kCLOCK_DivFRO_LF, 1U); /* !< Set SYSCON.FROLFDIV divider to value 1 */

CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1U); /* !< Set MRCC.WWDT0_CLKDIV divider to value 1 */

CLOCK_SetClockDiv(kCLOCK_DivTRACE, 2U); /* !< Set MRCC.TRACE_CLKDIV divider to value 2 */



/* Set SystemCoreClock variable */

SystemCoreClock = BOARD_BOOTCLOCKFROHF180M_CORE_CLOCK;

}


初始化LPUART2模块:

void BOARD_InitDebugConsole(void)

{

/* attach 12 MHz clock to FLEXCOMM0 (debug console) */

CLOCK_SetClockDiv(kCLOCK_DivLPUART2, 1u);

CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);



RESET_PeripheralReset(BOARD_DEBUG_UART_RST);



DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE,

BOARD_DEBUG_UART_CLK_FREQ);

}


包含头文件:

#include "fsl_debug_console.h"


打印指定字符串到串口助手:

PRINTF("Hello, DigiKey Funpack 5-1\r\n");

总结

通过本次Funpack活动,首次接触NXP单片机,并实现了使用串口UART打印指定字符串到串口的功能

本期活动获益良多,感谢硬禾与Digikey提供的平台,感谢诸位网友提供的协助!

附件下载
frdmmcxa346_hello_world.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号