微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > 嵌入式系统设计讨论 > 之ds18b20驱动

之ds18b20驱动

时间:10-02 整理:3721RD 点击:
前几天系统已经一直完成,这俩天做了一下温度传感器的实验,在这里与大家分享。
版本说明:
               平台:OK210;
                os :Linux2.6.35.7
                驱动类型:ds18b20


驱动程序如下

  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/init.h>
  5. #include <linux/delay.h>
  6. #include <linux/device.h>
  7. #include <linux/platform_device.h>
  8. #include <asm/uaccess.h>
  9. #include <asm/irq.h>
  10. #include <asm/io.h>
  11. #include <linux/miscdevice.h>


  12. #define DS18B20_RESET   (0x10009)
  13. #define DS18B20_REL     (0x10011)

  14. #define SKIP_ROM        0xcc
  15. #define COVERTT         0x44
  16. #define READ_MEM        0xbe
  17. #define WRITE_MEM       0x4e

  18. #define NINE_BIT           0x1f
  19. #define TEN_BIT          0x3f
  20. #define ELE_BIT          0x5f
  21. #define TWL_BIT          0x7f

  22. #define TH              100
  23. #define TL              0

  24. #define TEMP_H          10000
  25. #define TEMP_L          -10000

  26. static unsigned long *gpio_con;
  27. static unsigned long *gpio_dat;

  28. static void gpio_cfg_out(unsigned char val)
  29. {
  30.         *gpio_con &= ~0xf;
  31.         *gpio_con |= 0x1;
  32.         if (val == 0)
  33.                 *gpio_dat &= ~0x1;
  34.         else
  35.                 *gpio_dat |= 0x1;
  36. }

  37. static unsigned char gpio_cfg_in(void)
  38. {
  39.         *gpio_con &= ~0xf;
  40.         return *gpio_dat&0x1;
  41. }

  42. /* 鍙傜湅鏂囨。P16,娉ㄦ剰鍐?鍜?鐨勬椂闅欒姹?/
  43. static void ds18b20_write8(unsigned char data)
  44. {
  45.         int i;

  46.        for (i = 0; i < 8; i++) {
  47.                 if ((data & 0x1) == 1) {
  48.                         gpio_cfg_out(0);
  49.                         udelay(3);
  50.                         gpio_cfg_out(1);
  51.                         udelay(80);
  52.                 } else {
  53.                         gpio_cfg_out(0);
  54.                         udelay(80);
  55.                         gpio_cfg_out(1);
  56.                         udelay(3);
  57.                 }
  58.                 data >>= 1;
  59.        }
  60. }

  61. /* 鍙傜湅鏂囨。P16,娉ㄦ剰璇?鍜?鐨勬椂闅欒姹?/
  62. static unsigned char ds18b20_read8(void)
  63. {
  64.         int i;
  65.         unsigned char bit;
  66.         unsigned char data = 0;

  67.         for (i = 0; i < 8; i++) {
  68.                 gpio_cfg_out(0);
  69.                 udelay(2);
  70.                 gpio_cfg_out(1);
  71.                 udelay(5);
  72.                 bit = gpio_cfg_in();
  73.                 data |= (bit << i);
  74.                 udelay(5);
  75.                 gpio_cfg_out(1);
  76.                 udelay(60);
  77.         }
  78.         return data;
  79. }

  80. /* 鍙傜湅鏂囨。P15*/
  81. static void ds18b20_reset(void)
  82. {
  83.         unsigned char ret;

  84.         gpio_cfg_out(0);
  85.         udelay(500);
  86.         gpio_cfg_out(1);
  87.         udelay(30);
  88.         ret = gpio_cfg_in();
  89.         udelay(500);
  90. #if 0
  91.         if (ret == 0) {
  92.                 printk("reset ok.\n");
  93.         } else {
  94.                 printk("reset failed.\n");
  95.         }
  96. #endif
  97. }

  98. static void ds18b20_config_rel(unsigned char rel)
  99. {
  100.         ds18b20_reset();
  101.         ds18b20_write8(SKIP_ROM);
  102.         ds18b20_write8(WRITE_MEM);
  103.         ds18b20_write8(TH);
  104.         ds18b20_write8(TL);
  105.         switch(rel) {
  106.                 case 9:
  107.                         ds18b20_write8(NINE_BIT);
  108.                         break;
  109.                 case 10:
  110.                         ds18b20_write8(TEN_BIT);
  111.                         break;
  112.                 case 11:
  113.                         ds18b20_write8(ELE_BIT);
  114.                         break;
  115.                 case 12:
  116.                         ds18b20_write8(TWL_BIT);
  117.                         break;
  118.         }
  119. }

  120. static int ds18b20_open(struct inode *inode, struct file *file)
  121. {
  122.         return 0;
  123. }

  124. static int ds18b20_close(struct inode *inode, struct file *file)
  125. {
  126.         return 0;
  127. }

  128. void bubbleSort(int arr[], int count)
  129. {
  130.         int i = count, j;
  131.         int temp;

  132.         while(i > 0)
  133.         {
  134.                 for(j = 0; j < i - 1; j++)
  135.                 {
  136.                         if(arr[j] > arr[j + 1])
  137.                         {
  138.                                 temp = arr[j];
  139.                                 arr[j] = arr[j + 1];
  140.                                 arr[j + 1] = temp;
  141.                         }
  142.                 }
  143.                 i--;
  144.         }

  145. }

  146. static ssize_t ds18b20_read(struct file *file, char *buf, size_t count, loff_t *pos)
  147. {
  148.         unsigned char h8, l8;
  149.         int i, temp = 0, tvalsum;
  150.         int value[12];

  151.         ds18b20_reset();
  152.         ds18b20_write8(SKIP_ROM);
  153.         ds18b20_write8(COVERTT);
  154.         udelay(700);
  155.       
  156.         //mdelay(750);
  157.         
  158.         for (i = 0; i < 12; ++i) {
  159.                 ds18b20_reset();
  160.                 ds18b20_write8(SKIP_ROM);
  161.                 ds18b20_write8(READ_MEM);

  162.                 l8 = ds18b20_read8();
  163.                 h8 = ds18b20_read8();

  164.                 temp = (h8 << 8) | l8;
  165.                 if (temp & 0x8000) {
  166.                         temp = ~temp + 1;
  167.                 }
  168.                 temp *= 50;
  169.                 temp >>= 3;
  170.                 if ((temp > TEMP_H) || (temp < TEMP_L)) {
  171.                         --i;
  172.                         temp = 0;
  173.                         continue;
  174.                 }
  175.                 value[i] = temp;
  176.         }
  177.         
  178.         bubbleSort(value, 12);
  179.        
  180.         for(i = 4, tvalsum = 0;i < 8; ++i)
  181.                 tvalsum+=value[i];
  182.        
  183.         temp = (tvalsum) / 4;
  184.         copy_to_user(buf, &temp, 4);
  185.         return count;
  186. }

  187. static int ds18b20_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  188. {
  189.         unsigned char rel;

  190.         copy_from_user(&rel, (unsigned char *)arg, 1);

  191.         switch(cmd) {
  192.                 case DS18B20_RESET:
  193.                         ds18b20_reset();
  194.                         break;
  195.                 case DS18B20_REL:
  196.                         ds18b20_config_rel(rel);
  197.                         break;
  198.                 default:
  199.                         return -1;
  200.         }
  201.         return 0;
  202. }

  203. static struct file_operations ds18b20_fops = {
  204.         .owner  = THIS_MODULE,
  205.         .open   = ds18b20_open,
  206.         .release  = ds18b20_close,
  207.         .read    = ds18b20_read,
  208.         .unlocked_ioctl  = ds18b20_ioctl,
  209. };

  210. static struct miscdevice ds18b20_miscdev = {
  211.         .minor  = MISC_DYNAMIC_MINOR,      
  212.         .name   = "ds18b20",
  213.         .fops   = &ds18b20_fops,
  214. };

  215. static int ds18b20_init(void)
  216. {
  217.         misc_register(&ds18b20_miscdev);

  218.         gpio_con = ioremap(0xE0200C40, 8);
  219.         gpio_dat = gpio_con + 1;

  220.         return 0;
  221. }

  222. static void ds18b20_exit(void)
  223. {
  224.         iounmap(gpio_con);
  225.         misc_deregister(&ds18b20_miscdev);
  226. }

  227. module_init(ds18b20_init);
  228. module_exit(ds18b20_exit);
  229. MODULE_LICENSE("GPL");

复制代码


下面是makefile文件

  1. obj-m := ds18b20_drv.o
  2. KDIR := /my_dir/linux-smart210/
  3. all:
  4.         make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
  5. clean:
  6.         rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order

复制代码


下面是测试程序

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <sys/ioctl.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>

  8. #define DS18B20_RESET 0x10001
  9. #define DS18B20_REL   0x10002

  10. int main(int argc, char *argv[])
  11. {
  12.         int fd;
  13.         int data;
  14.         unsigned char relbit;

  15.         fd = open("/dev/ds18b20", O_RDWR);
  16.         if (fd < 0) {
  17.                 printf("open ds18b20 failed.\n");
  18.                 exit(-1);
  19.         }

  20.         if (argc < 2)  {
  21.                 printf("usage:\n %s <9|10|11|12>\n", argv[0]);
  22.                 exit(-1);
  23.         }
  24.       
  25.         relbit = strtoul(argv[1], NULL, 10);
  26.         while (1) {
  27.                 ioctl(fd, DS18B20_REL, &relbit);
  28.                 read(fd, &data, sizeof(data));
  29.                 usleep(200000);
  30.                 printf("%f\n", (float)data / 100);        
  31.         }
  32.         close(fd);
  33.         return 0;
  34. }

复制代码

水平有限,难免有错误,忘各位大神多多指教。

走过 路过 抢沙发

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top