Zynq平台上Qt应用程序开发:动态控制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

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

 https://live.csdn.net/v/472075

posted @ 2025-04-03 09:59  FPGAmaster  阅读(126)  评论(0)    收藏  举报