2. 按键控制LED

任务目标

在Zynq平台上,通过PS端MIO引脚连接按键与LED,实现按键按下时LED状态翻转。本案例采用轮询方式读取按键状态,学习GPIO输入输出配置及电平读取方法。

硬件连接

  • 按键:连接至PS_MIO引脚(如MIO 50),按下为低电平
  • LED:连接至PS_MIO引脚(如MIO 51),高电平点亮

软件实现

使用Vivado SDK进行裸机开发,通过XGpioPs驱动操作GPIO。核心逻辑为:配置两个MIO引脚分别为输入和输出,在主循环中轮询按键状态,检测到按下时翻转LED输出。

#include "xgpiops.h"
#include "xparameters.h"
#include "sleep.h"

#define GPIO_DEVICE_ID  XPAR_XGPIOPS_0_DEVICE_ID
#define KEY_PIN         50   // 按键连接MIO50
#define LED_PIN         51   // LED连接MIO51

static XGpioPs Gpio;

int main(void)
{
    XGpioPs_Config *ConfigPtr;
    u32 key_state;
    u32 led_state = 0;

    // 初始化GPIO
    ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
    XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);

    // 配置按键为输入,LED为输出
    XGpioPs_SetDirectionPin(&Gpio, KEY_PIN, 0);
    XGpioPs_SetDirectionPin(&Gpio, LED_PIN, 1);

    // 使能按键输入
    XGpioPs_SetOutputEnablePin(&Gpio, KEY_PIN, 0);
    XGpioPs_SetOutputEnablePin(&Gpio, LED_PIN, 1);

    // 初始关闭LED
    XGpioPs_WritePin(&Gpio, LED_PIN, 0);

    while (1) {
        // 读取按键状态(按下为低电平)
        key_state = XGpioPs_ReadPin(&Gpio, KEY_PIN);

        if (key_state == 0) {
            // 按键按下,翻转LED
            led_state = ~led_state & 0x1;
            XGpioPs_WritePin(&Gpio, LED_PIN, led_state);

            // 简单消抖延时
            usleep(200000);  // 200ms
        }
    }

    return 0;
}

运行与验证

  1. 在Vivado中创建硬件工程,使能MIO 50和MIO 51,导出硬件并启动SDK
  2. 在SDK中新建Application Project,将上述代码替换生成的helloworld.c
  3. 连接按键至MIO50(另一端接地),LED正极接MIO51(串联330Ω电阻后接地)
  4. 编译并下载程序到Zynq开发板
  5. 按下按键并松开,观察LED状态是否翻转

通过条件:每次按下按键,LED亮灭状态切换一次;松开按键期间LED保持当前状态不变。若按下时LED无响应,检查按键接线是否使用内部上拉(MIO默认有弱上拉)以及引脚编号是否与硬件一致。