2. S32G时钟与引脚复用配置实战
任务说明
本案例在 S32G 上完成两件事:一是把系统时钟树配置到目标频率(PLL 倍频 + 分频),二是把 CAN 与以太网的引脚复用(MSCR)配置为对应外设功能。这里用寄存器操作方式实现,便于在没有配置工具的环境下直接落地;若使用 S32 Design Studio 的配置工具,生成的代码逻辑与此一致。
时钟树与引脚复用关系
关键寄存器与配置要点
- 时钟:FXOSC 40 MHz 经 PLL 倍频到 1600 MHz,再经 CORE 分频器得到 800 MHz 内核时钟。配置顺序为:先使能 FXOSC,再配置 PLL 倍频系数并等待锁定,最后设置分频器。
- 引脚复用:每个引脚通过 MSCR 寄存器的
MUX_MODE字段选择功能。CAN 用 ALT=1,以太网用 ALT=2,GPIO 用 ALT=0。配置前需确保对应外设时钟已使能。
完整实现代码
#include <stdint.h>
/* S32G 寄存器基址(示例地址,实际以参考手册为准) */
#define MC_ME_BASE 0x402DC000u
#define MC_CGM_BASE 0x402DC300u
#define FXOSC_BASE 0x402E0000u
#define SIUL2_BASE 0x40290000u
/* MC_ME 寄存器 */
#define MC_ME_CTL (*(volatile uint32_t *)(MC_ME_BASE + 0x00))
#define MC_ME_PLL0CR (*(volatile uint32_t *)(MC_ME_BASE + 0x20))
/* MC_CGM 分频寄存器 */
#define MC_CGM_CORE_DC0 (*(volatile uint32_t *)(MC_CGM_BASE + 0x00))
/* FXOSC 控制 */
#define FXOSC_CTL (*(volatile uint32_t *)(FXOSC_BASE + 0x00))
/* SIUL2 MSCR 寄存器:每个引脚 4 字节 */
#define SIUL2_MSCR(n) (*(volatile uint32_t *)(SIUL2_BASE + 0x240 + (n) * 4))
/* 引脚编号(示例,实际以封装引脚映射为准) */
#define PIN_CAN0_TX 10u
#define PIN_CAN0_RX 11u
#define PIN_ENET0_TX 20u
#define PIN_ENET0_RX 21u
#define MSCR_MUX_MODE_SHIFT 0u
#define MSCR_MUX_MODE_MASK 0x7u
static void mscr_set_mux(uint32_t pin, uint32_t alt)
{
uint32_t v = SIUL2_MSCR(pin);
v &= ~(MSCR_MUX_MODE_MASK << MSCR_MUX_MODE_SHIFT);
v |= (alt & MSCR_MUX_MODE_MASK) << MSCR_MUX_MODE_SHIFT;
SIUL2_MSCR(pin) = v;
}
void clock_init(void)
{
/* 1. 使能 FXOSC */
FXOSC_CTL |= 0x1u;
while ((FXOSC_CTL & 0x2u) == 0u) { /* 等待 FXOSC 稳定 */ }
/* 2. 配置 PLL0:40 MHz × 40 = 1600 MHz */
MC_ME_PLL0CR = (40u << 16) | 0x1u;
while ((MC_ME_PLL0CR & 0x80000000u) == 0u) { /* 等待 PLL 锁定 */ }
/* 3. CORE 分频:1600 / 2 = 800 MHz */
MC_CGM_CORE_DC0 = (1u << 24) | 0x1u;
while ((MC_CGM_CORE_DC0 & 0x80000000u) == 0u) { /* 等待分频切换完成 */ }
}
void pinmux_init(void)
{
/* CAN0:ALT=1 */
mscr_set_mux(PIN_CAN0_TX, 1u);
mscr_set_mux(PIN_CAN0_RX, 1u);
/* ENET0:ALT=2 */
mscr_set_mux(PIN_ENET0_TX, 2u);
mscr_set_mux(PIN_ENET0_RX, 2u);
}
int main(void)
{
clock_init();
pinmux_init();
/* 验证:读回 MSCR 确认复用值 */
if ((SIUL2_MSCR(PIN_CAN0_TX) & MSCR_MUX_MODE_MASK) != 1u) return -1;
if ((SIUL2_MSCR(PIN_ENET0_TX) & MSCR_MUX_MODE_MASK) != 2u) return -1;
for (;;) { }
return 0;
}
运行与验证
- 用 S32 Design Studio 或 GCC 交叉工具链编译,烧录到 S32G 目标板。
- 运行后通过调试器读取
MC_CGM_CORE_DC0,确认分频比已生效(bit24=1 表示 ÷2)。 - 读取
SIUL2_MSCR(10)和SIUL2_MSCR(20),低 3 位应分别为 1 和 2,即 CAN 与以太网复用配置正确。 - 若
main返回 -1,说明 MSCR 读回值与预期不符,需检查引脚编号与 ALT 值是否与封装/参考手册一致。
通过条件:时钟分频寄存器读回值符合预期,且 CAN/以太网引脚的 MUX_MODE 分别为 1 和 2。