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\n");



    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");

 

posted @ 2017-03-08 14:40  叶念西风  阅读(1512)  评论(0编辑  收藏  举报
叶念西风 - 个人博客 & 电脑Run - 维修帮助软件教程安装