ds18b20驱动程序Linux,基于linux下的ds18b20驱动程序的编写

基于Linux操作系统下面的驱动程序的编写

一、所用的平台:

硬件平台:Mini2440

Size of NAND:256M

linux kernel:linux-2.6.32.2

二、编写ds18b20驱动程序所需要用到的硬件资源是操作s3c2440的引脚以及该引脚所对应的一些数据寄存器,那么该驱动程序例程是用引脚是S3C2410_GPG(0)。

三、编写驱动时首先要对编写的对象的时序要了解,那么ds18b20的时序如下:

DS18B20时序详解

初始化时序:

DS18B20的所有通信都是以由复位脉冲组成的初始化序列开始的。该初始化序列由主机发出,后跟由DS18B20发出的存在脉冲(presence

pulse)。

DS18B20发出存在脉冲,以通知主机它在总线上并且准备好操作了。

在初始化时序中,总线上的主机通过拉低单总线至少480μs来发送复位脉冲。然后总线主机释放总线并进入接收模式。总线释放后,4.7kΩ的上拉电阻把单总线上的电平拉回高电平。当DS18B20检测到上升沿后等待15到60us,然后以拉低总线60-240us的方式发出存在脉冲。

如上所述,主机将总线拉低最短480us,之后释放总线。由4.7kΩ上拉电阻将总线恢复到高电平。DS18B20检测到上升沿后等待15到60us,发出存在脉冲:拉低总线60-240us。至此,初始化和存在时序完毕。

写时序: 主机在写时隙向DS18B20写入数据,在读时隙从DS18B20读取数据。在单总线上每个时隙只传送一位数据。

有两种写时隙:写“0”时间隙和写“1”时间隙。总线主机使用写“1”时间隙向DS18B20写入逻辑1,使用写“0”时间隙向DS18B20写入逻辑0.所有的写时隙必须有最少60us的持续时间,相邻两个写时隙必须要有最少1us的恢复时间。两种写时隙都通过主机拉低总线产生。

为了产生写1时隙,在拉低总线后主机必须在15μs内释放总线。在总线被释放后,由于4.7kΩ上拉电阻将总线恢复为高电平。为了产生写0时隙,在拉低总线后主机必须继续拉低总线以满足时隙持续时间的要求(至少60μs)。

在主机产生写时隙后,DS18B20会在其后的15到60us的一个时间窗口内采样单总线。在采样的时间窗口内,如果总线为高电平,主机会向DS18B20写入1;如果总线为低电平,主机会向DS18B20写入0。

如上所述,所有的写时隙必须至少有60us的持续时间。相邻两个写时隙必须要有最少1us的恢复时间。所有的写时隙(写0和写1)都由拉低总线产生。

读时序: DS18B20只有在主机发出读时隙后才会向主机发送数据。因此,在发出读暂存器命令

[BEh]或读电源命令[B4h]后,主机必须立即产生读时隙以便DS18B20提供所需数据。另外,主机可在发出温度转换命令T

[44h]或Recall命令E 2[B8h]后产生读时隙,以便了解操作的状态。

所有的读时隙必须至少有60us的持续时间。相邻两个读时隙必须要有最少1us的恢复时间。所有的读时隙都由拉低总线,持续至少1us后再释放总线(由于上拉电阻的作用,总线恢复为高电平)产生。在主机产生读时隙后,DS18B20开始发送0或1到总线上。DS18B20让总线保持高电平的方式发送1,以拉低总线的方式表示发送0.当发送0的时候,DS18B20在读时隙的末期将会释放总线,总线将会被上拉电阻拉回高电平(也是总线空闲的状态)。DS18B20输出的数据在下降沿(下降沿产生读时隙)产生后15us后有效。因此,主机释放总线和采样总线等动作要在15μs内完成。

温度转换和读温度时序:

a4c26d1e5885305701be709a3d33442f.png

四、驱动程序:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define DS18B20_MAJOR 200

#define DEVICE_NAME "ds18b20"

#define DATA_IO S3C2410_GPG(0)

#define DATA_OUT S3C2410_GPIO_OUTPUT

#define DATA_IN S3C2410_GPIO_INPUT

#define LEVEL_HIGHT 1

#define LEVEL_LOW 0

#define

PULL_UP 1

#define PULL_NULL 0

#define index 0

int init_ds18b20(void);

unsigned char read_byte(void);

void write_byte(unsigned char data);

struct ds18b20_cdev{

struct cdev cdev;

};

struct ds18b20_cdev *ds18b20_char_dev;

int init_ds18b20(void)

{

int

get_data=0x01;

s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);

s3c2410_gpio_pullup(DATA_IO,PULL_UP);

s3c2410_gpio_setpin(DATA_IO,LEVEL_LOW);

udelay(520);

s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);

udelay(80);

s3c2410_gpio_cfgpin(DATA_IO,DATA_IN);

s3c2410_gpio_pullup(DATA_IO,PULL_NULL);

get_data=s3c2410_gpio_getpin(DATA_IO);

udelay(200);

s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);

s3c2410_gpio_pullup(DATA_IO,PULL_UP);

return

get_data;

}

void write_byte(unsigned char data)

{

unsigned

char Data,i;

Data=data;

s3c2410_gpio_pullup(DATA_IO,PULL_UP);

for(i=0;i<8;i++)

{

s3c2410_gpio_setpin(DATA_IO,LEVEL_LOW);

udelay(2);

if((Data&0x01)==0x01)

{

s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);

}

udelay(60);

Data= Data>>1;

s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);

}

}

unsigned char read_byte(void)

{

unsigned char data=0,i;

for(i=0;i<8;i++)

{

s3c2410_gpio_setpin(DATA_IO,LEVEL_LOW);

udelay(2);

s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);

udelay(20);

s3c2410_gpio_cfgpin(DATA_IO,DATA_IN);

s3c2410_gpio_pullup(DATA_IO,PULL_NULL);

if(s3c2410_gpio_getpin(DATA_IO))

{

data=data|0x80;

}

data=data>>1;

udelay(50);

s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);

s3c2410_gpio_pullup(DATA_IO,PULL_UP);

s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);

udelay(1);

}

s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);

s3c2410_gpio_pullup(DATA_IO,PULL_UP);

s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);

return data;

}

static ssize_t temper_read(struct file *filep,char __user

*buf,size_t count,loff_t *f_pos)

{

int

check;

char

result[2];

unsigned

long error;

check=

init_ds18b20();

if((check&0x01)==0x01)

{

printk("\n Warning : Fail the init ds18b20 ");

return -1; }

write_byte(0xcc);

write_byte(0x44);

udelay(500);

init_ds18b20();

write_byte(0xcc);

write_byte(0xbe);

result[0]= read_byte();

result[1]= read_byte();

error=copy_to_user(buf,result,sizeof(result));

if(!error)

{

return 0;

}

else

return min(sizeof(result),count);

}

static int ds18b20_open(struct inode *inode,struct file

*filep)

{

unsigned char flag;

flag=init_ds18b20();

if(flag)

{

printk("\n warning:Fail the init ds18b20 \n");

return -1; }

else

printk("\n open:successful");

return 0;

}

static struct file_operations ds18b20_fops={

.open=ds18b20_open,

.owner=THIS_MODULE,

.read=temper_read,

};

static void ds18b20_setup_cdev(void)

{

int error;

dev_t dev_num;

dev_num=MKDEV(DS18B20_MAJOR,index);

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

ds18b20_char_dev->cdev.owner=THIS_MODULE;

ds18b20_char_dev->cdev.ops=&ds18b20_fops;

error=cdev_add(&ds18b20_char_dev->cdev,dev_num,1);

if(error)

{

printk("error:add the ds18b20 driver \n %d,%d",error,index);

} }

static int __init ds18b20_init(void)

{

int

error;

dev_t

dev_num;

dev_num=MKDEV(DS18B20_MAJOR,index);

if(dev_num)

{

error=register_chrdev_region(dev_num,0,DEVICE_NAME);

}

else

{

error=alloc_chrdev_region(&dev_num,0,1,DEVICE_NAME);

}

if(error<0)

{

return -1;

}

ds18b20_char_dev=kmalloc(sizeof(struct

ds18b20_cdev),GFP_KERNEL);

if(!ds18b20_char_dev)

{

goto delete_error;

}

memset(ds18b20_char_dev,0,sizeof(struct ds18b20_cdev));

ds18b20_setup_cdev();

return 0;

delete_error:

unregister_chrdev_region(dev_num,1);

return error;

}

static void __exit ds18b20_exit(void)

{

dev_t

dev_num;

dev_num=MKDEV(DS18B20_MAJOR,index);

cdev_del(&ds18b20_char_dev->cdev);

kfree(ds18b20_char_dev);

unregister_chrdev_region(dev_num,1);

}

module_init(ds18b20_init);

module_exit(ds18b20_exit);

Makefile文件:

1 obj-m := ds18b20.o

2 CC = arm-linux-gcc

3 KDIR := /opt/linux-2.6.32.2

4 PWD := $(shell pwd)

5 default:

6 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

7 clean:

8 rm -rf *.o

9 rm -rf *.ko

10 rm -rf .*.cmd

11 rm -rf *.mod.*

五、上层应用程序

#include

#include

#include

#include

void udelay(unsigned int time)

{

int i,j;

for(i=0;i

{

for(j=0;j<50000;j++);

}

}

int main()

{

int fd,value=0;

float temper=0;

unsigned char flag=0;

char result[2];

fd=open("/dev/ds18b20",0);

if(fd<0)

{

printf("\n error:the fail open document");

return -1;

}

while(1)

{

read(fd,result,sizeof(result));

value=result[1];

value=(value<<8)|result[0];

if((result[1]&0xf0)==0x0f)

{

value=~value+1; flag=1;

} temper=(float)value*0.0625;

printf("\n The temper is:%f",temper);

udelay(50);

}

}

Makefile:

1 CC:= arm-linux-gcc

2

3 ds18b20_app:ds18b20_app.o

4 $(CC) -o ds18b20_app ds18b20_app.c

5

6 clean:

7 rm -rf ds18b20_*.o*~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值