2. LED闪烁控制

任务说明

本案例在NXP S32K144开发板上,通过配置PTD0引脚为GPIO输出模式,使用自编写的延时函数实现LED灯以约1秒周期(500ms亮、500ms灭)循环闪烁。核心目标是掌握S32K系列MCU的GPIO输出控制方法以及基于循环计数的软件延时编程技巧。

硬件连接

S32K144开发板上的LED通常连接在PTD0引脚(对应开发板丝印LED0位置),LED阳极通过限流电阻接3.3V电源,阴极接PTD0引脚。因此当PTD0输出低电平时LED点亮,输出高电平时LED熄灭。若实际硬件连接不同,需根据原理图调整引脚编号和点亮电平逻辑。

S32K144 PTD0 (GPIO输出) PTD0 330Ω 3.3V LED阴极接PTD0,输出低电平点亮 限流电阻 LED

代码实现

本案例使用S32K1xx系列MCU的标准外设库(S32K1xx_SDK),代码包含GPIO初始化、延时函数和主循环三部分。延时函数通过嵌套循环消耗CPU周期实现毫秒级延时,系统时钟配置为8MHz外部晶振,内核时钟80MHz。

/* led_blink.c - S32K144 LED闪烁控制 */
#include "S32K144.h"

/* 延时函数:约延时ms毫秒(基于80MHz内核时钟) */
void delay_ms(uint32_t ms)
{
    uint32_t i, j;
    for (i = 0; i < ms; i++)
    {
        /* 内层循环约执行8000次 ≈ 1ms(经实测校准) */
        for (j = 0; j < 8000; j++)
        {
            __NOP();  /* 空操作,防止编译器优化 */
        }
    }
}

/* GPIO初始化:PTD0配置为输出模式 */
void GPIO_Init(void)
{
    /* 1. 使能PORTD时钟 */
    PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;

    /* 2. 配置PTD0为GPIO功能(MUX=001) */
    PORTD->PCR[0] = PORT_PCR_MUX(1);

    /* 3. 设置PTD0为输出方向 */
    PTD->PDDR |= (1U << 0);

    /* 4. 初始输出高电平(LED熄灭) */
    PTD->PSOR = (1U << 0);
}

int main(void)
{
    /* 初始化系统时钟(默认使用SPCO 8MHz外部晶振) */
    WDOG->CNT = 0xD928C520;  /* 解锁看门狗 */
    WDOG->CNT = 0x17A353D8;
    WDOG->TOVAL = 0xFFFF;
    WDOG->CS = 0x0000;       /* 禁用看门狗 */

    GPIO_Init();

    while (1)
    {
        PTD->PCOR = (1U << 0);  /* 输出低电平,LED点亮 */
        delay_ms(500);           /* 延时500ms */

        PTD->PSOR = (1U << 0);  /* 输出高电平,LED熄灭 */
        delay_ms(500);           /* 延时500ms */
    }
}

代码说明

GPIO输出控制:通过PORTD的PCR寄存器将PTD0引脚复用为GPIO功能,再设置PDDR方向寄存器为输出。输出电平通过PSOR(置位)和PCOR(清零)寄存器控制,这种方式比直接写PDOR寄存器更安全,避免读-改-写竞争。

延时实现:delay_ms函数采用双层循环结构,外层循环次数等于毫秒数,内层循环通过空操作指令消耗固定周期。内层循环次数8000是基于80MHz主频、每个循环约10个时钟周期计算得出(80MHz/10/1000 = 8000)。实际延时精度受编译器优化等级影响,建议编译时使用-O0选项或通过示波器校准循环次数。

编译与烧录

本代码基于S32K1xx_SDK开发,可使用S32 Design Studio IDE创建工程,将上述代码替换main.c内容。编译配置需包含SDK头文件路径,并链接startup文件和系统时钟初始化代码。烧录使用PE Micro或J-Link调试器,通过S32 Design Studio的Flash烧录功能将生成的.elf或.hex文件下载到开发板。

验证方法

判定标准:程序烧录后,观察开发板LED0是否以约1秒周期(500ms亮/500ms灭)持续闪烁。若LED常亮或常灭,检查PTD0引脚连接是否正确、GPIO初始化代码中引脚号和端口号是否与硬件一致。若闪烁频率明显偏差,可通过示波器测量PTD0引脚波形,调整delay_ms函数中内层循环次数(8000)来校准延时精度。