永利真人

技术支持   Support
永利真人   Contact
搜索   Search

Linux下的ds18b20驱动

2019-3-18 9:30:25      点击:

运行环境 Fedora9.0

永利真人 交叉编译 arm-linux-gcc-4.3.2

永利真人 今天在各位前辈已有成就的基础上花了两天时间终于把这个驱动给搞定了,从开始编译成模块看效果,进行调试,再到编译进内核,最后又编译了一个界面出来,虽说大多数的程序代码是用各位前辈的成果,但坐下来自己收获也不小,现在写下来,以供以后参考,也和各位爱好者交流一下,呵呵!

一.编译成模块

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/sched.h>
#include <linux/delay.h> 
#include <linux/fs.h>  
#include <linux/init.h>    
#include <linux/miscdevice.h>  
#include <asm/irq.h>  
#include <mach/regs-gpio.h>  
#include <mach/hardware.h>  
#include <asm/uaccess.h>
#define DEVICE_NAME "DS18B20"  
#define DS18B20_MAJOR 250  
#define DS_PIN S3C2410_GPB1  
#define OUT S3C2410_GPB1_OUTP  
#define IN S3C2410_GPB1_INP  
#define DIS_UP 1  
#define EN_UP 0  
//#define Search 0x00F0  
#define Read_ROM 0x0033  //just for one  
#define Skip_ROM 0x00CC   //ds18b20的固定时序, 跳过读序号列号的操作 
#define Convert 0x0044  //ds18b20的固定时序,管脚识别到该信号是开始对测到的温度进行转换
#define Write 0x004E  //TH---TL---Config  
#define Read 0x00BE   //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
//#define bit_9 0x001F  
//#define bit_10 0x003F  
//#define bit_11 0x005F  
#define bit_12 0x007F  
#define uint16 unsigned int  
//unsigned int ROM_DATA[8];  
void usdelay(unsigned int i)

{  
unsigned int j;  
for(i=i;i>0;i--)  
  for(j=90;j>0;j--);  
}  
void msdelay(unsigned int i) //延时 i ms  
{  
for(i=i;i>0;i--)  
  usdelay(1000);  
}  
void SetL(void)  
{  
s3c2410_gpio_cfgpin(DS_PIN,OUT);  
s3c2410_gpio_setpin(DS_PIN,0);  
}  
void SetH(void)  
{  
s3c2410_gpio_cfgpin(DS_PIN,OUT);  
s3c2410_gpio_setpin(DS_PIN,1);  
}  
unsigned int Read_DS(void)  
{  
unsigned int i;  
s3c2410_gpio_cfgpin(DS_PIN,IN);  
s3c2410_gpio_pullup(DS_PIN,EN_UP);
  
__asm("nop");  
__asm("nop");  
__asm("nop");  
i=s3c2410_gpio_getpin(DS_PIN);  
if(i!=0)  
  i=1;  
return i;  
}  
unsigned int ds_start(void)  //初始化ds18b20
{  
unsigned int flag=1;
int err=0;
SetH();
udelay(2); 
SetL();  
udelay(600); //560延时要大于480u  
SetH();  
udelay(60);   //稍作延时
while(Read_DS()!=0)   //ds18B20初始化成功会返回一个低电平,此时跳出循环,执行下面的操作
{  
  printk(DEVICE_NAME "Wait....\n");  
  udelay(5);  
  err++;   //初始化的最多次数吧,超过规定的次数,说明初始化失败
  if(err==20)  
  {  
   printk(DEVICE_NAME "start fail\n");  
   return -1;  
  }  
}  
//printk(DEVICE_NAME "start sucess\n");  
flag=0;  
SetH();//初始化成功后赋为高电平准备从外界读入温度  
udelay(400);  
return flag;  
}  
void ds_send(unsigned int uidata)   //向18b20写入一个字节的数据
{  
//printk("the send data is %d\n",uidata);
 int i;  
 for(i=0;i<8;i++)  
 {  
  SetL();
  udelay(1); 
  if((uidata&1)!=0)
   {    
    SetH();  
    udelay(80);    //等待18b20进行数据采集
   }  
  else 
   {  
    udelay(80);  //等待18b20进行数据采集  
    SetH();     
    }  
  uidata>>=1;  
 }  
}  
unsigned int ds_read(void)    //从18b20读一个字节的数据
{  
 unsigned int uidata=0;unsigned int i;  
 for(i=0;i<8;i++)  
  { 
   uidata>>=1; 
   SetL();  
   udelay(1);   
   s3c2410_gpio_setpin(DS_PIN,1);
   s3c2410_gpio_cfgpin(DS_PIN,IN);
   udelay(10);    
   if(s3c2410_gpio_getpin(DS_PIN))
       uidata=(uidata|0x80);         
   udelay(65); 
   SetH();
   }  
// printk("ds_read success\n");
 return uidata;   
}  
 
unsigned int read_tem(void)  
{  
unsigned int th,tl;
//int err=0;  
//ds_init(100,0,bit_12);
th=tl=0;   
ds_start();     
ds_send(Skip_ROM);   //跳过读序号列号的操作
ds_send(Convert);    //启动温度转换
mdelay(50);    
ds_start();  
ds_send(Skip_ROM);   //跳过读序号列号的操作
ds_send(Read);       //准备读温度
tl=ds_read();  
th=ds_read();      
th<<=8;             //温度在低两个字节中
//printk("the tl data is %d\n",tl);  
tl|=th;            //获取温度
//printk("the th data is %d\n",th);
//printk("the tl2 data is %d\n",tl);
//printk("read_tmp success\n"); 
return tl;  
}  
 
static int ds18b20_ioctl(  
struct inode *inode,   
struct file *file,   
unsigned int cmd,unsigned long arg)  
{  
return 0;  
}  
static ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off )  
{  
    uint16 tmp,ret;  
      
    tmp =read_tem();
//    printk("the tmpk data is %d\n",tmp); 
    ret=copy_to_user(pData, &tmp, sizeof(tmp));    //将读取得的DS18B20数值复制到用户区  
if(ret>0)  
{  
  printk("copy data failed\n");  
  return -1;  
}
//else
 // printk("copy data succese\n"); 
return 0;  
}  
static struct file_operations ds18b20_fops = {  
.owner = THIS_MODULE,  
.ioctl = ds18b20_ioctl,  
.read = ds18b20_read,  
};  
static int __init ds18b20_init(void)  
{  
int ret;  
ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);  
if (ret < 0) {  
   printk(DEVICE_NAME " can't register major number\n");  
   return ret;  
}    
s3c2410_gpio_cfgpin(DS_PIN, OUT);  
s3c2410_gpio_setpin(DS_PIN, 1);  
printk(DEVICE_NAME " initialized\n");  
return 0;  
}  
static void __exit ds18b20_exit(void)  
{     
unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);  
printk(DEVICE_NAME " rmmodule\n");  
}  
module_init(ds18b20_init);  
module_exit(ds18b20_exit);  
MODULE_AUTHOR("benjamin_xc@163.com");             // 驱动程序的作者  
MODULE_DESCRIPTION("DS18B20 Driver");   // 一些描述信息  
MODULE_LICENSE("GPL");

永利真人 下面是将驱动编译成模块的过程:

1.将编写好的驱动代码copy或move到你的内核驱动代码中,比如我的是FriendlyARM/mini2440/linux2.6.29/drivers/char

2.编辑char目录下的Makefile文件,添加如下obj-m += 18b20.o 注意此处红色的部分要和你自己建的程序代码的文件名保持一致。

永利真人 3.退到Linux根目录下,我的就是linux2.6.29,输入命令make modules。

如果没有错误,在char目录下就会看到编译后的18b20.ko的模块文件。

永利真人 使用ftp或是串口将编译好的模块文件下载到开发板上

永利真人 接下来就是加载设备驱动程序模块了

永利真人 1.创建设备驱动程序的进入点mknod /dev/DS18B20 c 250 0 此处的主设备号要和你在程序中设定的一样,创建的设备接口文件要和测试程序中的保持一致啊!

2.加载驱动程序 insmod 18b20.ko

如果上面的步骤没出差错,就说明驱动方法这块是搞定的了。

永利真人 此处说下和本驱动没直接联系的话,各位别嫌我啰嗦啊,因为我做的时候碰到了,还郁闷了好几天的。想必有些朋友在将内核编译成模块后,在加载是没有什么错误,用lsmod命令来看,自己的模块也确实是加载进去了,但是在用rmmod进行卸载时,却出现提示说,找不到需要卸载的文件,因此在这个问题解决之前,每次加载后,想要卸载都要重新启动开发板,麻烦呀,后来终于在一个论坛里看到了解决方法,在/lib/modules/下建立Linux2.6.29.4-FriendlyARM文件夹,然后把想加载的模块放到这个文件中,这个问题就解决了,具体原因自己也不知道,能用就OK了吧,呵呵,感谢各位前辈的努力啊!

下面是测试代码(这是完全从网上搜的哦,再次感谢各位大哥)

#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <sys/ioctl.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <sys/select.h>  
#include <sys/time.h>  
#include <errno.h>  
#define K 0.0625  
int main(void)  
{  
    int fd = -1;  
    char count = 5;  
    unsigned int tmp = 0;float res=0;  
    fd = open("/dev/DS18B20", 0);  
    if(fd < 0)  
    {  
        perror("Can't open /dev/DS18B20 \n");  
        exit(1);  
    }  
    printf("open ds18b20 success \n");  
while(1){  
        read(fd, &tmp , sizeof(tmp));  
    res=tmp*K;
    //printf("the currently data is %d\n",tmp);  
    printf("the currently temperature is %f\n",res);  
    sleep(5);  
}  
close(fd);  
    return 0;  
}

永利真人 下面简单介绍一下ds18b20的东西吧:

具体可参考

大致有以下几种形状的

1.jpg

用的最多的当然是最左边的三针的,管脚少,操作也简单嘛。另外有一点注意,就是用的时候DQ(数据管脚)和VD之间要加一个4k—10k的电阻。

心情好,事情才能做得好!!

交叉编译过之后或是用NFS或者下载到板子上都可以,没什么差错的话就可以实现测温了。

永利真人 下面是运行情况

2.jpg

以上是手离开传感器后温度的变化情况。

永利真人 下面简单介绍一下ds18b20的东西吧

永利真人 1.DS18B20是Dallas公司生产的数字温度传感器,具有体积小、适用电压宽、经济灵活的特点。它内部使用了onboard专利技术,全部传感元件及转换电路集成在一个形如三极管的集成电路内。DS18B20有电源线、地线及数据线3根引脚线,工作电压范围为3~5.5 V,支持单总线接口。

永利真人 DS18B20的结构和工作原理

永利真人 2.1DS18B20的内外结构

永利真人 DS18B20的外部结构如图1所示。其中,VDD为电源输入端,DQ为数字信号输入/输出端,GND为电源地。

3.jpg

永利真人 DS18B20内部结构主要包括4部分:64位光刻ROM、温度传感器、非易失的温度报警触发器TH和TL、配置寄存器,如图2所示。

4.jpg

64位ROM中,在产品出厂前就被厂家通过光刻刻录好了64位序列号。该序列号可以看作是DS18B20的地址序列码,用来区分每一个DS18B20,从而更好地实现对现场温度的多点测量。

图2中的暂存器是DS18B20中最重要的寄存器。暂存器由9个字节组成,各字节定义如表1所列。

5.jpg

永利真人 配置寄存器用于用户设置温度传感器的转换精度,其各位定义如下:

6.jpg

TM位是测试模式位,用于设置DS18B20是工作模式(0)还是测试模式(1),其出厂值为0。R1、R0用于设置温度传感器的转换精度:00,分辨率为9位,转换时间为93.75ms;01,分辨率为10位,转换时间为187.5 ms;10,分辨率为11位,转换时间为375 ms;11,分辨为12位,转换时间为750 ms。R1、R0的出厂值为11。其余5位值始终为1。

永利真人 第0和第1字节为16位转换后的温度二进制值,其中前4位为符号位,其余12位为转换后的数据位(分辨率为12位)。如果温度大于0,则前4位值为0,只要将测到的数值乘上0.062 5即可得到实际温度值;如果温度小于0,则前4位为1,需将测得的数值取反加1后,再乘上0.062 5。第0和第1字节各位的二进制值如下:

7.jpg

永利真人 3. DS18B20的应用电路结构

按DS18B20的供电方式,其应用电路结构可分为如下3种:寄生电源供电方式;寄生电源强上拉供电方式;外部电源供电方式。实际应用中,以外部电源供电方式为主。其应用原理图如图3所示。

8.jpg

4. DS18B20的工作原理

永利真人 根据DS18B20的通信协议,MCU对其操作主要有如下3个步骤:读写之前,对DS18B20发送约500 μs的低电平进行复位;复位成功,发送ROM指令;发送RAM指令。MCU对DS18B20的具体操作流程如图4所示。

9.jpg

永利真人 5. 实物图

10.jpg

6.具体电路

11.jpg

其中p1.7是指你自己选的管脚

二.编译进内核

程序代码和上面的没有本质的差别,就是多了一些,创建设备节点的函数

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/sched.h>
#include <linux/delay.h> 
#include <linux/fs.h>  
#include <linux/init.h>      
#include <asm/irq.h>  
#include <mach/regs-gpio.h>  
#include <mach/hardware.h>  
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <asm/io.h>
#include <plat/regs-timer.h>
 

 
#define DS_PIN S3C2410_GPB1  
#define OUT S3C2410_GPB1_OUTP  
#define IN S3C2410_GPB1_INP  
#define DIS_UP 1  
#define EN_UP 0  
//#define Search 0x00F0  
#define Read_ROM 0x0033  //just for one  
#define Skip_ROM 0x00CC   //ds18b20的固定时序,管脚识别到该信号时开始从外界获取温度 
#define Convert 0x0044  //ds18b20的固定时序,管脚识别到该信号是开始对测到的温度进行转换
#define Write 0x004E  //TH---TL---Config  
#define Read 0x00BE  
//#define bit_9 0x001F  
//#define bit_10 0x003F  
//#define bit_11 0x005F  
#define bit_12 0x007F  
#define uint16 unsigned int  
//unsigned int ROM_DATA[8]; 
#define DEVICE_NAME "DS18B20"  
#define DS18B20_MAJOR 0 
static int device_major = DS18B20_MAJOR; //系统动态生成的主设备号
void usdelay(unsigned int i) //延时 i us 对于不同系统可能会有所差别,请适当修改  
{  
unsigned int j;  
for(i=i;i>0;i--)  
  for(j=90;j>0;j--);  
}  
void msdelay(unsigned int i) //延时 i ms  
{  
for(i=i;i>0;i--)  
  usdelay(1000);  
}  
void SetL(void)  
{  
s3c2410_gpio_cfgpin(DS_PIN,OUT);  
s3c2410_gpio_setpin(DS_PIN,0);  
}  
void SetH(void)  
{  
s3c2410_gpio_cfgpin(DS_PIN,OUT);  
s3c2410_gpio_setpin(DS_PIN,1);  
}  
unsigned int Read_DS(void)  
{  
unsigned int i;  
s3c2410_gpio_cfgpin(DS_PIN,IN);  
s3c2410_gpio_pullup(DS_PIN,EN_UP);
  
__asm("nop");  
__asm("nop");  
__asm("nop");  
i=s3c2410_gpio_getpin(DS_PIN);  
if(i!=0)  
  i=1;  
return i;  
}  
unsigned int ds_start(void)  //初始化ds18b20
{  
unsigned int flag=1;
int err=0;
SetH();
udelay(2); 
SetL();  
udelay(600); //560延时要大于480u  
SetH();  
udelay(60);   //稍作延时
while(Read_DS()!=0)   //ds18B20初始化成功会返回一个低电平,此时跳出循环,执行下面的操作
{  
  printk(DEVICE_NAME "Wait....\n");  
  udelay(5);  
  err++;   //??应该是初始化的最多次数吧??
  if(err==20)  
  {  
   printk(DEVICE_NAME "start fail\n");  
   return -1;  
  }  
}  
//printk(DEVICE_NAME "start sucess\n");  
flag=0;  
SetH();//初始化成功后赋为高电平准备从外界读入温度  
udelay(400);  
return flag;  
}  
void ds_send(unsigned int uidata)  
{  
//printk("the send data is %d\n",uidata);
 int i;  
 for(i=0;i<8;i++)  
 {  
  SetL();
  udelay(1); 
  if((uidata&1)!=0)
   {    
    SetH();  
    udelay(80);  
   }  
  else 
   {  
    udelay(80);  
    SetH();     
    }  
  uidata>>=1;  
 }  
}  
unsigned int ds_read(void)  
{  
 unsigned int uidata=0;unsigned int i;  
 for(i=0;i<8;i++)  
  { 
   uidata>>=1; 
   SetL();  
   udelay(1); //2 3  
   s3c2410_gpio_setpin(DS_PIN,1);
   s3c2410_gpio_cfgpin(DS_PIN,IN);
   udelay(10); //1 2 3 4 5(e)  
   if(s3c2410_gpio_getpin(DS_PIN))
       uidata=(uidata|0x80);         
   udelay(65); 
   SetH();
   }  
// printk("ds_read success\n");
 return uidata;   
}  
 
unsigned int read_tem(void)  
{  
unsigned int th,tl;
//int err=0;  
//ds_init(100,0,bit_12);
th=tl=0;   
ds_start();     
ds_send(Skip_ROM);  
ds_send(Convert);  
mdelay(50);    
ds_start();  
ds_send(Skip_ROM);  
ds_send(Read);
tl=ds_read();  
th=ds_read();      
th<<=8;
//printk("the tl data is %d\n",tl);  
tl|=th;
//printk("the th data is %d\n",th);
//printk("the tl2 data is %d\n",tl);
//printk("read_tmp success\n"); 
return tl;  
}  
 
static int ds18b20_ioctl(  
struct inode *inode,   
struct file *file,   
unsigned int cmd,unsigned long arg)  
{  
return 0;  
}  
static ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off )  
{  
    uint16 tmp,ret;  
      
    tmp =read_tem();
//    printk("the tmpk data is %d\n",tmp); 
    ret=copy_to_user(pData, &tmp, sizeof(tmp));    //将读取得的DS18B20数值复制到用户区  
if(ret>0)  
{  
  printk("copy data failed\n");  
  return -1;  
}
//else
 // printk("copy data succese\n"); 
return 0;  
}  
static struct file_operations ds18b20_fops = {  
.owner = THIS_MODULE,  
.ioctl = ds18b20_ioctl,  
.read = ds18b20_read,  
};
static struct class *tmp_class;//从此处开始和上面的代码有区别了啊
 
static int __init ds18b20_init(void)  
{     
device_major = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);  
 if (device_major < 0)
 {  
   printk(DEVICE_NAME " can't register major number\n");  
   return -1;  
 }  
tmp_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(tmp_class))
    {
        printk(DEVICE_NAME " register class falid!\n");
        return -1;
    }
 //创建一个设备节点,设备名为tmp_NAME,即:my2440_tmp
 device_create(tmp_class, NULL, MKDEV(device_major, 0), NULL, DEVICE_NAME);  
 s3c2410_gpio_cfgpin(DS_PIN, OUT);  
 s3c2410_gpio_setpin(DS_PIN, 1);  
 printk(DEVICE_NAME " initialized\n");  
 return 0;  
}  
static void __exit ds18b20_exit(void)  

   
unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);
     //删除设备节点
    device_destroy(tmp_class, MKDEV(device_major, 0));
    //注销设备类
    class_destroy(tmp_class); 
printk(DEVICE_NAME " rmmodule\n");  
}  
module_init(ds18b20_init);  
module_exit(ds18b20_exit);  
MODULE_AUTHOR("BINBIN");             // 驱动程序的作者  
MODULE_DESCRIPTION("DS18B20 Driver");   // 一些描述信息  
永利真人 MODULE_LICENSE("GPL");

永利真人 将上面的驱动程序保存为DS18B20.c,下面有解释,为什么要保存成该名称

编译方法

永利真人 1. 将驱动程序放到FriendlyARM/mini2440/linux2.6.29/drivers/char目录下

永利真人 2. 编译char目录里的Kconfig文件添加如下内容

永利真人 config MY2440_TMP //在Makefile中用

永利真人 tristate "My2440 TMP Device"

永利真人 depends on ARCH_S3C2440

永利真人 default y

永利真人 ---help---

My2440 TMP

3. 编译char目录下的Makefile文件 添加如下内容

obj-$(CONFIG_MY2440_TMP) += DS18B20.o //这里就体现出了上面将驱动保存成DS18B20.c的原因了吧

4. 编译内核,在Linux2.6.29目录下执行命令:make zImage

然后将内核烧录到板子里,直接运行测试程序就可以看到和上面用加载模块方法一样的效果了。

三.编写界面

永利真人 1.最终效果

12.jpg

运行时,会将测到的温度显示在上面的框中,转换的次数会显示在下面的框中。有程序可知按下Start按钮,可以转换20次,再按下会继续测。

永利真人 运行环境 按照友善之臂的手册,安装好Qtopia-2.2.0

1.编写.ui文件

永利真人 打开Qtopia2.2.0编译出入上界面,窗体名字是:TMPBaseForm,因为下面的程序要用到这个基类,如果要改名字请保证后面程序中用相同的名字

2.编写tmp.h文件

#ifndef MYHELLOFORM_H
#define MYHELLOFORM_H
#include "tmp_base.h"
#include <qpixmap.h>
class MyTMPForm : public TMPBaseForm
{
    Q_OBJECT
 
    public:
        MyTMPForm( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
     virtual ~MyTMPForm();
     //const QPixmap *eddy;
  int fd;
    private slots:
        void startTMP();
永利真人  void stopTMP();

};
#endif // MYHELLOFORM_H

3.编写tmp.cpp文件

#include "tmp.h"
#include <qlabel.h>
#include <qpushbutton.h>
#include <qspinbox.h>
#include <qlcdnumber.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>
#define K 0.0625;
 
MyTMPForm::MyTMPForm( QWidget* parent, const char* name, WFlags fl)
     :TMPBaseForm(parent, name, fl)
{
fd=0;
    connect(PushButton1,SIGNAL(clicked()),this,SLOT(startTMP()));
connect(PushButton2,SIGNAL(clicked()),this,SLOT(stopTMP()));
 
}
 
MyTMPForm::~MyTMPForm()
{
 ::close(fd);
}
 
 
 
void MyTMPForm::startTMP()
{
永利真人     //TextLabel1->setText("System Led is Started");

 fd = ::open("/dev/DS18B20", 0);
 if (fd < 0)
           {
  ::exit(1);
    }
 for(int num=0;num<20;num++)
               {
              unsigned int tmp = 0;
              float res=0;     
              read(fd, &tmp , sizeof(tmp));  
              res=tmp*K;    
  LCDNumber1->display(res);
              sleep(3);
  LCDNumber2->display(num);
         } 
 ::close(fd);
}
void MyTMPForm::stopTMP()
{
::close(fd);
}

永利真人 4.编写main.cpp

#include "tmp.h"
#include <qtopia/qpeapplication.h>
QTOPIA_ADD_APPLICATION("tmp",MyTMPForm)
QTOPIA_MAIN

5.编写tmp.desktop

[Desktop Entry]
Comment=An Example Program
Exec=tmp
Icon=alarmbell
Type=gaof  
永利真人 Name=TMP

6.编写tmp.pro文件

CONFIG  += qtopiaapp
CONFIG  -= buildQuicklaunch
HEADERS = tmp.h
SOURCES = tmp.cpp
SOURCES+=main.cpp
INTERFACES = tmp_base.ui
desktop.files = tmp.desktop
desktop.path = /apps/gaof
INSTALLS += desktop
TARGET  = tmp

7.编写build

永利真人 #!/bin/bash

source /opt/FriendlyARM/mini2440/arm-qtopia/qtopia-2.2.0-FriendlyARM/setQpeEnv

qmake -spec /opt/FriendlyARM/mini2440/arm-qtopia/qtopia-2.2.0-FriendlyARM/qtopia/mkspecs/qws/linux-arm-g++ -o Makefile *.pro

永利真人 make clean

make

永利真人 以上都做好后执行./bulid

永利真人 将生成的tmp可执行文件下载到板子上,并将其移到/opt/Qtopia/bin/目录下

永利真人 将tmp.desktop下载到板子上,并移动到/opt/Qtopia/apps/gaof/目录下 此处的gaof是我建立的各人可能不同,自己更改

重启板子就会看到和开始介绍的一样的界面效果了。

永利皇宫娱乐 永隆国际注册 bte365注册 永利娱乐.com 彩票巴巴——Home 永利会娱乐平台 银河澳门娱乐 www.2189.com——Home 永利贵宾会 www.4249.com——Home 360搜索,SO靠谱 快博娱乐 网赚靠谱吗 永利娱乐真钱游戏 网赚靠谱吗 www.5710.com——Home 金马国际娱乐——Home www.6196.com——Home www.5087.com——Home 豪门会彩票投注 金福彩票永利真人 彩票2元网 红彩会 大公鸡七星彩 鼎盛国际 纽约国际——Home 名汇国际注册 名汇国际注册 支付宝彩票 永利皇宫最新网站 彩票下注网址 快博娱乐 爱彩票 永利皇宫娱乐网站 GT彩票注册 皇都彩票永利真人 bbin平台 六合杀手 pk10操盘手 永利彩票注册 纽约国际——Home drf8.com -Home www.4997.com——Home www.4506.com——Home 微信购彩大厅 彩合网——Home E乐彩票网站 博乐网 永利电子娱乐 快赢彩票登陆 优彩网主站 凤凰新平台 68彩票投注 www.4046.com——Home 皇冠彩票官网 皇都彩票入口 庞博国际 名汇国际注册 金鼎国际娱乐 名汇国际注册 M5彩票网站 www.5385.com——Home 金沙网络赌场 百家乐登录 冠军彩票开户 永利国际赌博 冠军彩票开户 永利在线官网 永利电子平台 KK娱乐 88娱乐网 88娱乐网 M5彩票网站 88娱乐网 新利18 -Home 购彩网 雀彩-纽约国际 www.6617.com——Home 酷发巴巴彩票网 真人棋牌官网 KK娱乐 MG电子游戏 六合杀手 赢钱捕鱼 彩乐汇彩票 www.6216.com——Home 平台投注 www.2081.com——Home 凯旋门娱乐注册 财神汇彩票登陆 pk10技巧 博乐彩票网站 乐彩登录 号百彩票 博乐彩票网站 群英会网址 www.1663.com——Home 乐都彩票投注 永利网上娱乐 永利登录 百姓彩票网 凯旋门娱乐注册 永利国际电子游戏 www.1556.com——Home www.6210.com——Home 永利皇宫 全迅彩票开户 如意彩票网站 永利娱乐真钱游戏 彩民村 永利国际官方网站 彩票下注网址 大宝注册 淘宝彩票 皇都彩票是真是假 淘宝彩票 F1娱乐 永利皇宫备用网址 丰亿彩票下注 万福彩票开户 乐赢彩票永利真人 www.5403.com——Home 永利皇宫 国际赌场 3680.com -Home 辉煌国际官方 www.3652.com——Home 永利娱乐真钱游戏 bbin平台 博乐彩票网站 百乐坊娱乐 5颗星彩票开户 永利电子娱乐 彩票下注网址 永利国际电子游戏 www.1556.com——Home 永旺国际 众彩彩票下注 永利皇宫娱乐官网 快乐彩票登陆 大乐购彩票平台 彩盈彩票投注 金沙网络赌场 皇家网址 趣彩彩票注册 www.4182.com——Home 通乐国际官网 17博-bte365注册 bte365注册官网 金禾娱乐 如意彩 辉煌国际官方 www.2106.com——Home 申博官网 众彩彩票下注 传奇彩票永利真人 万达国际娱乐平台 广发彩票登录 www.4093.com——Home 大乐购彩票平台 天天博彩票登录 球探彩票 爱投彩票投注 亚泰分分彩 永利国际开户 GT彩票注册 真人棋牌网址 久久彩票注册 百利宫娱乐 永利会娱乐场 567彩票 如意彩票网站 pk10操盘手 中福在线 1233彩票 彩票巴巴 双赢彩票app官方地址 新一代的跑狗社 苹果彩票注册 必赢亚洲官网登录入口 www.2377.com——Home 龙虎娱乐登录 永利会手机网址 现金斗牛 速博国际娱乐 智胜彩票 悦彩票 永利贵宾会 www.5332.com——Home 宝马会 趣彩彩票注册 bet007.com 澳门贵宾厅赌场 明升88 达人娱乐 发彩网登录 www.5347.com——Home 永利博国际网 皇族彩票注册 乐和彩 玩彩app 永利娱乐登录 大润发娱乐 彩盈彩票投注 bte365注册 彩客登录 澳门威尼斯人网址 亚泰分分彩 远东国兰有限公司 双赢彩票手机 永利银河 龙虎娱乐登录 亿彩网 庞博国际 彩民村 抖音彩票注册 网赚平台靠谱吗 永利皇宫官网 永利.com BBIN糖果派对 999彩票登陆 5颗星彩票开户 现金斗牛 庞博国际 爱彩票 总统娱乐 鸿利彩票永利真人 433足球网会员 尊亿国际 永利正网开户 pk10技巧 丰亿彩票下注 爱投彩票投注 北京赛车账号注册 诚信彩票登陆 环博国际 -Home 赢宝捕鱼 博必发 球探彩票 迪拜皇宫 -Home 致富彩票app 澳门永利皇宫备用网址 www.5719.com——Home 银河娱乐 澳门老葡京 永利皇宫娱乐网站 永利银河国际 永利电子平台 富邦娱乐 澳门宝马线上娱乐 W彩票网网址 真人棋牌网址 爱波体育 北京赛车猜冠军 301.com—HOME 皇都彩票是真是假 大公鸡七星彩 致富彩票注册 投注平台 F1娱乐 -Home 百乐坊娱乐 永利ag 彩客登录 彩票专业投注平台 PK彩票永利真人 www.1427.com——Home 鼎盛国际 bet007.com 淘宝彩票注册 苹果彩票注册 彩客网彩票永利真人 跑狗出社新一代主论坛 旺彩11选5 必发彩票注册 永利手机网投 时时彩平台推荐 捷豹60秒分分彩计划 天上人间国际娱乐 买马图2019 永利国际赌城 蚂蚁彩票永利真人 新一代的跑狗社 www.4043.com——Home 乐发国际 葡京娱乐——Home 万福彩票开户 澳门新永利娱乐 泰彩彩票 永利登录 Bet888 新利彩票注册 腾讯分分彩 AG游戏 金沙网络赌场 永利皇宫娱乐 永利娱乐网址 永利皇宫娱乐网站 泰彩彩票 www.7084.com——Home 一定牛彩票网 u宝娱乐登录 如意彩票网 新一代的跑狗社 永利娱乐网址 皇族彩票注册 淘宝彩票 澳门金沙网 365真的新注册送188 总统娱乐注册 www.587.com——Home Bt365.com -Home 鼎盛彩票注册 www.6939.com——Home 永旺国际 宝马彩票官网 新2娱乐 易彩网 u宝娱乐登录 永利线上注册 天狮娱乐 幸运十分彩 必发彩票注册 跑狗图最新 永利真人 pk10基础 趣彩彩票注册 赚钱正规网址 亚泰分分彩 www.1590.com——Home 淘彩票-跑狗网6654com 易彩网 www.6288.com——Home 广发彩票登录 永利bte365_注册就送 鑫彩网彩票网址 真人游戏 奔驰宝马彩票 pk10冷热分析 银河娱乐-老板跑狗图自动更新092期 信誉平台投注 大发pk10平台 pk10操盘手 足彩310 千禧彩票注册 澳门新永利娱乐 幸运彩票——Home 凤凰娱乐注册 pk拾公式 捕鱼兑换现金 幸运十分彩 大智慧彩票——Home 跑狗图最新 嘉禾彩票网址 宝马彩票官网 淘宝彩票 老板跑狗图自动更新092期 盛彩娱乐注册 大发888.com -Home 真人棋牌游戏 金凤凰彩票网站 多彩彩票下注 pk10三码必中规律 买彩网注册 一定牛彩票网 爱投彩票投注 永利博国际网 彩票大赢家 亚泰分分彩 彩票99官网 宝马彩票官网 欢乐彩票注册 真人手机棋牌游戏 淘宝彩票注册 永利ag 彩票宝 pk10基础 永利电子游戏 球探彩票 永利会官网 2841财神1码数据分析 pk10刷水 18彩票网站 彩客登录 www.2359.com——Home 大满贯国际 优游分分彩 真人棋牌游戏 AG电子游戏 永利澳门娱乐场 彩票宝 GT彩票注册 大公鸡七星彩 bte365官网 微信支付彩票 159彩票网——Home 9188彩票网登录 永利登录 信彩娱乐 巴黎人贵宾会网址 信誉平台投注 拉菲彩票下注 特码生肖图 真人棋牌游戏 天狮娱乐彩票登录 悦彩票登录 捷豹60秒分分彩计划 微信支付彩票 百姓彩票网 特码生肖图 新世佳彩票网站 pk10操盘手 足彩310 PK彩票PK彩票永利真人 pk10时时计划 在线电子游戏平台 www.6038.com——Home 新世佳彩票网站 www.6311.com——Home www.4114.com——Home www.5320.com——Home 凤凰娱乐彩票登陆 永利皇宫手机版 鸿运来彩票网登录 必发彩票注册 淘宝彩票-永利真人 凤凰娱乐注册 PK彩票PK彩票永利真人 大奖网娱乐登录 网上现金斗牛 特码生肖图 希尔顿娱乐网址 永利登录 永利贵宾会 百家乐登录 www.4161.com——Home 速博国际娱乐 乐发国际 澳门永利高 -Home www.1504.com——Home www.1432.com——Home 传奇彩票永利真人 彩票专业投注平台 一定牛彩票网 永利线上注册 我赢彩票下注 爱投彩票投注 E时彩彩票注册 博必发 奔驰宝马娱乐 KK娱乐 北京赛车账号注册 永利会官网 彩客网彩票永利真人 玩彩网 尊亿娱乐 K7彩票登录 诚信彩票登陆 腾讯分分彩 买马图2019 皇家网址 北京单场官网 智胜彩票 鼎盛彩票注册 永利娱乐手游下载 pk10时时计划 凤凰新平台 伯爵娱乐 微信购彩 永利国际平台 彩乐汇彩票 永利下注网址 亚泰分分彩 豪门会彩票投注 亚泰分分彩 嘉禾彩票网址 永利.com 永利赌博 鑫彩网登录 苹果彩票注册 永利国际赌博 永利娱乐注册 金福彩票永利真人 新利彩票注册 u宝娱乐登录 永利银河官网 淘宝彩票 淘宝彩票