• <xmp id="y4ogs"><nav id="y4ogs"></nav>
    <nav id="y4ogs"></nav>
    <nav id="y4ogs"><code id="y4ogs"></code></nav><dd id="y4ogs"></dd>
  • <xmp id="y4ogs"><nav id="y4ogs"></nav>
    《電子技術應用》
    您所在的位置:首頁 > 嵌入式技術 > 其他 > Linux驅動開發-編寫DS18B20驅動

    Linux驅動開發-編寫DS18B20驅動

    2022-09-29
    來源:電子發燒友網

      【摘要】 當前文章介紹如何在Linux系統下編寫一個DS18B20溫度傳感器驅動,測量環境溫度,并將DS18B20注冊成字符設備,通過文件接口將溫度數據傳遞給應用層。

      1. 前言

      當前文章介紹如何在Linux系統下編寫一個DS18B20溫度傳感器驅動,測量環境溫度,并將DS18B20注冊成字符設備,通過文件接口將溫度數據傳遞給應用層。

      當前使用的開發板是友善之臂的Tiny4412開發板,CPU是三星的Exynos-4412,主頻是4核1.5GHZ,當前運行的Linux內核版本是3.5。使用的溫度傳感器是DS18B20,是一個數字溫度傳感器,非常經典的一款溫度傳感器,常年應用在各大高校畢設、實驗室、畢設、課設場景。DS1820接線比較簡單,只需要一根線就行,加上兩根電源線,一共3根線,并且DS18B20支持硬件序列號尋址,支持一個IO口上掛載多個DS18B20。

      2. DS18B20介紹

      DS18B20特性:

     ?。?)全數字溫度轉換及輸出。

     ?。?)先進的單總線數據通信。

     ?。?)最高 12 位分辨率,精度可達土 0.5 攝氏度。

     ?。?)12 位分辨率時的最大工作周期為 750 毫秒。

     ?。?)可選擇寄生工作方式。

     ?。?)檢測溫度范圍為-55° C ~+125° C (-67° F ~+257° F)

     ?。?)內置 EEPROM,限溫報警功能。

     ?。?)64 位光刻 ROM,內置產品序列號,方便多機掛接。

     ?。?)多樣封裝形式,適應不同硬件系統。

      

    13.JPG

      DS18B20引腳功能

      GND 電壓地

      DQ 單數據總線

      VDD 電源電壓

      NC 空引腳

      DS18B20讀取溫度的步驟:

      發送復位信號-->

      檢測回應信號--->

      發送0xCC-->發送0x44->

      發送復位信號->

      檢測回應信號->

      寫0xcc--->

      寫0xbe--->

      循環8次讀取溫度低字節--->

      循環8次讀取溫度高字節---->

      打印溫度信息

      DS18B20溫度轉換示例:

      u16 temp;

      u8 TL,TH;

      u16 intT,decT;               //溫度值的整數和小數部分

      TL=DS18B20_Read_Byte();       //讀取溫度低8位LSB

      TH=DS18B20_Read_Byte();       //讀取溫度高8位MSB

      temp=((u16)TH《8)|TL;          //將讀出的溫度高低位組合成16位的值

      intT = temp 》 4;                //分離出溫度值整數部分

      decT = temp & 0xF;              //分離出溫度值小數部分

      printf(“A: %d.%d\r\n”,(int)intT,(int)decT); //打印實際溫度值

      3. 硬件接線圖

      Tiny4412開發板擴展GPIO口:

    14.JPG

    捕獲.JPG

      4. 示例代碼

      復制

      #include

      #include

      #include    /*雜項字符設備頭文件*/

      #include            /*文件操作集合*/

      #include         /*延時函數*/

      #include

      #include

      /*DS18B20 GPIO接口: GPB_4*/

      /*定義指針,用于接收虛擬地址*/

      volatile unsigned int *DS18B20_GPBCON;

      volatile unsigned int *DS18B20_GPBDAT;

      #define DS18B20_INPUT()  {*DS18B20_GPBCON &= ~(0xf  《 4 * 4);}

      #define DS18B20_OUTPUT() {*DS18B20_GPBCON &= ~(0xf  《 4 * 4);*DS18B20_GPBCON |=  (0x1   《 4 * 4);}

      /*

      函數功能:等待DS18B20的回應

      返回1:未檢測到DS18B20的存在

      返回0:存在

      */

      unsigned char DS18B20_Check(void)

      {

      unsigned char retry=0;

      DS18B20_INPUT() ///SET PG11 INPUT

      while((*DS18B20_GPBDAT & (1 《 4))&&retry<200)

      {

      retry++;

      udelay(1);

      };

      if(retry>=200)return 1;

      else retry=0;

      while(?。?DS18B20_GPBDAT & (1 《 4))&&retry<240)

      {

      retry++;

      udelay(1);

      };

      if(retry>=240)return 1;

      return 0;

      }

      /*

      從DS18B20讀取一個位

      返回值:1/0

      */

      unsigned char DS18B20_Read_Bit(void)  // read one bit

      {

      unsigned char data;

      DS18B20_OUTPUT();

      *DS18B20_GPBDAT &= ~(1 《 4);//輸出0

      udelay(2);

      *DS18B20_GPBDAT |= (1 《 4);//輸出1

      DS18B20_INPUT()

      udelay(12);

      if((*DS18B20_GPBDAT & (1 《 4)))data=1;

      else data=0;

      udelay(50);

      return data;

      }

      /*

      從DS18B20讀取一個字節

      返回值:讀到的數據

      */

      unsigned char DS18B20_Read_Byte(void)    // read one byte

      {

      unsigned char i,j,dat;

      dat=0;

      for(i=1;i<=8;i++)

      {

      j=DS18B20_Read_Bit();

      dat=dat》1;

      if(j)        //主機對總線采樣的數 判斷-------讀數據-1就是1,否則就是0

      dat|=0x80;   //先收低位數據--一步一步向低位移動》

      }

      return dat;

      }

      /*

      寫一個字節到DS18B20

      dat:要寫入的字節

      */

      void DS18B20_Write_Byte(unsigned char dat)

      {

      unsigned char j;

      unsigned char testb;

      DS18B20_OUTPUT();

      for(j=1;j<=8;j++)

      {

      testb=dat&0x01;

      dat=dat》1;

      if(testb)

      {

      *DS18B20_GPBDAT &= ~(1 《 4);//輸出0// Write 1

      udelay(2);

      *DS18B20_GPBDAT |= (1 《 4);//輸出1

      udelay(60);

      }

      else

      {

      *DS18B20_GPBDAT &= ~(1 《 4);//輸出0// Write 0

      udelay(60);

      *DS18B20_GPBDAT |= (1 《 4);//輸出1

      udelay(2);

      }

      }

      }

      /*

      從ds18b20得到溫度值

      精度:0.1C

      返回值:溫度值 (-550~1250)

      */

      short DS18B20_Get_Temp(void)

      {

      unsigned short aaa;

      unsigned char temp;

      unsigned char TL,TH;

      DS18B20_OUTPUT();

      *DS18B20_GPBDAT &= ~(1 《 4);//輸出0 //拉低DQ

      udelay(750);    //拉低750us

      *DS18B20_GPBDAT |= (1 《 4);//輸出1 //DQ=1

      udelay(15);     //15US

      DS18B20_Check();

      DS18B20_Write_Byte(0xcc);

      DS18B20_Write_Byte(0x44);

      DS18B20_OUTPUT();

      *DS18B20_GPBDAT &= ~(1 《 4);//輸出0 //拉低DQ

      udelay(750);    //拉低750us

      *DS18B20_GPBDAT |= (1 《 4);//輸出1 //DQ=1

      udelay(15);     //15US

      DS18B20_Check();

      DS18B20_Write_Byte(0xcc);// skip rom

      DS18B20_Write_Byte(0xbe);// convert

      TL=DS18B20_Read_Byte();  // LSB

      TH=DS18B20_Read_Byte();  // MSB

      aaa=((unsigned short)TH《8)|TL;

      return aaa;

      }

      /*

      雜項字符設備注冊示例----->DS18B20

      */

      static int tiny4412_open(struct inode *my_inode, struct file *my_file)

      {

      /*映射物理地址*/

      DS18B20_GPBCON=ioremap(0x11400040,4);

      DS18B20_GPBDAT=ioremap(0x11400044,4);

      printk(“DS18B20初始化成功!\r\n”);

      /*設置ds18b20為輸出模式*/

      *DS18B20_GPBCON &= ~(0xf  《 4 * 4);

      *DS18B20_GPBCON |=  (0x1  《 4 * 4);

      return 0;

      }

      static int tiny4412_release(struct inode *my_inode, struct file *my_file)

      {

      /*釋放虛擬地址*/

      iounmap(DS18B20_GPBCON);

      iounmap(DS18B20_GPBDAT);

      printk(“DS18B20釋放成功\r\n”);

      return 0;

      }

      static ssize_t tiny4412_read(struct file *my_file, char __user *buf, size_t len, loff_t *loff)

      {

      /*讀取溫度信息*/

      short temp=DS18B20_Get_Temp();

      copy_to_user(buf,&temp,2);    //拷貝溫度至應用層

      return 0;

      }

      static ssize_t tiny4412_write(struct file *my_file, const char __user *buf, size_t len, loff_t *loff)

      {

      return 0;

      }

      /*文件操作集合*/

      static struct file_operations tiny4412_fops=

      {

      .open=tiny4412_open,

      .read=tiny4412_read,

      .write=tiny4412_write,

      .release=tiny4412_release

      };

      /*

      核心結構體

      */

      static struct miscdevice tiny4412_misc=

      {

      .minor=MISC_DYNAMIC_MINOR,  /*自動分配次設備號*/

      .name=“DS18B20”,      /*設備文件,指定/dev/生成的文件名稱*/

      .fops=&tiny4412_fops

      };

      static int __init DS18B20_dev_init(void)

      {

      /*雜項設備注冊*/

      misc_register(&tiny4412_misc);

      return 0;

      }

      static void __exit DS18B20_dev_exit(void)

      {

      /*雜項設備注銷*/

      misc_deregister(&tiny4412_misc);

      }

      module_init(DS18B20_dev_init);

      module_exit(DS18B20_dev_exit);

      MODULE_LICENSE(“GPL”);




    更多信息可以來這里獲取==>>電子技術應用-AET<<

    mmexport1621241704608.jpg

    本站內容除特別聲明的原創文章之外,轉載內容只為傳遞更多信息,并不代表本網站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創文章及圖片等內容無法一一聯系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經濟損失。聯系電話:010-82306116;郵箱:aet@chinaaet.com。
    日本一级婬片免费看
  • <xmp id="y4ogs"><nav id="y4ogs"></nav>
    <nav id="y4ogs"></nav>
    <nav id="y4ogs"><code id="y4ogs"></code></nav><dd id="y4ogs"></dd>
  • <xmp id="y4ogs"><nav id="y4ogs"></nav>