我用的是FL2440开发板查看好datasheet后找到相应的管脚写的platform 总线编写
/********************************************************************************* * Copyright: (C) 2016 guanlei * All rights reserved. * * Filename: myds18b20.c * Description: This file * * Version: 1.0.0(2016年04月11日) * Author: guanlei <995318056@QQ.com> * ChangeLog: 1, Release initial version on "2016年04月11日 14时56分25秒" * ********************************************************************************/#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/delay.h> #include <asm/irq.h> #include <mach/regs-gpio.h> #include <mach/hardware.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/kdev_t.h> #include <asm/uaccess.h> #include <linux/platform_device.h> #include <linux/gpio.h>#define DEV_NAME "ds18b20" #ifndef DEV_MAJOR#define DEV_MAJOR 0 /* dynamic major by default */#endif#define DS18B20_PIN S3C2410_GPG(0)#define DS18B20_PIN_OUT S3C2410_GPIO_OUTPUT#define DS18B20_PIN_IN S3C2410_GPIO_INPUTtypedef unsigned char BYTE; dev_t devno; MODULE_LICENSE("GPL"); static int dev_major = DEV_MAJOR;static int dev_minor = 0;struct cdev my_cdev; static struct class *ds18b20_class; BYTE data[2];static struct platform_device s3c2440_ds18b20_device ={ .name = "s3c2440_ds18b20", .id = 1, .dev ={ },}; unsigned char ds18b20_reset(void){ s3c2410_gpio_cfgpin(DS18B20_PIN,DS18B20_PIN_OUT);/* config output mode */ s3c2410_gpio_setpin(DS18B20_PIN,1);/* send high and keep 100us */ udelay(100); s3c2410_gpio_setpin(DS18B20_PIN,0) ;/* send low and keep 600us */ udelay(600); s3c2410_gpio_setpin(DS18B20_PIN, 1); // 向18B20发送一个上升沿,此时可释放DS18B20总线 udelay(100); // 通过再次配置GPIG0引脚成输入状态,可以检测到DS18B20是否复位成功 s3c2410_gpio_cfgpin(DS18B20_PIN,DS18B20_PIN_IN); if(s3c2410_gpio_getpin(DS18B20_PIN)) { PRintk("DS18b20 reset failed./r/n"); return 1; } printk("reset successed!/n"); return 0;}void ds18b20_write_byte(unsigned char byte){ unsigned char i; s3c2410_gpio_cfgpin(DS18B20_PIN,DS18B20_PIN_OUT); /* write 1 * keep low 1us-15us * then keep bus high 15us - 60us * * write 0 * keep low 15us - 60us * then keeep bus high 1us - 15us */ for (i=0;i<8;i++) { s3c2410_gpio_setpin(DS18B20_PIN,0); /* 每次写之后延时 1us */ udelay(1); /* write 1 or 0 */ s3c2410_gpio_setpin(DS18B20_PIN,(byte&0x01)?1:0); udelay(60); /* release bus */ s3c2410_gpio_setpin(DS18B20_PIN,1); byte >>= 1; udelay(15); } s3c2410_gpio_setpin(DS18B20_PIN, 1); //释放总线 }unsigned char ds18b20_read_byte(void ){ unsigned char i ; unsigned char dat = 0 ; for(i=0;i<8;i++) { s3c2410_gpio_cfgpin(DS18B20_PIN,DS18B20_PIN_OUT); s3c2410_gpio_setpin(DS18B20_PIN,0); /* give a maicohong */ dat >>= 1; udelay(1); s3c2410_gpio_setpin(DS18B20_PIN,1); /* */ s3c2410_gpio_cfgpin(DS18B20_PIN,DS18B20_PIN_IN); if(s3c2410_gpio_getpin(DS18B20_PIN)) { dat |= 0x80; } udelay(60); } return dat;}static int ds18b20_open(struct inode *inode, struct file *file) { printk("open ds18b20"); return 0;}static int ds18b20_read(struct file *filep,char *buff ,size_t len ,loff_t *offp){ //unsigned char temp_flag; /* above zero or below zero */ // unsigned short temp; int err; ds18b20_reset(); /* reset */ udelay(120); ds18b20_write_byte(0xcc);//写入CCH命令,跳过读序列号过程; ds18b20_write_byte(0x44);//写入44H命令,开始温度转换,延时5 ms; udelay(5); ds18b20_reset(); udelay(200); ds18b20_write_byte(0xcc);//写入CCH命令,跳过读序列号过程; ds18b20_write_byte(0xbe); //写入BEH命令,读取寄存器; data[0] = ds18b20_read_byte(); //温度的整数部分 data[1] = ds18b20_read_byte(); //温度的小数部分 /* temp = ((unsigned char)data[0]) << 8; temp |=(unsigned char)data[1]; temp = 0.0625*((double)temp); */ err = copy_to_user(buff,(void *)data,len); return err? -EFAULT:len ;}static struct file_Operations ds18b20_ops = { .owner = THIS_MODULE, .read = ds18b20_read, //.release = ds18b20_release,};static int s3c2440_ds18b20_probe(struct platform_device *pdev){ int ret ,err,result; /*alloc the device for device */ if( 0 != dev_major) { devno = MKDEV(dev_major,dev_minor); result = register_chrdev_region(devno,1,DEV_NAME); } else { result = alloc_chrdev_region(&devno,dev_minor,1,DEV_NAME); dev_major = MAJOR(devno); } /* alloc for device major failure */ if(result<0) { printk("alloc_chdrev_region error"); printk("%s driver can't get major %d/n", DEV_NAME, dev_major); return result; } printk("%s driver get major %d/n", DEV_NAME, dev_major); /* init ds18b20_device and register cdev */ cdev_init (&my_cdev,&ds18b20_ops); my_cdev.owner = THIS_MODULE; err = cdev_add(&my_cdev,devno,1); if(err<0) { printk("cdev error"); goto ERROR; } /* creat device node */ ds18b20_class = class_create(THIS_MODULE,DEV_NAME); if(IS_ERR(ds18b20_class)) { printk("Err:failed in ds18b20_class/n"); goto ERROR; } device_create(ds18b20_class,NULL,devno,NULL,DEV_NAME); printk(DEV_NAME"initialized/n"); return 0;ERROR: printk("s3c %s driver version %d=dev_major,%d=dev_minor install failure",DEV_NAME,DEV_MAJOR,dev_minor); cdev_del(&my_cdev); unregister_chrdev_region(devno,1); return -1;}static void __exit s3c2440_ds18b20_remove(void){ cdev_del(&my_cdev); unregister_chrdev_region(devno,1); class_destroy(ds18b20_class); device_destroy(ds18b20_class,devno);}static struct platform_driver s3c2440_ds18b20_driver ={ .probe = s3c2440_ds18b20_probe, .remove = s3c2440_ds18b20_remove, .driver = { .name = "s3c2440_ds18b20", .owner = THIS_MODULE, },};static int __init s3c2440_ds18b20_init ( void ){ int ret = 0; ret = platform_device_register(&s3c2440_ds18b20_device); if(ret) { printk("cant not register platform__device_register"); goto fail_reg_plat_dev; } ret = platform_driver_register(&s3c2440_ds18b20_driver); if(ret) { printk("cant not register platform_driver_register"); goto fail_reg_plat_drv; } printk("initial") ; return ret;fail_reg_plat_drv: platform_driver_unregister(&s3c2440_ds18b20_driver); return -1;fail_reg_plat_dev: return ret ;}static void s3c2440_ds18b20_exit(void){ platform_driver_unregister(&s3c2440_ds18b20_driver);}module_init(s3c2440_ds18b20_init);module_exit(s3c2440_ds18b20_exit);
相应的MAKEFILE
CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gccKDIR?=/home/guanlei/fl2440/kernel/linux-3.0obj-m:=myds18b20.odefault:$(MAKE) -C $(KDIR) M=`pwd` modulesmake cleanclean:rm -f *.ko.* *.o *mod.c *.order *.symvers
相应的简单的测试程序
#include <stdio.h> #include <sys/types.h> #include <sys/ioctl.h> #include <stdlib.h> #include <termios.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/time.h> main() { int fd; unsigned char buf[2]; unsigned short temp=0; double result=0; int flag=0; if ((fd=open("/dev/ds18b20",O_RDWR | O_NDELAY | O_NOCTTY)) < 0) { printf("Open Device DS18B20 failed./r/n"); exit(1); } else { printf("Open Device DS18B20 successed./r/n"); while(1) { read(fd, buf, sizeof(buf)); printf("read data is 0x%02X-0x%02X/n",buf[1],buf[0]); temp=((unsigned short)buf[1])<<8; temp|=(unsigned short)buf[0]; // printf("no error here/n"); result=0.0625*((double)temp); printf("temperature is %4f /r/n", result); sleep(2); } close(fd); } }
新闻热点
疑难解答