OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2320|回复: 0

《I.MX6U 嵌入式Qt开发指南》第十五章 Qt控制LED

[复制链接]

1070

主题

1081

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4443
金钱
4443
注册时间
2019-5-8
在线时间
1199 小时
发表于 2022-8-15 10:56:49 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2022-8-15 10:58 编辑

1)实验平台:正点原子阿尔法Linux开发板
2)  章节摘自【正点原子】《I.MX6U 嵌入式Qt开发指南》

3)购买链接:https://detail.tmall.com/item.htm?id=609033604451
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子阿尔法Linux交流群:1027879335




第十五章 Qt控制LED

本章开始使用Qt应用到正点原子的嵌入式I.MX6ULL开发板上,凡事是先易后难,我们也是从最简单的点亮LED说起。介绍如何使用Qt知识应用到正点原子的嵌入式I.MX6ULL开发板,亦可参考来修改到其他平台的嵌入式Linux开发板上。
15.1 资源简介
在正点原子的I.MX6U开发板,ALPHA和MINI Linux开发板板载资源上有一个LED。如下图原理图(下图为ALPHA开发板的LED原理图)。
image002.jpg
15.2 应用实例
想要控制这个LED,首先我们正点原子的出厂内核已经默认将这个LED注册成了gpio-leds类型设备。所以我们可以直接在应用层接口直接可以操作这个LED设备。我们在Qt里有很多种方法可以控制正点原子I.MX6U的LED设备。如可以用C语言的读写函数读写来控制LED的状态,或者直接使用system()函数启动一个进程执行相关指令直接控制LED等。
我们介绍最简单的方法控制开发板上的LED,就是使用Qt的操作文件的类直接控制LED。因为Linux上一切皆文件,所有的东西都当作文件来处理。
下面将贴上代码,其中不会再去讲如何搭建工程,不会贴上实验现象图。代码注释详细,不额外说明。实现现象请自行编译到开发板上运行查看。(编者都有在正点原子I.MX6U开发板上实验,确保准确性)。项目虽然简单,但是在嵌入式里基本都是从点亮一个LED里开始说起。只有我们会操作一个IO,剩下的基本都不会难!
项目简介:设置一个按钮,点击即可控制LED状态反转(点亮或者熄灭LED)。项目看来很起来很简单,实际上有些需要注意的地方,我们在改变LED的状态时,需要先去读取LED的状态,防止外界(外面应用程序)将LED的状态改变了。否则我们反转操作将不成立。在C++里一般使用get()和set()方法来获取和设置。我们的LED程序里也有这种方法。所以需要写好一个让人看得懂的程序是有“方法”的。不能将程序功能写在一堆,最好是分开写,留有接口。让后面的人看懂!
例01_led,控制LED(难度简单)。项目路径为Qt/3/01_led。3是代表第三篇的例程父目录。
       在源文件“mainwindow.h”的代码如下。
  1.   /******************************************************************

  2.     Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.

  3.     * @projectName   01_led

  4.     * @brief         mainwindow.h

  5.     * [url=home.php?mod=space&uid=90321]@Author[/url]        Deng Zhimao

  6.     * [url=home.php?mod=space&uid=55957]@EMAIL[/url]         1252699831@qq.com

  7.     * [url=home.php?mod=space&uid=28414]@net[/url]            www.openedv.com

  8.     * @date           2021-03-08

  9.     *******************************************************************/

  10. 1   #ifndef MAINWINDOW_H

  11. 2   #define MAINWINDOW_H

  12. 3

  13. 4   #include <QMainWindow>

  14. 5   #include <QPushButton>

  15. 6   #include <QFile>

  16. 7

  17. 8   class MainWindow : public QMainWindow

  18. 9   {

  19. 10      Q_OBJECT

  20. 11

  21. 12  public:

  22. 13      MainWindow(QWidget *parent = nullptr);

  23. 14      ~MainWindow();

  24. 15

  25. 16  private:

  26. 17      /* 按钮 */

  27. 18      QPushButton *pushButton;

  28. 19

  29. 20      /* 文件 */

  30. 21      QFile file;

  31. 22     

  32. 23      /* 设置lED的状态 */

  33. 24      void setLedState();

  34. 25

  35. 26      /* 获取lED的状态 */

  36. 27      bool getLedState();

  37. 28

  38. 29  private slots:

  39. 30      void pushButtonClicked();

  40. 31  };

  41. 32  #endif // MAINWINDOW_H
复制代码
在头文件“mainwindow.h”里第24行声明一个设置LED状态方法,另一个是获取状态的方法。另外声明一个槽函数,作用是点击切换LED的状态。
在源文件“mainwindow.cpp”的代码如下。
  1. /******************************************************************

  2.     Copyright &#169; Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.

  3.     * @projectName   01_led

  4.     * @brief         mainwindow.cpp

  5.     * @author        Deng Zhimao

  6.     * @email         1252699831@qq.com

  7.     * @net            www.openedv.com

  8.     * @date           2021-03-08

  9.     *******************************************************************/

  10. 1   #include "mainwindow.h"

  11. 2   #include <QDebug>

  12. 3   #include <QGuiApplication>

  13. 4   #include <QScreen>

  14. 5   #include <QRect>

  15. 6

  16. 7   MainWindow::MainWindow(QWidget *parent)

  17. 8       : QMainWindow(parent)

  18. 9   {

  19. 10      /* 获取屏幕的分辨率,Qt官方建议使用这

  20. 11       * 种方法获取屏幕分辨率,防上多屏设备导致对应不上

  21. 12       * 注意,这是获取整个桌面系统的分辨率

  22. 13       */

  23. 14      QList <QScreen *> list_screen =  QGuiApplication::screens();

  24. 15

  25. 16      /* 如果是ARM平台,直接设置大小为屏幕的大小 */

  26. 17  #if __arm__

  27. 18      /* 重设大小 */

  28. 19      this->resize(list_screen.at(0)->geometry().width(),

  29. 20                   list_screen.at(0)->geometry().height());

  30. 21      /* 默认是出厂系统的LED心跳的触发方式,想要控制LED,

  31. 22       * 需要改变LED的触发方式,改为none,即无 */

  32. 23      system("echo none > /sys/class/leds/sys-led/trigger");

  33. 24  #else

  34. 25      /* 否则则设置主窗体大小为800x480 */

  35. 26      this->resize(800, 480);

  36. 27  #endif

  37. 28

  38. 29      pushButton = new QPushButton(this);

  39. 30

  40. 31      /* 居中显示 */

  41. 32      pushButton->setMinimumSize(200, 50);

  42. 33      pushButton->setGeometry((this->width() - pushButton->width()) /2 ,

  43. 34                              (this->height() - pushButton->height()) /2,

  44. 35                              pushButton->width(),

  45. 36                              pushButton->height()

  46. 37                              );

  47. 38      /* 开发板的LED控制接口 */

  48. 39      file.setFileName("/sys/devices/platform/leds/leds/sys-led/brightness");

  49. 40

  50. 41      if (!file.exists())

  51. 42          /* 设置按钮的初始化文本 */

  52. 43          pushButton->setText("未获取到LED设备!");

  53. 44

  54. 45      /* 获取LED的状态 */

  55. 46      getLedState();

  56. 47

  57. 48      /* 信号槽连接 */

  58. 49      connect(pushButton, SIGNAL(clicked()),

  59. 50              this, SLOT(pushButtonClicked()));

  60. 51  }

  61. 52

  62. 53  MainWindow::~MainWindow()

  63. 54  {

  64. 55  }

  65. 56

  66. 57  void MainWindow::setLedState()

  67. 58  {

  68. 59      /* 在设置LED状态时先读取 */

  69. 60      bool state = getLedState();

  70. 61

  71. 62      /* 如果文件不存在,则返回 */

  72. 63      if (!file.exists())

  73. 64          return;

  74. 65

  75. 66      if(!file.open(QIODevice::ReadWrite))

  76. 67          qDebug()<<file.errorString();

  77. 68

  78. 69      QByteArray buf[2] = {"0", "1"};

  79. 70

  80. 71      /* 写0或1 */

  81. 72      if (state)

  82. 73          file.write(buf[0]);

  83. 74      else

  84. 75          file.write(buf[1]);

  85. 76

  86. 77      /* 关闭文件 */

  87. 78      file.close();

  88. 79

  89. 80      /*重新获取LED的状态 */

  90. 81      getLedState();

  91. 82  }

  92. 83

  93. 84  bool MainWindow::getLedState()

  94. 85  {

  95. 86      /* 如果文件不存在,则返回 */

  96. 87      if (!file.exists())

  97. 88          return false;

  98. 89

  99. 90      if(!file.open(QIODevice::ReadWrite))

  100. 91          qDebug()<<file.errorString();

  101. 92

  102. 93      QTextStream in(&file);

  103. 94

  104. 95      /* 读取文件所有数据 */

  105. 96      QString buf = in.readLine();

  106. 97

  107. 98      /* 打印出读出的值 */

  108. 99      qDebug()<<"buf: "<<buf<<endl;

  109. 100     file.close();

  110. 101     if (buf == "1") {

  111. 102         pushButton->setText("LED点亮");

  112. 103         return true;

  113. 104     } else {

  114. 105         pushButton->setText("LED熄灭");

  115. 106         return false;

  116. 107     }

  117. 108 }

  118. 109

  119. 110 void MainWindow::pushButtonClicked()

  120. 111 {

  121. 112     /* 设置LED的状态 */

  122. 113     setLedState();

  123. 114 }
复制代码
第9行~24行,界面初始化设置,在嵌入式里,根据实际的屏的大小,设置全屏显示。按钮居中显示。
第23行,因为出厂系统里配置LED的触发方式为心跳方式,要想控制此LED,需要将LED的触发方式改为none,即是无触发方式。为了方便,编者直接使用system()函数,用指令的方式改变LED的触发方式。
第54~82行设置LED的方法,写入“0”或“1”代表开和关。写入之前先读取LED的状态,预防在用户其他地方有设置过LED。
第84行~108行,获取LED的状。
第110行~114行设置LED的状态,此方法为槽函数,由点击按钮触发。
至此常规的控制一个IO,大概流程已经完成。

15.3 程序运行效果
下面为Ubuntu上仿真界面的效果,由于Ubuntu不是“开发板”,所以在读取LED设备时会读取失败。实际在板上运行图略。交叉编译程序到正点原子I.MX6U开发板上运行即可控制LED的状态。
image004.jpg


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-6-8 11:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表