AM3354增加DS18B20

kernel里面集成了1-wire(单总线驱动了),只需要的在平台配置文件中配置即可,不管是设备树还是平台外设的头文件。

1、在board-am335xevm.c文件中增加W1-GPIO的头文件。

#include <linux/w1-gpio.h>

2、配置W1-GPIO所使用的管脚

/* add w1-gpio */

static void w1_enable_external_pullup(int enable)
{
  gpio_set_value(GPIO_TO_PIN(1, 27), enable);
}

static struct w1_gpio_platform_data w1_gpio_pdata = {
  .pin = GPIO_TO_PIN(1, 27),
  .is_open_drain= 0, 
  //.enable_external_pullup = w1_enable_external_pullup,
};

static struct platform_device w1_device = {
  .name = "w1-gpio",
  .id = -1,
  .dev.platform_data= &w1_gpio_pdata,
};

/*
static struct pinmux_config w1_gpio_pin_mux[] = {
  {"gpmc_a11.gpio1_27", OMAP_MUX_MODE7 },//| AM33XX_PIN_OUTPUT},
  {NULL, 0},
};
*/

static void w1_init(int evm_id, int profile )
{
  int err;
  //setup_pin_mux(w1_gpio_pin_mux);//我配置了这个管脚一直没有办法读取管脚状态

  err = platform_device_register(&w1_device);
  if (err)
    pr_err("failed to register w1-gpio\n");
  else
    pr_info("w1-gpio connected to GPIO1_27\n");
}


3、在make menuconfig中配置

支持w1-gpio和ds18b20驱动:
Device Drivers  ---> 
  <*> Dallas's 1-wire support  --->
    --- Dallas's 1-wire support
      1-wire Bus Masters  ---> 
          <*> GPIO 1-wire busmaster
      1-wire Slaves  --->
          <*> Thermal family implementation

这是重新编译新内核并烧写重启。
/nfsswap # cd /sys/devices/w1_bus_master1/
/sys/devices/w1_bus_master1 # ls
28-0316423ecfff            w1_master_name
driver                     w1_master_pointer
power                      w1_master_pullup
subsystem                  w1_master_remove
uevent                     w1_master_search
w1_master_add              w1_master_slave_count
w1_master_attempts         w1_master_slaves
w1_master_max_slave_count  w1_master_timeout
/sys/devices/w1_bus_master1 # cd 28-0316423ecfff/
/sys/devices/w1_bus_master1/28-0316423ecfff # ls
driver     id         name       power      subsystem  uevent     w1_slave
/sys/devices/w1_bus_master1/28-0316423ecfff # cat w1_slave 
e2 01 4b 46 7f ff 0c 10 00 : crc=00 YES
e2 01 4b 46 7f ff 0c 10 00 t=30125
/sys/devices/w1_bus_master1/28-0316423ecfff # cat w1_slave 
e2 01 4b 46 7f ff 0c 10 00 : crc=00 YES
e2 01 4b 46 7f ff 0c 10 00 t=30125
/sys/devices/w1_bus_master1/28-0316423ecfff # cat w1_slave 
e1 01 4b 46 7f ff 0c 10 c5 : crc=c5 YES
e1 01 4b 46 7f ff 0c 10 c5 t=30062
/sys/devices/w1_bus_master1/28-0316423ecfff # cat w1_slave 
e1 01 4b 46 7f ff 0c 10 c5 : crc=c5 YES
e1 01 4b 46 7f ff 0c 10 c5 t=30062
/sys/devices/w1_bus_master1/28-0316423ecfff # 
/sys/devices/w1_bus_master1/28-0316423ecfff # cd /sys/bus/w1/
/sys/bus/w1 # ls
devices            drivers_autoprobe  uevent
drivers            drivers_probe
/sys/bus/w1 # cd devices/
/sys/bus/w1/devices # ls
28-0316423ecfff  w1_bus_master1
/sys/bus/w1/devices # cd 28-0316423ecfff/
/sys/devices/w1_bus_master1/28-0316423ecfff # ls
driver     id         name       power      subsystem  uevent     w1_slave
/sys/devices/w1_bus_master1/28-0316423ecfff # cat w1_slave 
de 01 4b 46 7f ff 0c 10 c3 : crc=c3 YES
de 01 4b 46 7f ff 0c 10 c3 t=29875
/sys/devices/w1_bus_master1/28-0316423ecfff # cat w1_slave 
de 01 4b 46 7f ff 0c 10 c3 : crc=c3 YES
de 01 4b 46 7f ff 0c 10 c3 t=29875
/sys/devices/w1_bus_master1/28-0316423ecfff # 




另外一种是注册成一个char字符设备:

驱动源代码:

/*********************************************************************************
 *      Copyright:  (C) 2015 songyong<handy_skyoutlook.com>
 *                  All rights reserved.
 *
 *       Filename:  ds18b20drv.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2017年06月22日)
 *        changer:  zue
 *      ChangeLog:  1, Release initial version on "2017年06月22日"
 *                 
 ********************************************************************************/
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/init.h>
#include<linux/delay.h>
#include<linux/gpio.h>
#include<linux/types.h>
#include<asm/irq.h>
#include<linux/device.h>
#include<linux/kdev_t.h>
#include<linux/cdev.h>
#include<linux/errno.h>
#include<asm/uaccess.h>
#include <linux/gpio.h>
#include <linux/phy.h>
#include <linux/gpio.h>



#define D_MAJOR 0
#define D_MINOR 0
#define DEV_NAME "ds18b20"



static int ds18b20_major = D_MAJOR;
static int ds18b20_minor = D_MINOR;


/* Convert GPIO signal to GPIO pin number */
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

#define W1GPIO GPIO_TO_PIN(1,27)

struct ds18b20_device
{
    struct class    *sy_class;
    struct cdev     cdev;
};
static struct ds18b20_device   dev;//若使用指针,记得给指针开辟空间。

static unsigned int ds18b20_reset(void)
{
    int err;

	gpio_direction_output(W1GPIO,0);

	gpio_set_value(W1GPIO,1);
    udelay(10);
	gpio_set_value(W1GPIO,0);
    udelay(600);

	gpio_set_value(W1GPIO,1);
    udelay(60);

	gpio_direction_input(W1GPIO);
    udelay(400);
	err = gpio_get_value(W1GPIO);
    //err = s3c2410_gpio_getpin(DQ);
    return err;
}

static unsigned int ds18b20_write(unsigned char data)
{
    unsigned int i;
	gpio_direction_output(W1GPIO,0);
    for (i = 0; i < 8; i++)   //只能一位一位的读写
    {
		gpio_set_value(W1GPIO,0);
        udelay(5);
        if(data & 0x01)
        {
			gpio_set_value(W1GPIO,1);
            udelay(60);
        }
        else udelay(60);
        data >>= 1;     //从最低位开始判断;每比较完一次便把数据向右移,获得新的最低位状态
		gpio_set_value(W1GPIO,1);
        udelay(1);
    }
    return 2;
}

static unsigned int ds18b20_read(void)
{
    unsigned int i ;
    unsigned char data = 0x00;

    for (i =0; i < 8 ; i++)
    {
		gpio_direction_output(W1GPIO,1);
		gpio_set_value(W1GPIO,1);
        udelay(1);
		gpio_set_value(W1GPIO,0);
        udelay(2);
		gpio_set_value(W1GPIO,1);
		gpio_direction_input(W1GPIO);
        data >>= 1;
        if(0 != gpio_get_value(W1GPIO))//s3c2410_gpio_getpin(DQ))
            data |= 0x80;   //最低位数据从data的最高位放起,边放边右移直到读取位完毕。
        udelay(60);
    }
    return data;
}

static ssize_t read_ds18b20(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    unsigned char Data[2] = {0x00, 0x00};
    unsigned long err; 
    int flag;

    flag = ds18b20_reset();
    if(flag <= 0)
    {
        printk("ds18b20 init fail!\n");
        return -1;
    }

    ds18b20_write(0xcc);
    ds18b20_write(0x44);

    ds18b20_reset();
    if(flag <= 0)
    {
        printk("ds18b20 init fail!\n");
        return -1;
    }

    ds18b20_write(0xcc);
    ds18b20_write(0xbe);

    Data[0] = ds18b20_read();
    Data[1] = ds18b20_read();
    ds18b20_reset();
    err = copy_to_user(buf, Data, sizeof(Data));
    return err? -EFAULT:count;
}
#if 1 

static int open_ds18b20(struct inode *inode, struct file *filp)
{
    int flag = 0;

    flag = ds18b20_reset();
    if(flag)
    {
        printk("open ds18b20 successful!\n");
    }
    else printk("open ds18b20 failed!\n");

    return 0;
}
#endif

static int release_ds18b20(struct inode *inode, struct file *filp)
{
    return 0;
}

static struct file_operations fops={
    .owner  = THIS_MODULE,
    .read   = read_ds18b20,
    .open   = open_ds18b20,
    .release = release_ds18b20,
};

static int __init ds18b20_init(void)
{
    int result,err;
    dev_t devno = 0;
	int ret=0;

    if(ds18b20_major)
    {
        devno = MKDEV(ds18b20_major, ds18b20_minor);
        result = register_chrdev_region(devno, 1, DEV_NAME);
    }
    else{
        result = alloc_chrdev_region(&devno, ds18b20_minor, 1, DEV_NAME);
        ds18b20_major = MAJOR(devno);
    }
    if(result < 0)
    {
        printk(KERN_ERR "%s can't use major %d\n",DEV_NAME, ds18b20_major);
    }
    printk("%s use major %d\n",DEV_NAME, ds18b20_major);

    cdev_init(&dev.cdev,&fops);
    dev.cdev.owner = THIS_MODULE;
    err = cdev_add(&dev.cdev, devno, 1);
    if(err)
    {
        printk(KERN_NOTICE"ERROR %d add ds18b20\n",err);
        goto ERROR;
    }
    dev.sy_class   = class_create(THIS_MODULE, DEV_NAME);
    device_create(dev.sy_class, NULL, MKDEV(ds18b20_major, ds18b20_minor), NULL, DEV_NAME);
    printk(KERN_NOTICE"Ds18b20 is ok!\n");

	ret = gpio_request(W1GPIO,"gpio1_27");
        
	if (ret < 0)
		pr_warning("w1-gpio Unable to request GPIO_W1_PULLUP_ENABLE\n");

    return 0;
ERROR:
    printk(KERN_ERR"%s driver installed failure.\n",DEV_NAME);
    cdev_del(&dev.cdev);
    unregister_chrdev_region(devno, 1);
    return err;

}
static void __exit ds18b20_exit(void)
{
    dev_t devno = MKDEV(ds18b20_major, 0);

    cdev_del(&dev.cdev);
    device_destroy(dev.sy_class,devno);
    class_destroy(dev.sy_class);

    unregister_chrdev_region(devno, 1);
    printk(KERN_NOTICE"bye ds18b20!\n");
}

module_init(ds18b20_init);
module_exit(ds18b20_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zue");


测试程序:

/*********************************************************************************
 *      Copyright:  (C) 2015 songyong<handy_skyoutlook.com>
 *                  All rights reserved.
 *
 *       Filename:  ds18b20drv.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2017年06月22日)
 *        changer:  zue
 *      ChangeLog:  1, Release initial version on "2017年06月22日"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/********************************************************************************
 *  Description:
 *   Input Args:
 *  Output Args:
 * Return Value:
 ********************************************************************************/

int main (int argc, char **argv)
{
    int fd;
    int i = 0;
    int data = 0;
    unsigned char result[2];
    float temperature = 0;

    printf("will open fd... \n");
    if((fd = open("/dev/ds18b20",O_RDWR|O_NONBLOCK)) < 0 )
    {
        perror("open device fail.\n");
        return -1;
    }
    else printf("Open Device Ds18b20 Successful!!\n");

    while(1)
    {
        int ret;

        printf("\nWill read temperature...\n");
        usleep(100);
        ret = read(fd, result, sizeof(result));
        if(ret != 2)
        {
            printf("read wrong\n");
            exit(0);
        }
        else printf("read success !\n");

        data = (int)result[1]; 
        data <<=8;
        data = data | result[0];
        temperature =data * 0.0625 ;
        printf("Temperature = %.2f ℃\n",temperature);
        fflush(stdout);
        sleep(1);
    }
    close(fd);
    return 0;
} /* ----- End of main() ----- */




/nfsswap # insmod DS18B20drv.ko 
[  316.888937] ds18b20 use major 250
[  316.893126] Ds18b20 is ok!
/nfsswap # 
/nfsswap # 
/nfsswap # ./DS18B20ts 
will open fd... [  321.254457] open ds18b20 successful!


Open Device Ds18b20 Successful!!


Will read temperature...
read success !
Temperature = 29.88 ℃


Will read temperature...
read success !
Temperature = 29.81 ℃


Will read temperature...
read success !
Temperature = 29.81 ℃


Will read temperature...
read success !
Temperature = 29.81 ℃


Will read temperature...
read success !
Temperature = 29.81 ℃


Will read temperature...
read success !
Temperature = 29.81 ℃


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值