使用Qt实现Zynq开发板上的LED顺序点亮控制

因最近有个客户找我用ZYNQ设计QT界面,通过QT界面去控制LED,然后正好总结一下,供大家参考一下。

制作不易,记得三连哦,给我动力,持续更新!!!

完整工程文件下载:QT界面控制ZYNQ的LED完整工程 (点击蓝色字体获取)


前言

在嵌入式开发中,Zynq平台的强大性能使其成为许多项目的首选。继之前分享的基于Zynq的AXI GPIO按键控制LED实验后,这次我将介绍一个更具交互性的设计:通过Qt界面实现Zynq开发板上4个LED的顺序点亮控制。本文将详细讲解项目的需求、实现过程、代码设计以及调试经验,希望能为有类似需求的开发者提供参考。

项目需求

本次设计的目标是利用Qt开发一个图形界面程序,控制Zynq开发板上的4个LED(2个位于PL端,2个位于PS端),实现以下功能:

  1. 正序点亮:LED按顺序逐个点亮(pl_led0 → pl_led1 → ps_led0 → ps_led1),每次只有一个LED亮,前一个LED在下一个亮起时熄灭。
  2. 反序点亮:LED按反序逐个点亮(ps_led1 → ps_led0 → pl_led1 → pl_led0),同样每次只有一个LED亮。
  3. 可调时间间隔:通过界面输入框设置每个LED的点亮时间,最后一个LED亮起后保持相同时间再熄灭。
  4. 界面设计:包含“正序点亮”和“反序点亮”两个按钮,以及一个时间间隔输入框。

开发环境

1、开发板:正点原子zynq7020启明星

2、开发软件:vivado2018.3、petalinux2018.3、QT5.9

3、其他:网线、鼠标、键盘、HDMI接口显示器、HDMI线等

如果是同样开发板的小伙伴可以完全抄作业!!

一、软件设计

1.1 vivado工程设计

本工程基于Xilinx Vivado设计套件,采用Block Design方法论实现多接口FPGA系统集成。系统以Zynq-7000系列SoC为核心(或Artix-7等目标器件),主要完成HDMI视频接口的硬件配置,并协同管理串口(UART)、USB 2.0/3.0、以太网(Ethernet)、GPIO(LED)等标准外设接口,其余未指定模块均保持正点原子开发板默认配置。

Block Design架构

1.2 rootfs配置

设置rootfs从SD启动,然后勾选上以下qt和OpenCV软件包

 Filesystem Packages --->
     libs --->
         opencv --->
             [*] opencv // opencv
 Filesystem Packages --->
     misc --->
         qtbase --->
             [*] qtbase // qt
             [*] qtbase-plugins // qt 相关插件

1.3 设备树配置

硬件环境基于Zynq开发板,LED通过设备树定义为GPIO控制,具体如下:

gpio-led2 {
    label = "pl_led0";
    gpios = <&gpio0 55 GPIO_ACTIVE_HIGH>;
    default-state = "on";
};
gpio-led3 {
    label = "pl_led1";
    gpios = <&gpio0 56 GPIO_ACTIVE_HIGH>;
    default-state = "on";
};
gpio-led4 {
    label = "ps_led0";
    gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
    default-state = "on";
};
gpio-led5 {
    label = "ps_led1";
    gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
    default-state = "on";
};

二、Qt界面设计

2.1 使用Qt Designer设计了一个简单的界面,

包含:

  • 正序点亮按钮:触发正序点亮逻辑。
  • 反序点亮按钮:触发反序点亮逻辑。
  • 时间间隔输入框:允许用户输入点亮间隔(单位:秒,默认1秒)。

界面布局代码(mainwindow.ui)保持简洁,核心部分如下:

<widget class="QPushButton" name="forwardButton">
    <property name="text">
        <string>正序点亮</string>
    </property>
</widget>
<widget class="QPushButton" name="reverseButton">
    <property name="text">
        <string>反序点亮</string>
    </property>
</widget>
<widget class="QLineEdit" name="intervalEdit">
    <property name="text">
        <string>1</string>
    </property>
</widget>

2.2 核心代码实现

程序使用C++和Qt框架编写,核心逻辑集中在mainwindow.cpp中。以下是关键部分的实现:

初始化与LED控制
void MainWindow::initLeds()
{
    for (int i = 0; i < 4; i++) {   // 循环遍历4个LED
        setLedState(i, false);      // 将每个LED设置为熄灭状态
    }
}

void MainWindow::setLedState(int ledIndex, bool state)
{
    if (ledIndex < 0 || ledIndex >= 4) return;  // 检查LED索引是否有效
    QString path = QString("/sys/class/leds/%1/brightness").arg(ledNames[ledIndex]);  // 构造brightness文件路径
    QFile brightnessFile(path);                 // 创建文件对象
    if (!brightnessFile.open(QIODevice::WriteOnly)) {  // 尝试打开文件
        qDebug() << "Cannot open brightness file for" << ledNames[ledIndex];  // 打开失败则输出错误
        return;
    }
    QTextStream out(&brightnessFile);           // 创建文本流
    out << (state ? "1" : "0");                 // 写入"1"点亮或"0"熄灭
    brightnessFile.close();                     // 关闭文件
}
  • initLeds():初始化时关闭所有LED。
  • setLedState():通过写入/sys/class/leds/下的brightness文件控制LED状态。
正反序逻辑
void MainWindow::on_forwardButton_clicked()
{
    timer->stop();                  // 停止当前定时器
    currentLed = 0;                 // 设置起点为第一个LED
    isForward = true;               // 设置正序方向
    for (int i = 0; i < 4; i++) {   // 关闭所有LED
        setLedState(i, false);
    }
    double interval = ui->intervalEdit->text().toDouble();  // 获取用户输入的时间间隔
    timer->start(interval * 1000);  // 启动定时器(毫秒)
}

void MainWindow::on_reverseButton_clicked()
{
    timer->stop();                  // 停止当前定时器
    currentLed = 3;                 // 设置起点为最后一个LED
    isForward = false;              // 设置反序方向
    for (int i = 0; i < 4; i++) {   // 关闭所有LED
        setLedState(i, false);
    }
    double interval = ui->intervalEdit->text().toDouble();  // 获取用户输入的时间间隔
    timer->start(interval * 1000);  // 启动定时器(毫秒)
}
  • 两个按钮分别设置正序和反序的起点和方向,并根据用户输入启动定时器。

三、上板测试

3.1 添加QT中文显示包

# 检查现有字体
ls /usr/share/fonts/ttf

# 下载字体包
下载网站:https://sourceforge.net/projects/wqy/files/wqy-microhei/0.2.0-beta/wqy-microhei-0.2.0-beta.tar.gz/

# 将下载好的字体,解压缩后放到以下目录
cp -rf wqy-microhei.ttc /usr/share/fonts/ttf

# 更新字体缓存
fc-cache -fv

3.2 设置QT运行环境

export QT_QPA_PLATFORM=linuxfb

3.3 运行QT程序

将生成的QT可执行文件,拷贝到开发板,然后执行

chmod +x Flowing_LED
./Flowing_LED

最终现象如下视频所示,界面设置比较简陋,后期可进行优化

使用Qt实现Zynq开发板上的LED顺序点亮控制

这样一个简单的QT结合ZYNQ的小程序就设计完成了,后期还可以进行优化调整。

制作不易,记得三连哦,给我动力,持续更新!!!

### 使用QT框架在Zynq平台上控制LED #### 实现概述 要在Zynq平台使用QT框架实现LED控制,主要涉及两个部分的工作:一是构建适合Zynq架构的应用程序环境;二是编写能够与底层硬件交互的具体代码。对于前者来说,由于Zynq是一种融合了ARM处理器子系统(PS, Processing System)和可编程逻辑区域(PL, Programmable Logic)于一体的SoC器件,因此需要确保所使用QT版本能够在Linux操作系统下正常运行于ARM架构之上[^3]。 #### 开发准备 - **安装交叉编译工具链**:为了使能在目标板上的应用程序得以编译,需先设置好适用于ARM Cortex-A9内核的GCC/G++编译器集合。 - **获取并配置QT源码或预编译包**:选择支持嵌入式系统的QT发行版,并按照官方指南完成其针对特定CPU类型的定制化安装过程。 - **移植根文件系统**:创建一个包含必要库和支持文件的基础镜像用于启动后的软件执行环境搭建。 #### 硬件连接说明 假设LED灯已通过GPIO引脚接到开发板上,则可通过修改对应端口状态来改变灯光亮灭情况。具体而言,在PS侧利用AXI GPIO IP核映射至外部资源后,再经由驱动层暴露给用户态API调用接口供上层应用直接操控这些外设设备[^4]。 #### QT工程建立 借助Qt Creator IDE新建项目向导快速生成基础结构,随后添加必要的头文件声明以便后续操作: ```cpp #include <QCoreApplication> #include "wiringpi.h" ``` 此处`wiringPi`是一个简化Linux下的GPIO编程难度的开源类库,它提供了类似于Arduino风格的功能函数集,极大地方便了开发者进行简单的输入输出管理任务[^1]。 #### 主要功能模块设计 定义槽函数响应来自图形界面控件触发的动作事件,比如按钮点击等行为,进而发出指令更改实际物理位置处发光二极管的状态变化: ```cpp void MainWindow::on_pushButton_clicked() { int pin = 0; // 设定关联的IO编号 pinMode(pin, OUTPUT); // 设置工作模式为输出方向 digitalWrite(pin, HIGH); // 输出高电平点亮指示灯 } void MainWindow::on_pushButtonDown_clicked() { int pin = 0; pinMode(pin, OUTPUT); digitalWrite(pin, LOW); // 切换成低准位熄灭光源 } ``` 上述片段展示了当按下不同按键时分别激活或是关闭相连组件的方法原型。当然也可以根据需求进一步扩展成更复杂的多路开关控制系统[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值