《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 其他 > Linux驅(qū)動開發(fā)-編寫DS18B20驅(qū)動

Linux驅(qū)動開發(fā)-編寫DS18B20驅(qū)動

2022-09-29
來源:電子發(fā)燒友網(wǎng)

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

  1. 前言

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

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

  2. DS18B20介紹

  DS18B20特性:

  (1)全數(shù)字溫度轉(zhuǎn)換及輸出。

  (2)先進的單總線數(shù)據(jù)通信。

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

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

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

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

  (7)內(nèi)置 EEPROM,限溫報警功能。

 ?。?)64 位光刻 ROM,內(nèi)置產(chǎn)品序列號,方便多機掛接。

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

  

13.JPG

  DS18B20引腳功能

  GND 電壓地

  DQ 單數(shù)據(jù)總線

  VDD 電源電壓

  NC 空引腳

  DS18B20讀取溫度的步驟:

  發(fā)送復位信號-->

  檢測回應信號--->

  發(fā)送0xCC-->發(fā)送0x44->

  發(fā)送復位信號->

  檢測回應信號->

  寫0xcc--->

  寫0xbe--->

  循環(huán)8次讀取溫度低字節(jié)--->

  循環(huán)8次讀取溫度高字節(jié)---->

  打印溫度信息

  DS18B20溫度轉(zhuǎn)換示例:

  u16 temp;

  u8 TL,TH;

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

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

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

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

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

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

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

  3. 硬件接線圖

  Tiny4412開發(fā)板擴展GPIO口:

14.JPG

捕獲.JPG

  4. 示例代碼

  復制

  #include

  #include

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

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

  #include         /*延時函數(shù)*/

  #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);}

  /*

  函數(shù)功能:等待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讀取一個字節(jié)

  返回值:讀到的數(shù)據(jù)

  */

  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)        //主機對總線采樣的數(shù) 判斷-------讀數(shù)據(jù)-1就是1,否則就是0

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

  }

  return dat;

  }

  /*

  寫一個字節(jié)到DS18B20

  dat:要寫入的字節(jié)

  */

  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

  };

  /*

  核心結(jié)構(gòu)體

  */

  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

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。