3. 按键控制LED

按键控制LED 学习卡片

任务说明

本案例实现基于S32K144 EVB的按键控制LED功能:通过轮询方式读取按键引脚电平,检测到按键按下时切换LED的亮灭状态。核心目标是掌握GPIO输入模式配置、电平读取及轮询消抖处理方法。

硬件连接

  • LED:连接至PTD15引脚(低电平点亮)
  • 按键:连接至PTC13引脚(按下为低电平,外部上拉)

软件实现

使用S32K14x系列MCU的SDK外设驱动,配置PTD15为GPIO输出,PTC13为GPIO输入。主循环中轮询按键状态,检测到下降沿(按下动作)时翻转LED输出。为避免机械抖动导致误触发,加入10ms软件延时消抖。

/* gpio_led_key.c */
#include "S32K144.h"
#include "clock_config.h"

#define LED_PORT       PTD
#define LED_PIN        15u
#define KEY_PORT       PTC
#define KEY_PIN        13u

/* 简单延时函数(约1ms @ 8MHz核心时钟) */
static void DelayMs(uint32_t ms)
{
    for (uint32_t i = 0; i < ms; i++) {
        for (volatile uint32_t j = 0; j < 4000u; j++) {
            __NOP();
        }
    }
}

/* GPIO初始化 */
static void GPIO_Init(void)
{
    /* 使能端口时钟 */
    PCC->PCCn[PCC_PORTD_INDEX] |= PCC_PCCn_CGC_MASK;
    PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK;

    /* LED引脚:PTD15 配置为GPIO输出 */
    PORTD->PCR[LED_PIN] = PORT_PCR_MUX(1u);          /* 复用为GPIO */
    PTD->PDDR |= (1u << LED_PIN);                    /* 设为输出 */
    PTD->PCOR = (1u << LED_PIN);                     /* 初始熄灭(低电平) */

    /* 按键引脚:PTC13 配置为GPIO输入,使能内部上拉 */
    PORTC->PCR[KEY_PIN] = PORT_PCR_MUX(1u) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
    PTC->PDDR &= ~(1u << KEY_PIN);                   /* 设为输入 */
}

/* 读取按键状态:按下返回1,释放返回0 */
static uint8_t Key_Read(void)
{
    if ((PTC->PDIR & (1u << KEY_PIN)) == 0u) {
        return 1u;   /* 低电平表示按下 */
    }
    return 0u;
}

int main(void)
{
    uint8_t key_state = 0u;
    uint8_t key_last = 0u;

    /* 初始化系统时钟 */
    CLOCK_InitClockSource(kCLOCK_SysClk, kCLOCK_SysClkSrcSysOsc);
    CLOCK_SetClockDivider(kCLOCK_PeriClkDiv, 1u);

    GPIO_Init();

    while (1) {
        key_state = Key_Read();

        /* 检测按下沿(上一次为释放,本次为按下) */
        if ((key_state == 1u) && (key_last == 0u)) {
            DelayMs(10u);                    /* 消抖延时 */
            if (Key_Read() == 1u) {          /* 再次确认按下 */
                PTD->PTOR = (1u << LED_PIN); /* 翻转LED */
            }
        }
        key_last = key_state;
    }
}

代码说明

  • GPIO初始化:使能PCC时钟后,将PTD15配置为输出模式并初始化为低电平(LED熄灭);PTC13配置为输入模式并启用内部上拉电阻,确保按键释放时读到高电平。
  • 按键读取:通过读取PDIR寄存器判断引脚电平,低电平表示按键按下。
  • 消抖处理:仅在检测到电平从高到低跳变时启动10ms延时,延时后再次读取确认,有效避免机械抖动造成的误动作。
  • LED切换:使用PTOR寄存器翻转输出,实现每次按下按键LED状态切换。

编译与烧录

  1. 在S32 Design Studio中创建S32K144空工程,将上述代码保存为gpio_led_key.c并添加至工程。
  2. 工程属性中确认预处理器宏CPU_S32K144已定义。
  3. 编译生成.elf或.hex文件,通过OpenSDA调试器或PE Micro烧录至开发板。

验证方法

烧录后观察以下现象:

  • 初始状态LED处于熄灭状态。
  • 每次按下按键(PTC13接地)并释放,LED亮灭状态切换一次。
  • 快速连续按键时,每次按下仅切换一次,无抖动导致的多次翻转。

判定标准:按键每按下并释放一次,LED状态翻转一次;按住不放时LED状态保持不变,符合预期逻辑。

关键信号连接示意

S32K144 MCU PTD15 PTC13 LED VCC R1 按键 GND 内部上拉 按键按下 → PTC13 = 低电平 LED低电平点亮,PTD15输出翻转控制亮灭

关键配置总结

引脚方向寄存器配置功能
PTD15输出PCR[MUX]=1, PDDR=1LED控制(低电平点亮)
PTC13输入PCR[MUX]=1, PE=1, PS=1, PDDR=0按键检测(按下为低)