mini2440的ds18b20驱动和测试程序

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

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

首先是从网上找了个18b20的驱动下载下来了,因为18b20是个技术很成熟的芯片,因此网上资料很多。我下载的代码如下:#include #include #include #include #include #include #include #include #include #include #include #include #define DEVICE_NAME "DS18B20" #define DS18B20_MAJOR 242 #define DS_PIN S3C2410_GPF0 #define OUT S3C2410_GPF0_OUTP #define IN S3C2410_GPF0_INP #define DIS_UP 1 #define EN_UP 0 #define Search 0x00F0 #define Read_ROM 0x0033 //just for one #define Skip_ROM 0x00CC #define Convert 0x0044 #define Write 0x004E //TH---TL---Config #define Read 0x00BE #define bit_9 0x001F #define bit_10 0x003F #define bit_11 0x005F #define bit_12 0x007F #define uint16 unsigned int //unsigned int ROM_DATA[8]; void usdelay(unsigned int i) //延时 i us 对于不同系统可能会有所差别,请适当修改 { unsigned int j; for(i=i;i>0;i--) for(j=90;j>0;j--); } void msdelay(unsigned int i) //延时 i us { for(i=i;i>0;i--) usdelay(1000); } void SetL(void) { s3c2410_gpio_cfgpin(DS_PIN,OUT); s3c2410_gpio_setpin(DS_PIN,0); } void SetH(void) { s3c2410_gpio_cfgpin(DS_PIN,OUT); s3c2410_gpio_setpin(DS_PIN,1); } unsigned int Read_DS(void) { unsigned int i; s3c2410_gpio_cfgpin(DS_PIN,IN); s3c2410_gpio_pullup(DS_PIN,EN_UP); __asm("nop"); __asm("nop"); __asm("nop"); i=s3c2410_gpio_getpin(DS_PIN); if(i!=0) i=1; return i; } unsigned int ds_start(void) { unsigned int flag=1;int err=0; SetL(); usdelay(500); //560 SetH(); usdelay(1); while(Read_DS()!=0) { // printk(DEVICE_NAME "Wait..../n"); usdelay(5); err++; if(err==20) { printk(DEVICE_NAME "start fail/n"); return -1; } } // printk(DEVICE_NAME "start sucess/n"); flag=0; SetH(); usdelay(400); return flag; } void ds_send(unsigned int uidata) { unsigned int i; for(i=0;i<8;i++) { SetL(); if((uidata&1)!=0) { usdelay(3); //3 SetH(); usdelay(80); } else { usdelay(80); SetH(); usdelay(5); // } uidata>>=1; } } unsigned int ds_read(void) { unsigned int uidata=0;unsigned int i; for(i=0;i<8;i++) { SetL(); usdelay(4); //2 3 SetH(); usdelay(7); //1 2 3 4 5(e) if(Read_DS()==1) uidata+=0x0100; uidata>>=1; SetH(); usdelay(65); } return uidata; } void ds_init(unsigned int TH,unsigned int TL,unsigned int bit_nmb) { SetH(); usdelay(80); if(ds_start()==0) { ds_send(Skip_ROM); //复位 ds_send(Write); //跳过ROM匹配 ds_send(TH); //TH ds_send(TL); //TL ds_send(bit_nmb); //转换位数 } } unsigned int read_tem(void) { unsigned int th,tl;int err=0; ds_init(100,0,bit_12); th=tl=0; ds_start(); ds_start(); ds_start(); ds_send(Skip_ROM); ds_send(Convert); msdelay(50); while(Read_DS()==0) { // printk(DEVICE_NAME "Convert..../n"); msdelay(50); err++; if(err==10) { printk(DEVICE_NAME "convert fail/n"); return -1; } } ds_start(); ds_start(); ds_send(Skip_ROM); ds_send(Read); tl=ds_read(); th=ds_read(); ds_start(); ds_start(); th<<=8; tl|=th; return tl; } static int ds18b20_ioctl( struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg) { return 0; } static ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off ) { uint16 tmp,ret; tmp =read_tem(); ret=copy_to_user(pData, &tmp, sizeof(tmp)); //将读取得的DS18B20数值复制到用户区 if(ret>0) { printk("copy data failed/n"); return -1; } return 0; } static struct file_operations ds18b20_fops = { .owner = THIS_MODULE, .ioctl = ds18b20_ioctl, .read = ds18b20_read, }; static int __init ds18b20_init(void) { int ret; ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops); if (ret < 0) { printk(DEVICE_NAME " can't register major number/n"); return ret; } devfs_mk_cdev(MKDEV(DS18B20_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME); s3c2410_gpio_cfgpin(DS_PIN, OUT); s3c2410_gpio_setpin(DS_PIN, 1); //printk(DEVICE_NAME " initialized/n"); return 0; } static void __exit ds18b20_exit(void) { devfs_remove(DEVICE_NAME); unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME); printk(DEVICE_NAME " rmmodule/n"); } module_init(ds18b20_init); module_exit(ds18b20_exit); MODULE_AUTHOR("[email protected]"); // 驱动程序的作者 MODULE_DESCRIPTION("DS18B20 Driver"); // 一些描述信息 MODULE_LICENSE("GPL"); // 遵循的协议 

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

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

建立nfs服务器,

mknod /dev/DS18B20 c 242 0

insmod ds18b20.ko

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

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

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

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

#include #include #include #include #include #include #include #include #include #include #define K 0.0625 int main(void) { int fd = -1; char count = 5; unsigned int tmp = 0;float res=0; fd = open("/dev/DS18B20", 0); if(fd < 0) { perror("Can't open /dev/DS18B20 /n"); exit(1); } printf("open ds18b20 success /n"); while(1){ read(fd, &tmp , sizeof(tmp)); res=tmp*K; printf("the currently temperature is %f/n",res); sleep(1); } close(fd); return 0; }  

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

你可能感兴趣的:(嵌入式开发,测试,module,struct,file,c,user)