mini2440的ds18b20驱动和测试程序

一步一步的在昨天终于把基于 mini2440的ds18b20的驱动编译成功了。其中最大的问题居然是18b20插反了,导致我研究了一天时间最后还是别人告诉我才发现反了。百度图片不可信啊,居然有错图,以后一定要长记性,去下官方的datasheet。呵呵

下面记录下自己的编译过程。

首先是从网上找了个18b20的驱动下载下来了,因为18b20是个技术很成熟的芯片,因此网上资料很多。我下载的代码如下:

 
  1. #include <linux/config.h>  
  2. #include <linux/module.h>  
  3. #include <linux/kernel.h>  
  4. #include <linux/sched.h>  
  5. #include <linux/fs.h>  
  6. #include <linux/init.h>  
  7. #include <linux/devfs_fs_kernel.h>  
  8. #include <linux/miscdevice.h>  
  9. #include <asm/irq.h>  
  10. #include <asm/arch/regs-gpio.h>  
  11. #include <asm/hardware.h>  
  12. #include <asm/uaccess.h>  
  13. #define DEVICE_NAME "DS18B20"  
  14. #define DS18B20_MAJOR 242  
  15. #define DS_PIN S3C2410_GPF0  
  16. #define OUT S3C2410_GPF0_OUTP  
  17. #define IN S3C2410_GPF0_INP  
  18. #define DIS_UP 1  
  19. #define EN_UP 0  
  20. #define Search 0x00F0  
  21. #define Read_ROM 0x0033  //just for one  
  22. #define Skip_ROM 0x00CC    
  23. #define Convert 0x0044  
  24. #define Write 0x004E  //TH---TL---Config  
  25. #define Read 0x00BE  
  26. #define bit_9 0x001F  
  27. #define bit_10 0x003F  
  28. #define bit_11 0x005F  
  29. #define bit_12 0x007F  
  30. #define uint16 unsigned int  
  31. //unsigned int ROM_DATA[8];  
  32. void usdelay(unsigned int i) //延时 i us 对于不同系统可能会有所差别,请适当修改  
  33. {  
  34. unsigned int j;  
  35. for(i=i;i>0;i--)  
  36.   for(j=90;j>0;j--);  
  37. }  
  38. void msdelay(unsigned int i) //延时 i us  
  39. {  
  40. for(i=i;i>0;i--)  
  41.   usdelay(1000);  
  42. }  
  43. void SetL(void)  
  44. {  
  45. s3c2410_gpio_cfgpin(DS_PIN,OUT);  
  46. s3c2410_gpio_setpin(DS_PIN,0);  
  47. }  
  48. void SetH(void)  
  49. {  
  50. s3c2410_gpio_cfgpin(DS_PIN,OUT);  
  51. s3c2410_gpio_setpin(DS_PIN,1);  
  52. }  
  53. unsigned int Read_DS(void)  
  54. {  
  55. unsigned int i;  
  56. s3c2410_gpio_cfgpin(DS_PIN,IN);  
  57. s3c2410_gpio_pullup(DS_PIN,EN_UP);  
  58. __asm("nop");  
  59. __asm("nop");  
  60. __asm("nop");  
  61. i=s3c2410_gpio_getpin(DS_PIN);  
  62. if(i!=0)  
  63.   i=1;  
  64. return i;  
  65. }  
  66. unsigned int ds_start(void)  
  67. {  
  68. unsigned int flag=1;int err=0;  
  69. SetL();  
  70. usdelay(500); //560  
  71. SetH();  
  72. usdelay(1);  
  73. while(Read_DS()!=0)  
  74. {  
  75. //  printk(DEVICE_NAME "Wait..../n");  
  76.   usdelay(5);  
  77.   err++;  
  78.   if(err==20)  
  79.   {  
  80.    printk(DEVICE_NAME "start fail/n");  
  81.    return -1;  
  82.   }  
  83. }  
  84. // printk(DEVICE_NAME "start sucess/n");  
  85. flag=0;  
  86. SetH();  
  87. usdelay(400);  
  88. return flag;  
  89. }  
  90. void ds_send(unsigned int uidata)  
  91. {  
  92. unsigned int i;  
  93. for(i=0;i<8;i++)  
  94. {  
  95.   SetL();  
  96.   if((uidata&1)!=0)  
  97.   {  
  98.    usdelay(3); //3  
  99.    SetH();  
  100.    usdelay(80);  
  101.   }  
  102.   else  
  103.   {  
  104.    usdelay(80);  
  105.    SetH();  
  106.    usdelay(5); //  
  107.   }  
  108.   uidata>>=1;  
  109. }  
  110. }  
  111. unsigned int ds_read(void)  
  112. {  
  113. unsigned int uidata=0;unsigned int i;  
  114. for(i=0;i<8;i++)  
  115. {  
  116.   SetL();  
  117.   usdelay(4); //2 3  
  118.   SetH();  
  119.   usdelay(7); //1 2 3 4 5(e)  
  120.   if(Read_DS()==1)  
  121.    uidata+=0x0100;  
  122.   uidata>>=1;  
  123.   SetH();  
  124.   usdelay(65);  
  125. }  
  126. return uidata;   
  127. }  
  128. void ds_init(unsigned int TH,unsigned int TL,unsigned int bit_nmb)  
  129. {  
  130. SetH();  
  131. usdelay(80);  
  132. if(ds_start()==0)  
  133. {  
  134.     
  135.   ds_send(Skip_ROM);  //复位  
  136.   ds_send(Write);  //跳过ROM匹配  
  137.   ds_send(TH);  //TH  
  138.   ds_send(TL);  //TL  
  139.   ds_send(bit_nmb);  //转换位数  
  140. }  
  141. }  
  142. unsigned int read_tem(void)  
  143. {  
  144. unsigned int th,tl;int err=0;  
  145. ds_init(100,0,bit_12);  
  146. th=tl=0;   
  147. ds_start();  
  148. ds_start();  
  149. ds_start();  
  150. ds_send(Skip_ROM);  
  151. ds_send(Convert);  
  152. msdelay(50);  
  153. while(Read_DS()==0)  
  154. {  
  155. //  printk(DEVICE_NAME "Convert..../n");  
  156.   msdelay(50);  
  157.   err++;  
  158.   if(err==10)  
  159.   {  
  160.    printk(DEVICE_NAME "convert fail/n");  
  161.    return -1;  
  162.   }  
  163. }  
  164. ds_start();  
  165. ds_start();  
  166. ds_send(Skip_ROM);  
  167. ds_send(Read);  
  168. tl=ds_read();  
  169. th=ds_read();  
  170. ds_start();  
  171. ds_start();  
  172. th<<=8;  
  173. tl|=th;  
  174. return tl;  
  175. }  
  176.   
  177. static int ds18b20_ioctl(  
  178. struct inode *inode,   
  179. struct file *file,   
  180. unsigned int cmd,unsigned long arg)  
  181. {  
  182. return 0;  
  183. }  
  184. static ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off )  
  185. {  
  186.     uint16 tmp,ret;  
  187.       
  188.     tmp =read_tem();  
  189.     ret=copy_to_user(pData, &tmp, sizeof(tmp));    //将读取得的DS18B20数值复制到用户区  
  190. if(ret>0)  
  191. {  
  192.   printk("copy data failed/n");  
  193.   return -1;  
  194. }  
  195.     return 0;  
  196. }  
  197. static struct file_operations ds18b20_fops = {  
  198. .owner = THIS_MODULE,  
  199. .ioctl = ds18b20_ioctl,  
  200. .read = ds18b20_read,  
  201. };  
  202. static int __init ds18b20_init(void)  
  203. {  
  204. int ret;  
  205. ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);  
  206. if (ret < 0) {  
  207.    printk(DEVICE_NAME " can't register major number/n");  
  208.    return ret;  
  209. }  
  210. devfs_mk_cdev(MKDEV(DS18B20_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);  
  211. s3c2410_gpio_cfgpin(DS_PIN, OUT);  
  212. s3c2410_gpio_setpin(DS_PIN, 1);  
  213. //printk(DEVICE_NAME " initialized/n");  
  214. return 0;  
  215. }  
  216. static void __exit ds18b20_exit(void)  
  217. {  
  218. devfs_remove(DEVICE_NAME);  
  219. unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);  
  220. printk(DEVICE_NAME " rmmodule/n");  
  221. }  
  222. module_init(ds18b20_init);  
  223. module_exit(ds18b20_exit);  
  224. MODULE_AUTHOR("benjamin_xc@163.com");             // 驱动程序的作者  
  225. MODULE_DESCRIPTION("DS18B20 Driver");   // 一些描述信息  
  226. MODULE_LICENSE("GPL");                              // 遵循的协议  
 

 

我只改了引脚和主设备号。其他的都没改。

按照之前的帖子编译,编译成功后出现*.ko文件。

建立nfs服务器,

mknod /dev/DS18B20 c 242 0

insmod ds18b20.ko

两条命令如果都没有错误自少说明驱动的方法没有问题,就看驱动本身有没有错误了。

连线,18b20有三根线,把平面对着自己,左手边起为地,数据,正。

在数据和正之间要加一个4-10k的电阻,我加的是4.7K的。开发板插的是一个正,地,和gpf0端口。fpf0端口在con4的靠着滑动电阻的第五根线。正是第一根,地是第二跟。

之后编译测试程序,如下:

 

 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <sys/ioctl.h>  
  5. #include <sys/types.h>  
  6. #include <sys/stat.h>  
  7. #include <fcntl.h>  
  8. #include <sys/select.h>  
  9. #include <sys/time.h>  
  10. #include <errno.h>  
  11. #define K 0.0625  
  12. int main(void)  
  13. {  
  14.     int fd = -1;  
  15.     char count = 5;  
  16.     unsigned int tmp = 0;float res=0;  
  17.     fd = open("/dev/DS18B20", 0);  
  18.     if(fd < 0)  
  19.     {  
  20.         perror("Can't open /dev/DS18B20 /n");  
  21.         exit(1);  
  22.     }  
  23.     printf("open ds18b20 success /n");  
  24. while(1){  
  25.         read(fd, &tmp , sizeof(tmp));  
  26.     res=tmp*K;  
  27.     printf("the currently temperature is %f/n",res);  
  28.     sleep(1);  
  29. }  
  30. close(fd);  
  31.     return 0;  
  32. }  
 

 

编译后运行,如果没有什么线插错的情况下应该就能正常显示温度了。呵呵~

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值