首页 > 学院 > 开发设计 > 正文

嵌入式采集温度DS18B20-platform驱动

2019-11-08 18:43:28
字体:
来源:转载
供稿:网友

我用的是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);       }   } 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表