基于Tiny6410的ds18b20驱动


从网站上下载了lixin的mini2410的ds18b20代码,并做了修改,成功实现了Tiny6410的ds18b20驱动。感谢署名为lixin的网友!

 【程序清单】

ds18b20.c

[html]
  1. /******************************************Copyright(c)************************************************  
  2. ** 文件名称: ds18b20_drv.c  
  3. ** 作    者: lixin  
  4. ** 版    本: v1.0  
  5. ** 说    明: ds18b20驱动程序.工作过程及时序见ds18b20 datasheet  
  6. ** 修改记录: 2009-8-27创建  
  7. ** 最后修改时间: 2009-09-01  
  8. ******************************************************************************************************/  
  9. #include <linux/init.h>  
  10. #include <linux/module.h>  
  11. #include <linux/delay.h>  
  12. #include <linux/kernel.h>  
  13. #include <linux/moduleparam.h>  
  14. #include <linux/init.h>  
  15. #include <linux/types.h>  
  16. #include <linux/fs.h>  
  17. #include <mach/regs-gpio.h>  
  18. #include <linux/device.h>  
  19. #include <mach/hardware.h>  
  20. #include <linux/cdev.h>  
  21. #include <asm/uaccess.h>  
  22. #include <linux/errno.h>  
  23.   
  24. #include "s3c6410_gpio.h"  
  25.   
  26. //#define DEBUG  
  27. /* 相关引脚定义,方便以后移植 */  
  28. #define DEVICE_NAME "ds18b20"  
  29. #define DQ         8  
  30. #define CFG_IN     0  
  31. #define CFG_OUT    1  
  32.   
  33. // ds18b20主次设备号(动态分配)  
  34. int ds18b20_major = 0;  
  35. int ds18b20_minor = 0;  
  36. int ds18b20_nr_devs = 1;  
  37.   
  38. // 定义设备类型  
  39. static struct ds18b20_device {  
  40.     struct cdev cdev;  
  41. };  
  42. struct ds18b20_device ds18b20_dev;  
  43.   
  44. static struct class *ds18b20_class;  
  45.   
  46. /* 函数声明 */  
  47. static int ds18b20_open(struct inode *inode, struct file *filp);  
  48. static int ds18b20_init(void);  
  49. static void write_byte(unsigned char data);  
  50. static unsigned char read_byte(void);  
  51. static ssize_t ds18b20_read(struct file *filp, char __user *buf,  
  52.                             size_t count, loff_t *f_pos);  
  53. void ds18b20_setup_cdev(struct ds18b20_device *dev, int index);  
  54.   
  55. /******************************************************************************************************  
  56. ** 函数名称: ds18b20_open()  
  57. ** 函数功能: 打开设备,初始化ds18b20  
  58. ** 入口参数: inode:设备文件信息; filp: 被打开的文件的信息  
  59. ** 出口参数: 成功时返回0,失败返回-1  
  60. ** 备    注:  
  61. ******************************************************************************************************/  
  62. static int ds18b20_open(struct inode *inode, struct file *filp)  
  63. {  
  64.     int flag = 0;  
  65.     /*struct ds18b20_device *dev;  
  66.     dev = container_of(inode->i_cdev, struct ds18b20_device, cdev);  
  67.     filp->private_data = dev;*/  
  68.   
  69.     flag = ds18b20_init();  
  70.     if(flag & 0x01)  
  71.     {  
  72. #ifdef DEBUG  
  73.         printk(KERN_WARNING "open ds18b20 failed\n");  
  74. #endif  
  75.     return -1;  
  76.     }  
  77. #ifdef DEBUG  
  78.     printk(KERN_NOTICE "open ds18b20 successful\n");  
  79. #endif  
  80.     return 0;  
  81. }  
  82.   
  83. /******************************************************************************************************  
  84. ** 函数名称: ds18b20_init()  
  85. ** 函数功能: 复位ds18b20  
  86. ** 入口参数: 无  
  87. ** 出口参数: retval:成功返回0,失败返回1  
  88. ** 备    注: 操作时序见ds18b20 datasheet  
  89. ******************************************************************************************************/  
  90. static int ds18b20_init(void)  
  91. {  
  92.     int retval = 0;  
  93.   
  94.     s3c6410_gpio_cfgpin(DQ, CFG_OUT);  
  95.     s3c6410_gpio_pullup(DQ, 0);  
  96.   
  97.     s3c6410_gpio_setpin(DQ, 1);  
  98.     udelay(2);  
  99.     s3c6410_gpio_setpin(DQ, 0);        // 拉低ds18b20总线,复位ds18b20  
  100.     udelay(500);                       // 保持复位电平500us  
  101.   
  102.     s3c6410_gpio_setpin(DQ, 1);        // 释放ds18b20总线  
  103.     udelay(60);  
  104.   
  105.     // 若复位成功,ds18b20发出存在脉冲(低电平,持续60~240us)  
  106.     s3c6410_gpio_cfgpin(DQ, CFG_IN);  
  107.     retval = s3c6410_gpio_getpin(DQ);  
  108.   
  109.     udelay(500);  
  110.     s3c6410_gpio_cfgpin(DQ, CFG_OUT);  
  111.     s3c6410_gpio_pullup(DQ, 0);  
  112.     s3c6410_gpio_setpin(DQ, 1);        // 释放总线  
  113.       
  114.     return retval;  
  115. }  
  116.   
  117. /******************************************************************************************************  
  118. ** 函数名称: write_byte()  
  119. ** 函数功能: 向18b20写入一个字节数据  
  120. ** 入口参数: data  
  121. ** 出口参数: 无  
  122. ** 备    注:  
  123. ******************************************************************************************************/  
  124. static void write_byte(unsigned char data)  
  125. {  
  126.     int i = 0;  
  127.   
  128.     s3c6410_gpio_cfgpin(DQ, CFG_OUT);  
  129.     s3c6410_gpio_pullup(DQ, 1);  
  130.   
  131.     for (i = 0; i < 8; i ++)  
  132.     {  
  133.         // 总线从高拉至低电平时,就产生写时隙  
  134.         s3c6410_gpio_setpin(DQ, 1);  
  135.         udelay(2);  
  136.         s3c6410_gpio_setpin(DQ, 0);  
  137.         s3c6410_gpio_setpin(DQ, data & 0x01);  
  138.         udelay(60);  
  139.     data >>= 1;  
  140.     }  
  141.     s3c6410_gpio_setpin(DQ, 1);        // 重新释放ds18b20总线  
  142. }  
  143.   
  144. /******************************************************************************************************  
  145. ** 函数名称: read_byte()  
  146. ** 函数功能: 从ds18b20读出一个字节数据  
  147. ** 入口参数: 无  
  148. ** 出口参数: 读出的数据  
  149. ** 备    注:  
  150. ******************************************************************************************************/  
  151. static unsigned char read_byte(void)  
  152. {  
  153.     int i;  
  154.     unsigned char data = 0;  
  155.   
  156.     for (i = 0; i < 8; i++)  
  157.     {  
  158.         // 总线从高拉至低,只需维持低电平17ts,再把总线拉高,就产生读时隙  
  159.         s3c6410_gpio_cfgpin(DQ, CFG_OUT);  
  160.         s3c6410_gpio_pullup(DQ, 0);  
  161.         s3c6410_gpio_setpin(DQ, 1);  
  162.         udelay(2);  
  163.         s3c6410_gpio_setpin(DQ, 0);  
  164.         udelay(2);  
  165.     s3c6410_gpio_setpin(DQ, 1);  
  166.         udelay(8);  
  167.         data >>= 1;  
  168.     s3c6410_gpio_cfgpin(DQ, CFG_IN);  
  169.     if (s3c6410_gpio_getpin(DQ))  
  170.         data |= 0x80;  
  171.     udelay(50);  
  172.     }  
  173.     s3c6410_gpio_cfgpin(DQ, CFG_OUT);  
  174.     s3c6410_gpio_pullup(DQ, 0);  
  175.     s3c6410_gpio_setpin(DQ, 1);        // 释放ds18b20总线  
  176.     return data;  
  177. }  
  178. /******************************************************************************************************  
  179. ** 函数名称: ds18b20_read()  
  180. ** 函数功能: 读出18b20的温度  
  181. ** 入口参数:   
  182. ** 出口参数:   
  183. ** 备    注:  
  184. ******************************************************************************************************/  
  185. static ssize_t ds18b20_read(struct file *filp, char __user *buf,  
  186.                             size_t count, loff_t *f_pos)  
  187. {  
  188.     int flag;  
  189.     unsigned long err;  
  190.     unsigned char result[2] = {0x00, 0x00};  
  191.     //struct ds18b20_device *dev = filp->private_data;  
  192.   
  193.     flag = ds18b20_init();  
  194.     if (flag)  
  195.     {  
  196. #ifdef DEBUG  
  197.         printk(KERN_WARNING "ds18b20 init failed\n");  
  198. #endif  
  199.         return -1;  
  200.     }  
  201.       
  202.     write_byte(0xcc);  
  203.     write_byte(0x44);  
  204.   
  205.     flag = ds18b20_init();  
  206.     if (flag)  
  207.         return -1;  
  208.   
  209.     write_byte(0xcc);  
  210.     write_byte(0xbe);  
  211.   
  212.     result[0] = read_byte();    // 温度低八位  
  213.     result[1] = read_byte();    // 温度高八位  
  214.       
  215.     err = copy_to_user(buf, &result, sizeof(result));  
  216.     return err ? -EFAULT : min(sizeof(result),count);  
  217. }  
  218.   
  219. /**************************************************************  
  220.  * 字符驱动程序的核心,应用程序所调用的open,read等函数最终会  
  221.  * 调用这个结构中的对应函数  
  222.  *************************************************************/  
  223. static struct file_operations ds18b20_dev_fops = {  
  224.     .owner = THIS_MODULE,  
  225.     .open = ds18b20_open,  
  226.     .read = ds18b20_read,  
  227. };  
  228.   
  229. /******************************************************************************************************  
  230. ** 函数名称: ds18b20_setup_cdev()  
  231. ** 函数功能: 初始化cdev  
  232. ** 入口参数: dev:设备结构体; index:  
  233. ** 出口参数: 无  
  234. ** 备    注:  
  235. ******************************************************************************************************/  
  236. void ds18b20_setup_cdev(struct ds18b20_device *dev, int index)  
  237. {  
  238.     int err, devno = MKDEV(ds18b20_major, ds18b20_minor + index);  
  239.   
  240.     cdev_init(&dev->cdev, &ds18b20_dev_fops);  
  241.     dev->cdev.owner = THIS_MODULE;  
  242.     err = cdev_add(&(dev->cdev), devno, 1);  
  243.     if (err)  
  244.     {  
  245. #ifdef DEBUG  
  246.         printk(KERN_NOTICE "ERROR %d add ds18b20\n", err);  
  247. #endif  
  248.     }  
  249. }  
  250.   
  251. /******************************************************************************************************  
  252. ** 函数名称: ds18b20_dev_init()  
  253. ** 函数功能: 为温度传感器分配注册设备号,初始化cdev  
  254. ** 入口参数: 无  
  255. ** 出口参数: 若成功执行,返回0  
  256. ** 备    注:  
  257. ******************************************************************************************************/  
  258. static int __init ds18b20_dev_init(void)  
  259. {  
  260.     ds18b20_major = register_chrdev(ds18b20_major, DEVICE_NAME, &ds18b20_dev_fops);  
  261.     if (ds18b20_major<0)  
  262.     {  
  263.     printk(DEVICE_NAME " Can't register major number!\n");  
  264.     return -EIO;  
  265.     }  
  266.   
  267.     ds18b20_class = class_create(THIS_MODULE, DEVICE_NAME);  
  268.     device_create(ds18b20_class, NULL, MKDEV(ds18b20_major, ds18b20_minor), NULL, DEVICE_NAME);  
  269. #ifdef DEBUG  
  270.     printk(KERN_WARNING "register ds18b20 driver successful!\n");  
  271. #endif  
  272.     return 0;  
  273. }  
  274.   
  275. /******************************************************************************************************  
  276. ** 函数名称: ds18b20_dev_exit()  
  277. ** 函数功能: 注销设备  
  278. ** 入口参数: 无  
  279. ** 出口参数: 无  
  280. ** 备    注:  
  281. ******************************************************************************************************/  
  282. static void __exit ds18b20_dev_exit(void)  
  283. {  
  284.     device_destroy(ds18b20_class, MKDEV(ds18b20_major,ds18b20_minor));  
  285.     class_unregister(ds18b20_class);  
  286.     class_destroy(ds18b20_class);  
  287.     unregister_chrdev(ds18b20_major, DEVICE_NAME);  
  288. #ifdef DEBUG  
  289.     printk(KERN_WARNING "Exit ds18b20 driver!\n");  
  290. #endif  
  291. }  
  292.   
  293. module_init(ds18b20_dev_init);  
  294. module_exit(ds18b20_dev_exit);  
  295. MODULE_LICENSE("Dual BSD/GPL");  
  296. MODULE_AUTHOR("xinli_whut@163.com");  
  297. /******************************************************************************************************  
  298. **                                         文件到此结束  
  299. ******************************************************************************************************/    
  • 1
  • 2
  • 下一页

相关内容