基于Qt Gui的Led控制显示程序

转载地址:   http://www.cnblogs.com/elect-fans/archive/2012/03/16/2408576.html    

      基于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 如下 :

复制代码
  1 #include <linux/miscdevice.h>
  2 #include <linux/delay.h>
  3 #include <asm/irq.h>
  4 #include <mach/regs-gpio.h>
  5 #include <mach/hardware.h>
  6 #include <linux/kernel.h>
  7 #include <linux/module.h>
  8 #include <linux/init.h>
  9 #include <linux/mm.h>
 10 #include <linux/fs.h>
 11 #include <linux/types.h>
 12 #include <linux/delay.h>
 13 #include <linux/moduleparam.h>
 14 #include <linux/slab.h>
 15 #include <linux/errno.h>
 16 #include <linux/ioctl.h>
 17 #include <linux/cdev.h>
 18 #include <linux/string.h>
 19 #include <linux/list.h>
 20 #include <linux/pci.h>
 21 #include <asm/uaccess.h>
 22 #include <asm/atomic.h>
 23 #include <asm/unistd.h>
 24 
 25 #define IOCTL_GPIO_ON  0
 26 #define IOCTL_GPIO_OFF 1
 27 #define DEVICE_NAME "leds"
 28 
 29 static unsigned long led_table [] = {
 30  S3C2410_GPB5,
 31  S3C2410_GPB6,
 32  S3C2410_GPB7,
 33  S3C2410_GPB8,
 34 };
 35 
 36 static unsigned int led_cfg_table [] = {
 37  S3C2410_GPB5_OUTP,
 38  S3C2410_GPB6_OUTP,
 39  S3C2410_GPB7_OUTP,
 40  S3C2410_GPB8_OUTP,
 41 };
 42 
 43 static int sbc2440_leds_ioctl(
 44  struct inode *inode,
 45  struct file *file,
 46  unsigned int cmd,
 47  unsigned long arg)
 48 {
 49  switch(cmd) {
 50  // 设置指定引脚的输出电平为0,即低电平,灯亮
 51  case IOCTL_GPIO_ON:
 52   s3c2410_gpio_setpin(led_table[arg], cmd);
 53   return 0;
 54  // 设置指定引脚的输出电平为1,即高电平,灯灭
 55  case IOCTL_GPIO_OFF:
 56   s3c2410_gpio_setpin(led_table[arg], !cmd);
 57   return 0;
 58 
 59  default:
 60   return -EINVAL;
 61  }
 62 }
 63 
 64 static struct file_operations dev_fops = {
 65  .owner = THIS_MODULE,
 66  //.open = sbc2440_leds_open,
 67  //.release= sbc2440_leds_close,
 68  .ioctl = sbc2440_leds_ioctl,
 69 };
 70 
 71 static struct miscdevice misc = {
 72  .minor = MISC_DYNAMIC_MINOR,
 73  .name = DEVICE_NAME,
 74  .fops = &dev_fops,
 75 };
 76 
 77 static int __init dev_init(void)
 78 {
 79  int ret;
 80 
 81  int i;
 82  
 83  for (i = 0; i < 4; i++) {
 84   s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
 85   s3c2410_gpio_setpin(led_table[i], 0);
 86  }
 87 
 88  ret = misc_register(&misc);
 89 
 90  printk (DEVICE_NAME"/tinitialized/n");
 91 
 92  return ret;
 93 }
 94 
 95 static void __exit dev_exit(void)
 96 {
 97  misc_deregister(&misc);
 98 }
 99 
100 module_init(dev_init);
101 module_exit(dev_exit);
102 MODULE_LICENSE("GPL");
103 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

复制代码
 1 #ifndef LED_H
 2 #define LED_H
 3 
 4 #include <QObject>
 5 
 6 class Led : public QObject
 7 {
 8     Q_OBJECT
 9 public:
10     explicit Led(QObject *parent = 0);
11 
12 public:
13     int fd;
14     int on[4];
15 
16 public:
17     // Led();
18     ~Led();
19 
20 public:
21     void led1_on();
22     void led2_on();
23     void led3_on();
24     void led4_on();
25 };
26 
27 #endif // LED_H
复制代码



================================================
led.cpp

复制代码
 1 #include "led.h"
 2 
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <fcntl.h>
 6 #include <stdio.h>
 7 #include <sys/ioctl.h>
 8 #include <stdlib.h>
 9 #include <unistd.h>
10 
11 Led::Led(QObject *parent) :
12     QObject(parent)
13 {
14     on[0] = 0;
15     on[1] = 0;
16     on[2] = 0;
17     on[3] = 0;
18 
19     fd = open("/dev/leds",0);
20     // cout<<"fd = "<<fd<<endl;
21     if ( fd < 0 )
22     {
23         perror("Error : fd < 0");
24     }
25 }
26 
27 void Led::led1_on()
28 {
29     on[0] = (~on[0]) & 1;
30     ioctl(fd,on[0],0);
31 }
32 
33 void Led::led2_on()
34 {
35     on[1] = (~on[1]) & 1;
36     ioctl(fd,on[1],1);
37 }
38 
39 void Led::led3_on()
40 {
41     on[2] = (~on[2]) & 1;
42     ioctl(fd,on[2],2);
43 
44 }
45 
46 void Led::led4_on()
47 {
48     on[3] = (~on[3]) & 1;
49     ioctl(fd,on[3],3);
50 }
51 
52 Led::~Led()
53 {
54    //close(fd);
55 }
复制代码

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

 

      第三,GUI的设计。

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

leddialog.h

复制代码
 1 #ifndef LEDDIALOG_H
 2 #define LEDDIALOG_H
 3 
 4 #include <QtGui/QDialog>
 5 #include <Qt/QtGui>
 6 #include "led.h"
 7 
 8 class LedDialog : public QDialog
 9 {
10     Q_OBJECT
11 
12 private :
13     QLabel      *label;
14     QPushButton *led1Button;
15     QPushButton *led2Button;
16     QPushButton *led3Button;
17     QPushButton *led4Button;
18     QPushButton *exitButton;
19     Led *ledobj;
20 
21 private slots :
22     void Light_style1(void);
23     void Light_style2(void);
24     void Light_style3(void);
25     void Light_style4(void);
26     void Light_style_exit(void);
27     void Light_delay(int times);
28 
29 public:
30     LedDialog(QWidget *parent = 0);
31     ~LedDialog();
32 };
33 
34 #endif // LEDDIALOG_H
复制代码

=========================================================================================

leddialog.cpp

复制代码
 1 #include "leddialog.h"
 2 #include <QtGui>
 3 
 4 //Construction Function
 5 LedDialog::LedDialog(QWidget *parent)
 6     : QDialog(parent)
 7 {
 8     // init component
 9     label= new QLabel(tr("Set Led"));
10     led1Button = new QPushButton(tr("Led1"));
11     led2Button = new QPushButton(tr("Led2"));
12     led3Button = new QPushButton(tr("Led3"));
13     led4Button = new QPushButton(tr("Led4"));
14     exitButton = new QPushButton(tr("Exit"));
15     ledobj = new Led();
16 
17     //layout component
18     QVBoxLayout *layout = new QVBoxLayout;
19     layout->addWidget(label,Qt::AlignTop);
20     layout->addWidget(led1Button);
21     layout->addWidget(led2Button);
22     layout->addWidget(led3Button);
23     layout->addWidget(led4Button);
24     layout->addWidget(exitButton);
25     setLayout(layout);
26     //resize(200,230);
27 //setFixedSize(200,230);
28 // this->setFixedSize( this->width (),this->height ());
29     setMinimumSize(200, 230);
30     setMaximumSize(200, 230);
31 
32     // signal-slots connect
33     QObject::connect(led1Button, SIGNAL(clicked()), this, SLOT(Light_style1()));
34     QObject::connect(led2Button, SIGNAL(clicked()), this, SLOT(Light_style2()));
35     QObject::connect(led3Button, SIGNAL(clicked()), this, SLOT(Light_style3()));
36     QObject::connect(led4Button, SIGNAL(clicked()), this, SLOT(Light_style4()));
37     QObject::connect(exitButton, SIGNAL(clicked()), this, SLOT(Light_style_exit()));
38 
39 }
40 
41 //self-declaration function implement
42 void LedDialog::Light_style1(void)
43 {
44         ledobj->led1_on();
45         Light_delay(100);
46 }
47 
48 void LedDialog::Light_style2(void)
49 {
50 
51         ledobj->led2_on();
52         Light_delay(2000);
53 }
54 
55 void LedDialog::Light_style3(void)
56 {
57         ledobj->led3_on();
58         Light_delay(2000);
59 }
60 
61 void LedDialog::Light_style4(void)
62 {
63     ledobj->led4_on();
64     Light_delay(2000);;
65 }
66 
67 void LedDialog::Light_style_exit(void)
68 {
69     exit(0);
70 }
71 
72 void LedDialog::Light_delay(int times)
73 {
74     int i;
75     int j;
76     for (i = 0;i < times; i++)
77         for (j = 0; j < times; j++)
78         {
79             // Null function
80         }
81 }
82 
83 LedDialog::~LedDialog()
84 {
85 
86 }
复制代码

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

复制代码
 1 #include <QtGui/QApplication>
 2 //#include <QTextCodec>
 3 #include "led.h"
 4 #include "leddialog.h"
 5 
 6 #include "leddialog.h"
 7 
 8 int main(int argc, char *argv[])
 9 {
10     QApplication a(argc, argv);
11     LedDialog w;
12     // QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
13          w.show();
14     return a.exec();
15 }
复制代码

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值