日韩欧美自拍在线观看-欧美精品在线看片一区二区-高清性视频一区二区播放-欧美日韩女优制服另类-国产精品久久久久久av蜜臀-成人在线黄色av网站-肥臀熟妇一区二区三区-亚洲视频在线播放老色-在线成人激情自拍视频

基于ARM-LINUX的溫度傳感器驅(qū)動(DS18B20)

出處:eefocus 發(fā)布于:2018-08-28 14:24:47


  DS18B20數(shù)字溫度傳感器接線方便,封裝成后可應(yīng)用于多種場合,如管道式,螺紋式,磁鐵吸附式,不銹鋼封裝式,型號多種多樣,有LTM8877,LTM8874等等。主要根據(jù)應(yīng)用場合的不同而改變其外觀。封裝后的DS18B20可用于電纜溝測溫,高爐水循環(huán)測溫,鍋爐測溫,機房測溫,農(nóng)業(yè)大棚測溫,潔凈室測溫,彈藥庫測溫等各種非極限溫度場合。耐磨耐碰,體積小,使用方便,封裝形式多樣,適用于各種狹小空間設(shè)備數(shù)字測溫和控制領(lǐng)域。

  技術(shù)性能描述

  1. 獨特的單線接口方式,DS18B20在與微處理器連接時僅需要一條口線即可實現(xiàn)微處理器與DS18B20的雙向通訊。

  2. 測溫范圍 -55℃~+125℃,固有測溫分辨率0.5℃。

  3. 支持多點組網(wǎng)功能,多個DS18B20可以并聯(lián)在的三線上。

  4. 工作電源: 3~5V/DC

  5. 在使用中不需要任何外圍元件

  6. 測量結(jié)果以9~12位數(shù)字量方式串行傳送

DS18b20封裝

DS18B20 引腳功能: GND 電壓地 ?DQ 單數(shù)據(jù)總線 ?VDD 電源電壓 ?NC 空引腳

  DS18b20與處理器的連接

  DS18B20 工作原理及應(yīng)用

  DS18B20 的溫度檢測與數(shù)字數(shù)據(jù)輸出全集成于一個芯片之上,從而抗干擾力更強。其一個工作周期可分為兩個部分,即溫度檢測和數(shù)據(jù)處理。在講解其工作流程之前我們有必要了解 18B20的內(nèi)部存儲器資源。18B20 共有三種形態(tài)的存儲器資源。它們分別是:

  ROM 只讀存儲器:

  用于存放 DS18B20ID 編碼,其前 8 位是單線系列編碼(DS18B20 的編碼是19H) ,后面48 位是芯片的序列號, 8位是以上 56的位的 CRC碼(冗余校驗)。數(shù)據(jù)在出產(chǎn)時設(shè)置不由用戶更改。DS18B20 共 64 位 ROM。

  RAM 數(shù)據(jù)暫存器:

  用于內(nèi)部計算和數(shù)據(jù)存取,數(shù)據(jù)在掉電后丟失,DS18B20 共9 個字節(jié) RAM,每個字節(jié)為 8 位。第1、2 個字節(jié)是溫度轉(zhuǎn)換后的數(shù)據(jù)值信息,第 3、4 個字節(jié)是用戶 EEPROM(常用于溫度報警值儲存)的鏡像。在上電復(fù)位時其值將被刷新。第 5 個字節(jié)則是用戶第 3 個 EEPROM的鏡像。第 6、7、8 個字節(jié)為計數(shù)寄存器,是為了讓用戶得到更高的溫度分辨率而設(shè)計的,同樣也是內(nèi)部溫度轉(zhuǎn)換、計算的暫存單元。第 9 個字節(jié)為前 8個字節(jié)的 CRC碼。EEPROM 非易失性記憶體,用于存放長期需要保存的數(shù)據(jù),上下限溫度報警值和校驗數(shù)據(jù), DS18B20共3位EEPROM,并在 RAM 都存在鏡像,以方便用戶操作。

  控制器對 18B20 操作流程:

  1、 復(fù)位:首先我們必須對 DS18B20 芯片進行復(fù)位,復(fù)位就是由控制器(單片機)給 DS18B20單總線至少 480uS 的低電平信號。當 18B20 接到此復(fù)位信號后則會在 15~60uS 后回發(fā)一個芯片的存在脈沖。

  2、 存在脈沖:在復(fù)位電平結(jié)束之后,控制器應(yīng)該將數(shù)據(jù)單總線拉高,以便于在 15~60uS 后接收存在脈沖,存在脈沖為一個 60~240uS 的低電平信號。至此,通信雙方已經(jīng)達成了基本的協(xié)議,接下來將會是控制器與 18B20 間的數(shù)據(jù)通信。如果復(fù)位低電平的時間不足或是單總線的電路斷路都不會接到存在脈沖,在設(shè)計時要注意意外情況的處理。

  3、 控制器發(fā)送 ROM 指令:雙方打完了招呼之后要將進行交流了,ROM 指令共有 5條,每一個工作周期只能發(fā)一條,ROM指令分別是讀 ROM 數(shù)據(jù)、指定匹配芯片、跳躍 ROM、芯片搜索、報警芯片搜索。ROM 指令為 8 位長度,功能是對片內(nèi)的 64位光刻 ROM進行操作。其主要目的是為了分辨一條總線上掛接的多個器件并作處理。誠然,單總線上可以同時掛接多個器件,并通過每個器件上所獨有的 ID號來區(qū)別,一般只掛接單個 18B20芯片時可以跳過 ROM 指令(注意:此處指的跳過 ROM指令并非不發(fā)送 ROM 指令,而是用特有的一條“跳過指令” )

  4、 控制器發(fā)送存儲器操作指令:在 ROM 指令發(fā)送給 18B20 之后,緊接著(不間斷)就是發(fā)送存儲器操作指令了。操作指令同樣為 8 位,共 6 條,存儲器操作指令分別是寫 RAM 數(shù)據(jù)、讀RAM 數(shù)據(jù)、將 RAM 數(shù)據(jù)復(fù)制到 EEPROM、溫度轉(zhuǎn)換、將 EEPROM中的報警值復(fù)制到 RAM、工作方式切換。存儲器操作指令的功能是命令 18B20 作什么樣的工作,是芯片控制的關(guān)鍵。

  5、 執(zhí)行或數(shù)據(jù)讀寫:一個存儲器操作指令結(jié)束后則將進行指令執(zhí)行或數(shù)據(jù)的讀寫,這個操作要視存儲器操作指令而定。如執(zhí)行溫度轉(zhuǎn)換指令則控制器(單片機)必須等待 18B20 執(zhí)行其指令,一般轉(zhuǎn)換時間為 500uS。如執(zhí)行數(shù)據(jù)讀寫指令則需要嚴格遵循 18B20 的讀寫時序來操作。

  若要讀出當前的溫度數(shù)據(jù)我們需要執(zhí)行兩次工作周期,個周期為復(fù)位、跳過 ROM 指令、執(zhí)行溫度轉(zhuǎn)換存儲器操作指令、等待 500uS 溫度轉(zhuǎn)換時間。緊接著執(zhí)行第二個周期為復(fù)位、跳過 ROM指令、執(zhí)行讀 RAM 的存儲器操作指令、讀數(shù)據(jù)(多為 9 個字節(jié),中途可停止,只讀簡單溫度值則讀前 2 個字節(jié)即可)。其它的操作流程也大同小異,在此不多介紹。關(guān)于ds18b20的數(shù)據(jù)手冊網(wǎng)上資源較為豐富,這里不再詳細介紹,下面是基于ARM-LINUX的驅(qū)動程序,在arm-gcc 編譯后測試通過。

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  MODULE_LICENSE("GPL");

  #define GPHCON (*(volatile unsigned int *)S3C2410_GPHCON)

  #define GPHDAT (*(volatile unsigned int *)S3C2410_GPHDAT)

  #define GPHUP (*(volatile unsigned int *)S3C2410_GPHUP)

  static int ds18b20_major = 230;        /*靜態(tài)申請設(shè)備號*/

  struct cdev cdev;

  struct class *my_class;

  spinlock_t lock;

  dev_t dev = 0;

  int number_of_devices = 1;

  /*配置為輸入模式*/

  void set_conIN(void)

  {

  GPHCON &= ~(1<<19);

  GPHCON &= ~(1<<18);

  }

  /*配置為輸出模式*/

  void set_conOUT(void)

  {

  GPHCON |= (1<<18);

  GPHCON &= ~(1<<19);

  }

  /*引腳置位*/

  void set_data(int i)

  {

  if( i == 0 ){

  GPHDAT &= ~(1<<9);

  }else if( i == 1 ){

  GPHDAT |= (1<<9);

  }

  }

  /*復(fù)位ds18b20*/

  unsigned int reset_ds18b20(void)

  {

  unsigned int retValue;

  set_conOUT();

  set_data(1);

  __udelay(1);

  set_data(0);

  __udelay(600);

  set_data(1);

  __udelay(20);

  set_conIN();

  __udelay(100);

  /*稍做延時后 如果x=0則初始化成功

  x=1則初始化失*/

  retValue = (GPHDAT >> 9) & 0x01;

  printk("init is %d\n",retValue);

  return retValue;

  }

  /*讀取一位溫度*/

  unsigned int read_bit(void)

  {

  spin_lock(&lock);

  set_conOUT();

  //set_data(1);

  //__udelay(2);

  set_data(0);

  __udelay(2);

  set_conIN();

  __udelay(1);

  spin_unlock(&lock);

  return ((GPHDAT >> 9) & 0x01);

  }

  /*寫一位命令*/

  void write_bit(char bitValue)

  {

  spin_lock(&lock);

  set_conOUT();

  set_data(0);

  __udelay(15);

  if( bitValue == 1 ){

  set_data(1);

  }else{

  set_data(0);

  }

  spin_unlock(&lock);

  __udelay(45);

  set_conIN();

  __udelay(2);

  }

  /*寫命令*/

  void write_cmd(char cmd)

  {

  unsigned char i;

  unsigned char temp;

  for(i=0; i<8;i++){

  temp = cmd>>i;

  temp &= 0x01;

  write_bit(temp);

  }

  //__udelay(10);

  }

  /*打開設(shè)備*/

  static int ds18b20_open(struct inode *inode,struct file *filp)

  {

  printk (KERN_INFO "HEY! device opened\n");

  //GPHUP &= ~(1<<9);

  GPHUP |= (1<<9);

  spin_lock_init(&lock);

  return 0;

  }

  /*讀取數(shù)據(jù)*/

  static int ds18b20_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)

  {

  char lowValue=0,highValue=0;

  unsigned int i;

  //float value;

  if(reset_ds18b20()){

  printk("init error\n");

  }

  __udelay(400);

  set_conOUT();

  set_data(1);

  write_cmd(0xCC);

  write_cmd(0x44);

  __udelay(100000);

  if(reset_ds18b20()){

  printk("init error\n");

  }

  __udelay(400);

  set_conOUT();

  set_data(1);

  write_cmd(0xcc);

  write_cmd(0xBE);

  /*讀取溫度轉(zhuǎn)化數(shù)值*/

  for(i=0; i<8; i++){

  if( read_bit() ){

  lowValue |= (0x01<<i);

  }

  __udelay(62);

  }

  printk("lowValue is %d\n",lowValue);

  for(i=0; i<8; i++){

  if( read_bit() ){

  highValue |= (0x01<<i);

  }

  __udelay(62);

  }

  printk("highValue is %d\n",highValue);

  #if 0

  i = highValue;

  i <<= 8;

  i = i|lowValue;

  value = i*0.0625;

  printk("kernel is %d\n",value);

  #endif

  highValue <<= 4;

  highValue |= ((lowValue&0xf0)>>4) ;

  /*拷貝內(nèi)核數(shù)據(jù)到用戶空間*/

  copy_to_user(buffer, &highValue, sizeof(highValue));

  return 0;

  }

  /*寫命令,在此置空*/

  static int ds18b20_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)

  {

  return 0;

  }

  static int ds18b20_release(struct inode *inode,struct file *filp)

  {

  printk (KERN_INFO "device closed\n");

  return 0;

  }

  static int ds18b20_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

  {

  return 0;

  }

  struct file_operations ds18b20_fops ={

  .owner = THIS_MODULE,

  .open = ds18b20_open,

  .read = ds18b20_read,

  .write = ds18b20_write,

  .ioctl = ds18b20_ioctl,

  .release = ds18b20_release,

  };

  static void ds18b20_setup_cdev(void)

  {

  int error,devno = MKDEV(ds18b20_major,0);

  cdev_init(&cdev,&ds18b20_fops);

  cdev.owner = THIS_MODULE;

  cdev.ops = &ds18b20_fops;

  error = cdev_add(&cdev,devno,1);

  if( error )

  printk(KERN_INFO"Error %d adding ds18b20 %d\n",error,0);

  my_class = class_create(THIS_MODULE,"my_class");

  if(IS_ERR(my_class))

  {

  printk("Err: failed in creating class.\n");

  return;

  }

  device_create(my_class,NULL,devno,NULL,"ds18b20");

  }

  /*注冊設(shè)備*/

  static int ds18b20_init(void)

  {

  int result;

  dev = MKDEV(ds18b20_major,0);

  if(ds18b20_major)

  result = register_chrdev_region(dev,1,"ds18b20");

  else{

  result = alloc_chrdev_region(&dev,0,1,"ds18b20");

  ds18b20_major=MAJOR(dev);

  }

  if( result < 0 ){

  printk(KERN_WARNING"ds18b20:unable to get major %d\n",ds18b20_major);

  return result;

  }

  if(ds18b20_major == 0 )

  ds18b20_major = result;

  ds18b20_setup_cdev();

  printk("ds18b20 initialized.\n");

  return 0;

  }

  static void __exit ds18b20_exit(void)

  {

  dev_t devno = MKDEV (ds18b20_major, 0);

  device_destroy(my_class,devno);

  class_destroy(my_class);

  cdev_del (&cdev);

  unregister_chrdev_region (devno, number_of_devices);

  printk("ds18b20_major=%d\n",ds18b20_major);

  printk("ds18b20 device uninstalled\n");

  }

  module_init(ds18b20_init);

  module_exit(ds18b20_exit);

關(guān)鍵詞:ARM,LINUX,DS18B20,

版權(quán)與免責聲明

凡本網(wǎng)注明“出處:維庫電子市場網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場網(wǎng),轉(zhuǎn)載請必須注明維庫電子市場網(wǎng),http://www.hbjingang.com,違反者本網(wǎng)將追究相關(guān)法律責任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性,不承擔此類作品侵權(quán)行為的直接責任及連帶責任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品出處,并自負版權(quán)等法律責任。

如涉及作品內(nèi)容、版權(quán)等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。

廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機號碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務(wù):
賣家服務(wù):
技術(shù)客服:

0571-85317607

網(wǎng)站技術(shù)支持

13606545031

客服在線時間周一至周五
9:00-17:30

關(guān)注官方微信號,
第一時間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務(wù)的動力!意見一經(jīng)采納,將有感恩紅包奉上哦!