<wbr id="70qiw"></wbr>
    <i id="70qiw"></i>
    <wbr id="70qiw"></wbr>
    <source id="70qiw"></source>
    1. <wbr id="70qiw"></wbr>
    2. 你的位置:首頁 > 技術支持 > 技術文章

      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是我建立的各人可能不同,自己更改

      重啟板子就會看到和開始介紹的一樣的界面效果了。

      日本红怡院亚洲美女色情图片18p,国内绝对真实偷窥短视频,手机免费AV在线观看网址,各类熟女熟妇真实视频,国产成人无码AV在线观看,国产又色又爽又黄又刺激视频 午夜无码片在线观看影视,在线观看免费无码专区,成年肉动漫在线观看无码,99久久无色码中文字幕,久久SE精品一区二区,午夜无码片在线观看影视 中文字幕第一页,日韩AV午夜在线观看,人妻无码av一区二区三区,亚洲动漫AV第一页,aⅴ亚洲综合网,福利二区福利三微拍,最近中文字幕完整视频,国产成人拍拍拍高潮尖叫 亚洲人成网站在线播放青青,亚洲性夜夜夜色综合网,亚洲欧美国产,亚洲欧美中文日韩视频,欧美日韩一中文字不卡,日本视频高清免费观看,亚洲综合色在线视频 亚洲av欧美卡通动漫.亚洲欧美中文日韩v在线,亚洲系列 中文字幕制服,国产日韩av无码亚洲在线,欧美卡通另类偷 自拍网站,香港日本三级在线播放,亚洲人成电影网站免费 手机在线观看日本A级视频在线播放,在线播放日本A级视频在线播放,免费观看日本A级黄毛片免费天堂,日本免费高清一本视频在线视频观看,无敌影院视频在线播放日本a级片 在线a亚洲视频播放在线观看,美女免费高清视频黄是免费,免费观看性欧美大片毛片,高清无码中文字幕,日韩欧美亚洲每日更新在线,老熟妇乱子伦牲交视频
      国产日韩av无码亚洲在线,欧美卡通另类偷 自拍网站,香港日本三级在线播放,日本毛片高清免费视频-夜夜干,FREE欧美性婬妇,欧洲美女牲交视频在线视频,洲女人牲交视频免费, 在线观看免费网站看v片,免费电影在线观看,免费网站看v片在线a,免费影视网站,免费看视频的网站,免费高清在线大片,免费网站看全部v片.欧美日韩在线无码YY8399 老司机午夜神器_两性色午夜视频_午夜男人免费福利视频,男人吃奶视频.男人女人强吻下面视频.无码av手机免费不卡在线观看.在线日本v二区不卡,一本到高清视频不卡dvd 欧美BBWHD大屁股丰满大屁股,欧美激情第1页,2020年最新最全欧美成年性色生活片,免費欧美成年性色生活片 毛片做爰片在線觀看,久久婷香五月综合色啪 欧美成人,欧美成 人版在线观看_第1页,日本特黄aa级毛片,亚洲人成视频在线,中文字幕 欧美精品 第1页,亚洲成人av,青青草色青在现线观1,欧美肥老太交性视频视频在线观看 国产美女精品自在线拍免费,国产精品午夜片在线观看,av人妻区高清完整版在线,成人乱伦在线视频,男女电梯吻胸抓胸激烈,精品国产AV一二三四区这,国产女主播精品一区二区 亚洲精品人成网线在线播放VA,欧洲美女,办公室紧身裙丝袜AV在线,我和岳坶双飞A片,久久精品国产99国产精品,国产精品高清青草aⅴ在线日本a级视频在线播放 中文字幕熟女人妻一区二区,亚洲中文无码AV永久,久久综合网丁香五月,国产在线精品亚洲第一区香蕉,欧美精品VIDEOSSEX,美女高潮喷水30分钟全程露脸在线视频免费观看 在线a亚洲视频播放在线观看,美女免费高清视频黄是免费,免费观看性欧美大片毛片,高清无码中文字幕,日韩欧美亚洲每日更新在线,老熟妇乱子伦牲交视频 免费看成年人视频大全,亚洲成A片,在线看h片,色屋屋网站,色av2019中文 极品大片,一本道国产自拍,在线av中文字幕,久久超碰视频,国产亚洲中文日韩欧美综合网