基于arm + linux的嵌入式软件开发,基本上的内容主要是:u-boot的移植,kernel的裁剪和相关驱动程序的设计,root-fs的制作,应用程序的设计,其中,应用程序主要包含两方面的内容:Gui的设计和逻辑控制程序的实现。在整个开发中,具有相当代码量的部分也就这么两个方面:驱动程序、应用程序。一般的开发板都有相关配套的底层驱动程序例程,开发者可稍加修改在工程项目中加以使用(其实我不知道这样是不是会触犯什么只是产权之类的东东,先凑着用吧)。

第一,驱动程序的设计。

很容易想到,Led在板子上是直接与CPU的GPIO引脚相接,即对相应GPIO的控制也就是对外设Led的控制,以下是Led作为一个外设在板子上的详细资源占用表。

图1.0 mini2440 开发板上Led灯的资源占用表

板子Led的原理图如下 :

图1.1 LED原理图

分析:LED灯只有两种状态,亮与不亮。查看用户手册可以知道,当GPIO被赋予低电平的时候,LED灯被点亮,否则将处于熄灭的状态,因此,只要设置好管脚高低电平两个状态就可以完成驱动程序连接底层硬件和应用程序的功能了。源码mini2440_leds.c 如下 :

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h> #define IOCTL_GPIO_ON 0
#define IOCTL_GPIO_OFF 1
#define DEVICE_NAME "leds" static unsigned long led_table [] = {
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
}; static unsigned int led_cfg_table [] = {
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
}; static int sbc2440_leds_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
{
switch(cmd) {
// 设置指定引脚的输出电平为0,即低电平,灯亮
case IOCTL_GPIO_ON:
s3c2410_gpio_setpin(led_table[arg], cmd);
return 0;
// 设置指定引脚的输出电平为1,即高电平,灯灭
case IOCTL_GPIO_OFF:
s3c2410_gpio_setpin(led_table[arg], !cmd);
return 0; default:
return -EINVAL;
}
} static struct file_operations dev_fops = {
.owner = THIS_MODULE,
//.open = sbc2440_leds_open,
//.release= sbc2440_leds_close,
.ioctl = sbc2440_leds_ioctl,
}; static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
}; static int __init dev_init(void)
{
int ret; int i; for (i = 0; i < 4; i++) {
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
s3c2410_gpio_setpin(led_table[i], 0);
} ret = misc_register(&misc); printk (DEVICE_NAME"/tinitialized/n"); return ret;
} static void __exit dev_exit(void)
{
misc_deregister(&misc);
} module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chenxiaomai");

为了编译此驱动程序,必须编写一个Makefile 文件,其内容如下 :

# If KERNELREEASE is defined ,we've been invoked from the kernel
# build system and can use its language ifneq ($(KERNELRELEASE),)
obj-m := mini2440_leds.o
# Otherwise we were called directly from the command line
# invoke the kernel build sysstem
else KERNELDIR=/root/build_kernel/linux-2.6.29
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif all:mini2440_leds.c -o mini2440_leds.o
$(CC) mini2440_leds.c -o mini2440_leds clean:
rm -rvf *.o *.ko *.mod.c *.order *.symvers

把驱动程序和Makefile 放同一目录,在终端进行#make,如果不出问题,将会产生一些中间文件,但是,只有.ko文件才是我们想要的,你知道,那是我们在超级终端的主角。make以后在终端输入#file mini2440_leds.ko,就可以看见驱动模块的详细信息啦。

[root@localhost Led]# file mini2440_leds.ko

mini2440_leds.ko: ELF 32-bit LSB relocatable, ARM, version 1 (SYSV), not stripped

到这里,你就可以把.ko文件送到板子的超级终端上直接insmod 和rmmod,这个,就不多说啦。。。

      第二,逻辑控制设计。

基于逻辑与GUI分离的原则,这里把逻辑控制部分设置成每一个方法设置一个灯的熄灭状态。源码如下 :

led.h

#ifndef LED_H
#define LED_H #include <QObject> class Led : public QObject
{
Q_OBJECT
public:
explicit Led(QObject *parent = 0); public:
int fd;
int on[4]; public:
// Led();
~Led(); public:
void led1_on();
void led2_on();
void led3_on();
void led4_on();
}; #endif // LED_H

led.cpp

#include "led.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h> Led::Led(QObject *parent) :
QObject(parent)
{
on[0] = 0;
on[1] = 0;
on[2] = 0;
on[3] = 0; fd = open("/dev/leds",0);
// cout<<"fd = "<<fd<<endl;
if ( fd < 0 )
{
perror("Error : fd < 0");
}
} void Led::led1_on()
{
on[0] = (~on[0]) & 1;
ioctl(fd,on[0],0);
} void Led::led2_on()
{
on[1] = (~on[1]) & 1;
ioctl(fd,on[1],1);
} void Led::led3_on()
{
on[2] = (~on[2]) & 1;
ioctl(fd,on[2],2); } void Led::led4_on()
{
on[3] = (~on[3]) & 1;
ioctl(fd,on[3],3);
} Led::~Led()
{
//close(fd);
}

必需要说明的是,在调用驱动程序ioctl()接口之前,必须包含怎么一个头文件#include <sys/ioctl.h>,否则,编译器将会提示找不到该接口——这个问题也郁闷了三天的时间,后来是我们Qt群的一个老同志提醒我的,人生啊!

      第三,GUI的设计。

在这里我们只设置4个按钮和一个退出按钮,并且附上一个提示面板,当然,必须在这一部分对Led进行实例化,并且加以应用才能完成对应用程序的功能,必须提醒的是,定义一个Led  *ledobj对象指针以后,必须对其进行分配内存操作,否则程序将会出现不可预料完成的终止提示。源码如下:

leddialog.h

#ifndef LEDDIALOG_H
#define LEDDIALOG_H #include <QtGui/QDialog>
#include <Qt/QtGui>
#include "led.h" class LedDialog : public QDialog
{
Q_OBJECT private :
QLabel *label;
QPushButton *led1Button;
QPushButton *led2Button;
QPushButton *led3Button;
QPushButton *led4Button;
QPushButton *exitButton;
Led *ledobj; private slots :
void Light_style1(void);
void Light_style2(void);
void Light_style3(void);
void Light_style4(void);
void Light_style_exit(void);
void Light_delay(int times); public:
LedDialog(QWidget *parent = 0);
~LedDialog();
}; #endif // LEDDIALOG_H

leddialog.cpp

#include "leddialog.h"
#include <QtGui> //Construction Function
LedDialog::LedDialog(QWidget *parent)
: QDialog(parent)
{
// init component
label= new QLabel(tr("Set Led"));
led1Button = new QPushButton(tr("Led1"));
led2Button = new QPushButton(tr("Led2"));
led3Button = new QPushButton(tr("Led3"));
led4Button = new QPushButton(tr("Led4"));
exitButton = new QPushButton(tr("Exit"));
ledobj = new Led(); //layout component
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label,Qt::AlignTop);
layout->addWidget(led1Button);
layout->addWidget(led2Button);
layout->addWidget(led3Button);
layout->addWidget(led4Button);
layout->addWidget(exitButton);
setLayout(layout);
//resize(200,230);
//setFixedSize(200,230);
// this->setFixedSize( this->width (),this->height ());
setMinimumSize(200, 230);
setMaximumSize(200, 230); // signal-slots connect
QObject::connect(led1Button, SIGNAL(clicked()), this, SLOT(Light_style1()));
QObject::connect(led2Button, SIGNAL(clicked()), this, SLOT(Light_style2()));
QObject::connect(led3Button, SIGNAL(clicked()), this, SLOT(Light_style3()));
QObject::connect(led4Button, SIGNAL(clicked()), this, SLOT(Light_style4()));
QObject::connect(exitButton, SIGNAL(clicked()), this, SLOT(Light_style_exit())); } //self-declaration function implement
void LedDialog::Light_style1(void)
{
ledobj->led1_on();
Light_delay(100);
} void LedDialog::Light_style2(void)
{ ledobj->led2_on();
Light_delay(2000);
} void LedDialog::Light_style3(void)
{
ledobj->led3_on();
Light_delay(2000);
} void LedDialog::Light_style4(void)
{
ledobj->led4_on();
Light_delay(2000);;
} void LedDialog::Light_style_exit(void)
{
exit(0);
} void LedDialog::Light_delay(int times)
{
int i;
int j;
for (i = 0;i < times; i++)
for (j = 0; j < times; j++)
{
// Null function
}
} LedDialog::~LedDialog()
{ }

最后附上main.cpp的内容,其实是完全没有做任何修改,QtCreator2.0自动生成。哈

#include <QtGui/QApplication>
//#include <QTextCodec>
#include "led.h"
#include "leddialog.h" #include "leddialog.h" int main(int argc, char *argv[])
{
QApplication a(argc, argv);
LedDialog w;
// QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
w.show();
return a.exec();
}

PS : 源代码中有许多是我在调试的时候修改的,所以有一些源码注释没删除,呵呵。。。也说明了还有一些问题存在呢,不过,在板子上我已经测试过整个程序,没有问题,运行情况良好。



转自:http://blog.csdn.net/zjucxm/article/details/5874043

基于Qt Gui的Led控制显示程序的更多相关文章

  1. 基于jquery封装通用的控制显示隐藏的方法

    应用场景 在项目中会存在大量这样的需求: 1.选择不同的radio单选框,页面上的部分内容随之显示隐藏 2.选择不同的option下拉框内容,页面上的部分内容随之显示隐藏 如果每次遇到这类需求都单独写 ...

  2. 【Qt程序】基于Qt词典开发系列&lt;十二&gt;呼叫讲述

    我们知道,win7系统自带有讲述人,即能够机器读出当前内容,详细能够将电脑锁定.然后点击左下角的button就可以.之前在用Matlab写扫雷游戏的时候,也以前调用过讲述人来进行游戏的语音提示. 详细 ...

  3. 【Qt编程】基于Qt的词典开发系列<十一>系统托盘的显示

    本文主要讨论Qt中的系统托盘的设置.系统托盘想必大家都不陌生,最常用的就是QQ.系统托盘以简单.小巧的形式能让人们较快的打开软件.废话不多说,下面开始具体介绍. 首先,新建一个Qt Gui项目,类型选 ...

  4. 基于Qt实现的截图小程序

    在最近做的行人检测项目中,由于需要训练分类器,而分类器的训练又需要有一个一定长宽的样本.为了方便样本的采集,因此实现了这样的一个截图程序.该程序的主要功能是加载视频到程序中,程序可以对视频进行播放.暂 ...

  5. 【Qt编程】基于Qt的词典开发系列<十>--国际音标的显示

    在年前的一篇文章中,我提到要学习Qt.于是在这学期看了一个月的qt.现在大致对qt有了一些了解.但是现在导师又把我调到了android应用开发平台,所以说qt的学习要搁置了.本打算这学期做一个单词查询 ...

  6. 使用C#模拟键盘输入、鼠标移动和点击、设置光标位置及控制应用程序的显示

    1.模拟键盘输入(SendKeys) 功能:将一个或多个按键消息发送到活动窗口,就如同在键盘上进行输入一样. 语法:SendKeys.Send(string keys);SendKeys.SendWa ...

  7. vscode 显示"没有活动的源代码控制提供程序“处理

    不知为何我的 VS Code 在 1.25 版本开始就一直 ”没有活动的源代码控制提供程序“,找了好几天都没找到,今天终于找到怎么处理了, 切换到插件中找到下图对应的 Git (可以直接再上面搜索框输 ...

  8. 【Qt编程】基于Qt的词典开发系列<十二>调用讲述人

    我们知道,win7系统自带有讲述人,即可以机器读出当前内容,具体可以将电脑锁定,然后点击左下角的按钮即可.之前在用Matlab写扫雷游戏的时候,也曾经调用过讲述人来进行游戏的语音提示.具体的Matla ...

  9. 【转贴】-- 基于QT的跨平台应用开发

    原帖地址:http://www.cnblogs.com/R0b1n/p/4106613.html 1 Qt简介 Qt是1991年奇趣科技开发的一个跨平台的C++图形用户界面应用程序框架.它提供给应用程 ...

随机推荐

  1. WampServer无法直接打开myprojects的解决方法

    https://jingyan.baidu.com/article/7e4409533ace042fc1e2ef40.html

  2. JDK设置Encoding编码格式

    执行JAVA程序报错内容如下: java.lang.IllegalStateException: The Java Virtual Machine has not been configured to ...

  3. windows 10 python 2.7和python3.6共存解决方法和pip安装

    一.首先去python官网将两个版本下载并安装: 然后进入windows的环境变量,检查下面4个变量: 1.C:\Python272.C:\Python27\Scripts3.D:\software\ ...

  4. MySQL 事务1

    本人应用的MySQL的版本为:5.6.22

  5. python 基础 9.0 安装MySQL-python-1.2.5客户端

    一. 安装客户端     python 标准数据库接口为Python DB-API,Python DB-API 为开发人员提供了数据应用编程接口.参考地址:https://wiki.python.or ...

  6. python 中读取excel

    第一步:  先下载一个xlrd 包 # pip install xlrd import xlrd from datetime import date, datetime file = '学生信息表.x ...

  7. To discount or not to discount in reinforcement learning: A case study comparing R learning and Q learning

    https://www.cs.cmu.edu/afs/cs/project/jair/pub/volume4/kaelbling96a-html/node26.html [平均-打折奖励] Schwa ...

  8. 【题解】Coins(二进制拆分+bitset)

    [题解]Coins(二进制拆分+bitset) [vj] 俗话说得好,bitset大法吼啊 这道题要不是他多组数据卡死了我复杂度算出来等于九千多万的选手我还不会想这种好办法233 考虑转移的实质是怎样 ...

  9. Flask:web表单

    客户端发送的所有通过POST发出的请求信息都可以通过request.form获取.但是如果我们要生成表单的HTML代码和验证提交的表单数据那么就需要采用另外的方法.Flask-WTF扩展可以把处理we ...

  10. chunkhash笔记

    假设有main1.main2两个入口文件,main引入chunk1.chunk2,main2引入chunk1 改变chunk2 main1的chunkhash改变,main2不发生改变 main再引入 ...