2. 按键输入检测
任务目标
在Zynq平台上通过GPIO读取按键输入状态,控制LED的亮灭。按下按键时LED点亮,松开时LED熄灭,以此掌握GPIO输入模式配置与轮询检测方法。
硬件连接
- 按键一端连接GPIO引脚(本例使用MIO引脚,内部上拉),另一端接地
- LED正极通过限流电阻连接GPIO引脚,负极接地
- 按键按下时引脚读到低电平(0),松开时读到高电平(1)
实现原理
Zynq的GPIO控制器通过MIO(多功能IO)引脚访问外部设备。本案例将按键接入MIO引脚并配置为输入方向,LED接入另一MIO引脚并配置为输出方向。主循环中持续读取按键引脚电平,根据电平状态决定LED引脚的输出值。由于按键按下时引脚为低电平,因此当读到0时点亮LED(输出1),读到1时熄灭LED(输出0)。
完整代码
#include "xgpio.h"
#include "xparameters.h"
#include "sleep.h"
#define GPIO_DEVICE_ID XPAR_XGPIO_0_DEVICE_ID
#define KEY_CHANNEL 1 // 按键接在通道1
#define LED_CHANNEL 2 // LED接在通道2
#define KEY_PIN_MASK 0x01 // 使用bit0
#define LED_PIN_MASK 0x01 // 使用bit0
static XGpio gpio;
int main(void)
{
int status;
u32 key_value;
// 初始化GPIO实例
status = XGpio_Initialize(&gpio, GPIO_DEVICE_ID);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
// 配置按键引脚为输入方向
XGpio_SetDataDirection(&gpio, KEY_CHANNEL, KEY_PIN_MASK);
// 配置LED引脚为输出方向
XGpio_SetDataDirection(&gpio, LED_CHANNEL, 0x0);
// 初始熄灭LED
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, 0x0);
while (1) {
// 轮询读取按键状态
key_value = XGpio_DiscreteRead(&gpio, KEY_CHANNEL);
// 按键按下时读到0,点亮LED;松开时读到1,熄灭LED
if ((key_value & KEY_PIN_MASK) == 0) {
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, LED_PIN_MASK);
} else {
XGpio_DiscreteWrite(&gpio, LED_CHANNEL, 0x0);
}
usleep(10000); // 10ms延时,消除抖动影响
}
return 0;
}
硬件配置说明
在Vivado中创建Block Design时,添加Zynq PS核并启用MIO引脚。将按键连接到MIO的bit0(对应GPIO通道1的bit0),LED连接到MIO的bit8(对应GPIO通道2的bit0)。在Xilinx SDK中,xparameters.h会根据硬件配置自动生成XPAR_XGPIO_0_DEVICE_ID等参数,无需手动修改。
运行与验证
- 在Vivado中完成硬件设计并导出到SDK
- 在SDK中新建应用工程,将上述代码替换默认的
helloworld.c - 连接开发板,下载比特流并运行程序
- 验证标准:按下按键时LED立即点亮,松开后LED熄灭,循环响应无延迟
常见问题
- 按键无响应:检查MIO引脚编号是否与代码中通道/bit对应,确认按键接线是否正确(一端接MIO,另一端接地)
- LED常亮或常灭:检查LED引脚方向配置是否正确,确认
XGpio_SetDataDirection参数中通道号与硬件连接一致 - 电平逻辑相反:若按键按下时读到高电平,说明按键接法为接VCC而非接地,需反转判断条件