2. LED闪烁控制
任务说明
本案例在NXP S32K144开发板上,通过配置PTD0引脚为GPIO输出模式,使用自编写的延时函数实现LED灯以约1秒周期(500ms亮、500ms灭)循环闪烁。核心目标是掌握S32K系列MCU的GPIO输出控制方法以及基于循环计数的软件延时编程技巧。
硬件连接
S32K144开发板上的LED通常连接在PTD0引脚(对应开发板丝印LED0位置),LED阳极通过限流电阻接3.3V电源,阴极接PTD0引脚。因此当PTD0输出低电平时LED点亮,输出高电平时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)来校准延时精度。