mini2440上DS18B20的驱动程序(含简单测试)

发布时间: 2024-06-24
来源: 电子工程世界

ds18b20_drv.c


[cpp]

  1. #include    

  2. #include    

  3. #include    

  4. #include    

  5. #include    

  6. #include    

  7. #include    

  8. #include    

  9. #include    

  10. #include    

  11. #include    

  12. #include    

  13. #include    

  14. #include    

  15. #include    

  16.   

  17. /* 相关引脚定义,方便以后移植 */  

  18. #define DQ         S3C2410_GPF(3)   

  19. #define CFG_IN     S3C2410_GPIO_INPUT   

  20. #define CFG_OUT    S3C2410_GPIO_OUTPUT   

  21.   

  22. // ds18b20主次设备号(动态分配)   

  23. static int ds18b20_major = 0;  

  24. static int ds18b20_minor = 0;  

  25. static int ds18b20_nr_devs = 1;  

  26.   

  27. // 定义设备类型   

  28. static struct ds18b20_device  

  29. {  

  30.     struct cdev cdev;  

  31. };  

  32.   

  33. struct ds18b20_device *ds18b20_devp;    /*设备结构体指针 */  

  34.   

  35. static struct class *ds18b20_class;  

  36. static struct class_device *ds18b20_class_dev;  

  37.   

  38. /* 函数声明 */  

  39. static int ds18b20_open(struct inode *inode, struct file *filp);  

  40. static int ds18b20_init(void);  

  41. static void write_byte(unsigned char data);  

  42. static unsigned char read_byte(void);  

  43. static ssize_t ds18b20_read(struct file *filp, char __user * buf, size_t count, loff_t * f_pos);  

  44. void ds18b20_setup_cdev(struct ds18b20_device *dev, int index);  

  45.   

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

  47. {  

  48.     int flag = 0;  

  49.   

  50.     flag = ds18b20_init();  

  51.     if (flag & 0x01)  

  52.     {  

  53.         printk(KERN_WARNING "open ds18b20 failedn");  

  54.         return -1;  

  55.     }  

  56.     printk(KERN_NOTICE "open ds18b20 successfuln");  

  57.     return 0;  

  58. }  

  59.   

  60. static int ds18b20_init(void)  

  61. {  

  62.     int retval = 0;  

  63.   

  64.     s3c2410_gpio_cfgpin(DQ, CFG_OUT);  

  65.     s3c2410_gpio_pullup(DQ, 0);  

  66.   

  67.     s3c2410_gpio_setpin(DQ, 1);  

  68.     udelay(2);  

  69.     s3c2410_gpio_setpin(DQ, 0); // 拉低ds18b20总线,复位ds18b20   

  70.     udelay(500);                // 保持复位电平500us   

  71.   

  72.     s3c2410_gpio_setpin(DQ, 1); // 释放ds18b20总线   

  73.     udelay(60);  

  74.   

  75.     // 若复位成功,ds18b20发出存在脉冲(低电平,持续60~240us)   

  76.     s3c2410_gpio_cfgpin(DQ, CFG_IN);  

  77.     retval = s3c2410_gpio_getpin(DQ);  

  78.   

  79.     udelay(500);  

  80.     s3c2410_gpio_cfgpin(DQ, CFG_OUT);  

  81.     s3c2410_gpio_pullup(DQ, 0);  

  82.     s3c2410_gpio_setpin(DQ, 1); // 释放总线   

  83.   

  84.     return retval;  

  85. }  

  86.   

  87. static void write_byte(unsigned char data)  

  88. {  

  89.     int i = 0;  

  90.   

  91.     s3c2410_gpio_cfgpin(DQ, CFG_OUT);  

  92.     s3c2410_gpio_pullup(DQ, 1);  

  93.   

  94.     for (i = 0; i < 8; i++)  

  95.     {  

  96.         // 总线从高拉至低电平时,就产生写时隙   

  97.         s3c2410_gpio_setpin(DQ, 1);  

  98.         udelay(2);  

  99.         s3c2410_gpio_setpin(DQ, 0);  

  100.         s3c2410_gpio_setpin(DQ, data & 0x01);  

  101.         udelay(60);  

  102.         data >>= 1;  

  103.     }  

  104.     s3c2410_gpio_setpin(DQ, 1); // 重新释放ds18b20总线   

  105. }  

  106.   

  107. static unsigned char read_byte(void)  

  108. {  

  109.     int i;  

  110.     unsigned char data = 0;  

  111.   

  112.     for (i = 0; i < 8; i++)  

  113.     {  

  114.         // 总线从高拉至低,只需维持低电平17ts,再把总线拉高,就产生读时隙   

  115.         s3c2410_gpio_cfgpin(DQ, CFG_OUT);  

  116.         s3c2410_gpio_pullup(DQ, 0);  

  117.         s3c2410_gpio_setpin(DQ, 1);  

  118.         udelay(2);  

  119.         s3c2410_gpio_setpin(DQ, 0);  

  120.         udelay(2);  

  121.         s3c2410_gpio_setpin(DQ, 1);  

  122.         udelay(8);  

  123.         data >>= 1;  

  124.         s3c2410_gpio_cfgpin(DQ, CFG_IN);  

  125.         if (s3c2410_gpio_getpin(DQ))  

  126.             data |= 0x80;  

  127.         udelay(50);  

  128.     }  

  129.     s3c2410_gpio_cfgpin(DQ, CFG_OUT);  

  130.     s3c2410_gpio_pullup(DQ, 0);  

  131.     s3c2410_gpio_setpin(DQ, 1); // 释放ds18b20总线   

  132.     return data;  

  133. }  

  134.   

  135. static ssize_t ds18b20_read(struct file *filp, char __user * buf, size_t count, loff_t * f_pos)  

  136. {  

  137.     int flag;  

  138.     unsigned long err;  

  139.     unsigned char result[2] = { 0x00, 0x00 };  

  140.     //struct ds18b20_device *dev = filp->private_data;   

  141.   

  142.     flag = ds18b20_init();  

  143.     if (flag & 0x01)  

  144.     {  

  145.         printk(KERN_WARNING "ds18b20 init failedn");  

  146.         return -1;  

  147.     }  

  148.   

  149.     write_byte(0xcc);  

  150.     write_byte(0x44);  

  151.   

  152.     flag = ds18b20_init();  

  153.     if (flag & 0x01)  

  154.         return -1;  

  155.   

  156.     write_byte(0xcc);  

  157.     write_byte(0xbe);  

  158.   

  159.     result[0] = read_byte();    // 温度低八位   

  160.     result[1] = read_byte();    // 温度高八位   

  161.   

  162.     err = copy_to_user(buf, &result, sizeof(result));  

  163.     return err ? -EFAULT : min(sizeof(result), count);  

  164. }  

  165.   

  166. static struct file_operations ds18b20_dev_fops = {  

  167.     .owner = THIS_MODULE,  

  168.     .open = ds18b20_open,  

文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。