ds18b20驱动程序Linux,DS18B20 driver for Linux

驱动源码 #include #include #include #include #include #include #include #include #include #include

#include #include #include #include #include #include

/* 引脚相关定义 */

#define DQ S3C2410_GPF(0)

#define DQ_OUTP

S3C2410_GPIO_OUTPUT

#define DQ_INP S3C2410_GPIO_INPUT

/* 设置DQ引脚为输出 */

#define DQ_OUT s3c2410_gpio_cfgpin(DQ,DQ_OUTP)

/*

设置DQ引脚为输入 */

#define DQ_IN s3c2410_gpio_cfgpin(DQ,DQ_INP)

/* 打开上拉电阻

*/

#define DQ_UP s3c2410_gpio_pullup(DQ,1)

/* 读取DQ状态 */

#define DQ_STA

s3c2410_gpio_getpin(DQ)

/* 拉低DQ */

#define DQ_L

s3c2410_gpio_setpin(DQ,0)

/* 拉高DQ */

#define DQ_H

s3c2410_gpio_setpin(DQ,1)

/* 设备名称 */

#define DEV_NEME “ds18b20”

struct ds18b20_dev{

dev_t devno; //设备号

int major; //主设备号

char *data;

//缓冲区

struct cdev cdev; //内嵌字符设备结构

};

struct ds18b20_dev *ds18b20_device;

/* 初始化DQ18B20,返回0表示初始化成功1表示失败 */

unsigned int init_ds18b20(void)

{

unsigned int dat = 0;

DQ_OUT;

DQ_H; //复位DQ

udelay(10);

DQ_L; //拉低DQ,发出reset脉冲

udelay(600);

DQ_H;

udelay(65);

DQ_IN; //设置DQ为输入,准备读取presence脉冲

dat = DQ_STA; //读取DQ状态,dat=0表示初始化成功,dat=1

表示失败

udelay(50);

DQ_OUT;

DQ_H; //复位DQ

udelay(50);

return dat;

}

/* Write a char */

void write_char(unsigned char dat)

{ unsigned int i

= 0;

DQ_OUT;

for(i=8;i>0;i–){

DQ_L; //拉低DQ,开始写时序

udelay(10);

if(dat&0x01)

DQ_H; //拉高DQ,写1

else

DQ_L;

//拉低DQ,写0

udelay(60);

DQ_H; //复位DQ

udelay(10);

dat

>>=1;

}

}

/* Read a char */

unsigned char read_char(void)

{ unsigned int i=

0;

unsigned char dat =

0;

for(i=8;i>0;i–){

DQ_OUT;

DQ_L;

udelay(2);

dat >>=1;

DQ_H;

udelay(2);

DQ_IN;

udelay(10);

if(DQ_STA)

dat

|=0x80;

udelay(60);

}

return dat;

}

/* Read temperature */

int read_temperature(void)

{ unsigned int msb

=0;

unsigned int lsb =0;

if(init_ds18b20()){

printk(KERN_WARNING “DS18B20:init_ds18b20

failed1”);

return -1;

}

write_char(0xCC);

//跳过读取ROM

write_char(0x44); //开始温度转换

/* 此处必须有一个较长的延时,等待温度转换完成

* 不然可能读出默认值1360 */

msleep_interruptible(900);

//此处延时较长,应该改用非忙等待。 感谢aimybee提醒~

if(init_ds18b20()){

printk(KERN_WARNING

“DS18B20:init_ds18b20 failed2”);

return -1;

}

write_char(0xCC);

//跳过读取ROM

write_char(0xBE); //读取寄存器

lsb = read_char();

//前两个寄存器的值分别为温度的低位和高位

msb = read_char();

msb <<=8;

return msb+lsb;

}

int ds18b20_open(struct inode *inode,struct file *filp)

{ DQ_UP;

//打开上拉电阻

DQ_OUT;

return 0;

}

ssize_t ds18b20_read(struct file *filp,char __user *buf ,size_t count ,

loff_t *f_pos)

{ int temperature;

temperature =

read_temperature();

sprintf(ds18b20_device->data,”%dn”,temperature);

if(temperature < 0){

printk(KERN_WARNING “DS18B20:Read temperature

failed!”);

return

-EFAULT;

}

if(copy_to_user(buf,ds18b20_device->data,sizeof(ds18b20_device->data))){

return

-EFAULT;

}

return sizeof(ds18b20_device->data);

}

struct file_operations ds18b20_fops = {

.owner = THIS_MODULE,

.read =

ds18b20_read,

.open = ds18b20_open,

};

int __init init_module(void)

{ int result,err;

/* 初始化ds18b20_device 结构体

*/

ds18b20_device = kmalloc(sizeof(struct

ds18b20_dev),GFP_KERNEL);

if(!ds18b20_device){

result = -ENOMEM;

goto

fail_malloc_device;

}

memset(ds18b20_device,0,sizeof(struct

ds18b20_dev));

cdev_init(&ds18b20_device->cdev,&ds18b20_fops);

ds18b20_device->cdev.owner

= THIS_MODULE;

/* 分配设备号 */

result =

alloc_chrdev_region(&ds18b20_device->devno,0,1,DEV_NEME);

ds18b20_device->major

= MAJOR(ds18b20_device->devno);

if(result <0 ){

printk(KERN_WARNING

“DS18b20:cat’t get major %d”,ds18b20_device->major);

return

result;

}

printk(KERN_INFO “DS18b20:major = %d

“,ds18b20_device->major);

/* 分配缓冲区 */

ds18b20_device->data =

kmalloc(20,GFP_KERNEL);

if(!ds18b20_device->data){

result =

-ENOMEM;

goto

fail_malloc_data;

}

memset(ds18b20_device->data,0,20);

err =

cdev_add(&ds18b20_device->cdev,ds18b20_device->devno,1);

if(err)

printk(KERN_WARNING

“DS18b20:Error %d adding ds18b20”,err);

printk(KERN_INFO “DS18b20:init_module”);

return result;

fail_malloc_data:

kfree(ds18b20_device->data);

fail_malloc_device:

unregister_chrdev_region(ds18b20_device->devno,1);

kfree(ds18b20_device);

return

result;

}

void __exit cleanup_module(void)

{

unregister_chrdev_region(ds18b20_device->devno,1);

kfree(ds18b20_device->data);

kfree(ds18b20_device);

printk(KERN_INFO

“DS18b20:cleanup_module”);

}

module_init(init_module);

module_exit(cleanup_module);

MODULE_AUTHOR(“Issac”);

MODULE_LICENSE(“GPL”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值