• Linux嵌入式学习-ds18b20驱动


    ds18b20的时序图如下:

    复位时序:

    读写时序:

    以下是程序代码:

    #include <linux/module.h>
    
    #include <linux/init.h>
    
    #include <linux/miscdevice.h>
    
    #include <linux/interrupt.h>
    
    #include <linux/io.h>
    
    #include <linux/fs.h>
    
    #include <linux/slab.h>
    
    #include <asm/irq.h>
    
    #include <linux/random.h>
    
    #include <linux/uaccess.h>
    
    #include <linux/device.h>
    
    #include <linux/delay.h>
    
    #include <mach/gpio.h>
    
    #include <linux/mutex.h>
    
    
    
    
    
    #define GPH3_0CON 0xE0200C60
    
    #define GPH3_0DAT 0xE0200C64
    
    #define GPH3_0PUD 0xE0200C68
    
    
    
    unsigned int *gpio_config;
    
    unsigned char *gpio_data;
    
    unsigned int *gpio_pud;
    
    
    
    static struct class *fog_class;     //´´½¨Àà
    
    static struct class_device *fog_class_devs;   //´´½¨Àà¶ÔÓ¦µÄÉ豸
    
    
    
    int major;
    
    
    
    struct mutex res_mutex;
    
    
    
    void Ds18b20_Pin_Init(void)
    
    {
    
        unsigned int pin_val;
    
    
    
        gpio_request(S5PV210_GPH3(0),"my_ds1802");
    
        gpio_config = ioremap(GPH3_0CON,4);
    
        gpio_data = ioremap(GPH3_0DAT,1);
    
        gpio_pud = ioremap(GPH3_0PUD,2);
    
    
    
        pin_val = readl(gpio_pud);
    
        pin_val &=~(0x0003);
    
        pin_val |= 0x2;
    
        writel(pin_val,gpio_pud);
    
    
    
        pin_val = readl(gpio_data);
    
        writel(pin_val|0x1,gpio_data);
    
    
    
    }
    
    
    
    void DS18B20_OUT( unsigned char value)
    
    {
    
    
    
        if( value == 1)
    
        {
    
            gpio_direction_output( S5PV210_GPH3(0), 1);
    
        }
    
        else
    
        {
    
            gpio_direction_output( S5PV210_GPH3(0), 0);
    
        }
    
    }
    
    unsigned char DS18B20_IN( void )
    
    {
    
        unsigned int pin_val;
    
    
    
        gpio_direction_input( S5PV210_GPH3(0));
    
        pin_val = readl(gpio_data);
    
        return pin_val&0x1;
    
    }
    
    
    
    
    
    
    
    static void Init_DS18B20(void)
    
    {
    
       gpio_direction_output( S5PV210_GPH3(0), 1);
    
        udelay(200);
    
        gpio_direction_output( S5PV210_GPH3(0), 0);
    
        udelay(600);
    
        gpio_direction_output( S5PV210_GPH3(0), 1);
    
        udelay(480);
    
    
    
    }
    
    
    
    static void WriteCode(unsigned char dat)
    
    {
    
        unsigned char temp,i;
    
    
    
        for(i=0;i<8;i++)
    
        {
    
            temp = dat&0x01;
    
            gpio_direction_output( S5PV210_GPH3(0), 1);
    
            udelay(2);
    
            gpio_direction_output( S5PV210_GPH3(0), 0);
    
    
    
            if(temp == 0x01)
    
            {
    
                udelay(2);
    
                gpio_direction_output( S5PV210_GPH3(0), 1);
    
                udelay(100);
    
            }else{
    
                udelay(100);
    
                gpio_direction_output( S5PV210_GPH3(0), 1);
    
                udelay(3);
    
            }
    
            dat = dat>>1;
    
        }
    
    }
    
    
    
    static void Reset_DS18B20( void )
    
    {
    
        gpio_direction_output( S5PV210_GPH3(0), 0);
    
        udelay(500);
    
        gpio_direction_output( S5PV210_GPH3(0), 1);
    
        udelay(480);
    
    }
    
    
    
    static unsigned int ReadData(void)
    
    {
    
        unsigned int rec,data,i;
    
        data = 0;
    
    
    
        for(i=0;i<16;i++)
    
        {
    
            gpio_direction_output( S5PV210_GPH3(0), 0);
    
            udelay(5);
    
    
    
            udelay(3);
    
            rec = DS18B20_IN();
    
                udelay(20);
    
            if(rec){
    
            data |= 0x8000;
    
            }else{
    
            data &= 0x7fff;
    
            }
    
            if(i<15)
    
            data >>=1;
    
            udelay(20);
    
    
    
            gpio_direction_output( S5PV210_GPH3(0), 1);
    
            udelay(5);
    
        }
    
        return (data);
    
    }
    
    
    
    int ds18b20_open(struct inode *node, struct file *filp)
    
    {
    
        return 0;
    
    }
    
    
    
    static int ds18b20_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
    
    {
    
        int tem;
    
        int ds_value;
    
    
    
        mutex_lock_interruptible(&res_mutex);
    
    
    
        Ds18b20_Pin_Init();
    
    
    
        Init_DS18B20();
    
        WriteCode(0xcc);
    
        WriteCode(0x44);
    
        gpio_direction_input( S5PV210_GPH3(0));
    
        udelay(100);
    
        tem = DS18B20_IN();
    
        if(tem)
    
        {
    
            gpio_direction_output( S5PV210_GPH3(0), 1);
    
            Reset_DS18B20();
    
            WriteCode(0xcc);
    
            WriteCode(0xbe);
    
            ds_value = ReadData();
    
        }else{
    
            udelay(50);
    
            ds_value = 0xaaaa;
    
        }
    
        mutex_unlock(&res_mutex);
    
    
    
        copy_to_user(buffer, &ds_value, 4);
    
    
    
        return sizeof ds_value;
    
    }
    
    
    
    static struct file_operations ds18b20_fops =
    
    {
    
        .open = ds18b20_open,
    
        .read = ds18b20_read,
    
    };
    
    
    
    
    
    static int Ds18b20_init(void)
    
    {
    
    
    
        major = register_chrdev( 0,"ds18b20_drv", &ds18b20_fops );
    
        fog_class = class_create(THIS_MODULE,"ds18b20_class");
    
        fog_class_devs = device_create(fog_class,NULL,MKDEV(major,0),NULL,"my_ds1802");
    
    
    
        mutex_init(&res_mutex);
    
    
    
        printk("install module successed
    ");
    
    
    
        return 0;
    
    }
    
    
    
    
    
    void Ds18b20_exit(void)
    
    {
    
        unregister_chrdev( major, "ds18b20_drv" );
    
        device_unregister(fog_class_devs);
    
        class_destroy(fog_class);
    
    }
    
    
    
    
    
    module_init(Ds18b20_init);
    
    module_exit(Ds18b20_exit);
    
    
    
    
    
    MODULE_LICENSE("GPL");
  • 相关阅读:
    JCL: What is EXCP
    百分比布局的使用
    使用TabLayout快速实现一个导航栏
    彻底理解android中的内部存储与外部存储
    Eclipse的LogCat总是自动清空怎么办?
    怎么给Unity写一个原生的插件
    一句话、一张图记住Activity和Fragment之间错综复杂的生命周期关系
    2015年工作中遇到的问题:131-140(有图才有真相)
    2015年工作中遇到的问题:131-140(有图才有真相)
    雷观(二十四):谈谈我对国家事务“二胎”和“教育”的一些看法
  • 原文地址:https://www.cnblogs.com/ynxf/p/6519384.html
Copyright © 2020-2023  润新知