您的位置:首页 > 运维架构 > Linux

s3c2410的ds18b20驱动(基于linux-2.6.24.4内核)

2009-03-31 14:00 501 查看
/*包含了这么多的头文件,也不知道有的有没有用*/

#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/clk.h>

#include <asm-arm/arch-s3c2410/regs-gpio.h>
#include <asm/io.h>
#include <asm/arch/map.h>
#include <asm-arm/plat-s3c24xx/clock.h>
#include <asm/arch/regs-clock.h>


/*和引脚相关的宏定义*/
#define DQ S3C2410_GPH9
#define CFG_IN S3C2410_GPH9_INP
#define CFG_OUT S3C2410_GPH9_OUTP

static int opencount = 0;

unsigned char init_ds(void)//ds18b20复位,返回0成功,返回1失败
{
unsigned char ret = 0;

s3c2410_gpio_cfgpin(DQ, CFG_OUT);
s3c2410_gpio_pullup(DQ, 0);

s3c2410_gpio_setpin(DQ, 1);
s3c2410_gpio_setpin(DQ, 0);
udelay(500);

s3c2410_gpio_setpin(DQ, 1);
udelay(50);

s3c2410_gpio_cfgpin(DQ, CFG_IN);
udelay(200);
ret = s3c2410_gpio_getpin(DQ);

s3c2410_gpio_cfgpin(DQ, CFG_OUT);
s3c2410_gpio_pullup(DQ, 0);
s3c2410_gpio_setpin(DQ, 1);

return ret;
}

void write_byte(char data)//向18b20写一个字节
{
char i = 0;

s3c2410_gpio_cfgpin(DQ, CFG_OUT);
s3c2410_gpio_pullup(DQ, 1);

for(i=0; i<8; i++){
s3c2410_gpio_setpin(DQ, 0);
udelay(10);
s3c2410_gpio_setpin(DQ, 1);
s3c2410_gpio_setpin(DQ, data&0x01);
udelay(60);
s3c2410_gpio_setpin(DQ, 1);
udelay(2);
data >>= 1;
}
}

unsigned char read_byte(void)//从18b20读一个字节
{
unsigned char i;
unsigned char data=0;

s3c2410_gpio_cfgpin(DQ, CFG_OUT);
s3c2410_gpio_pullup(DQ, 0);

for(i=0; i<8; i++)
{
s3c2410_gpio_setpin(DQ, 0);
udelay(1);
s3c2410_gpio_setpin(DQ, 1);

s3c2410_gpio_cfgpin(DQ, CFG_IN);

udelay(10);

data >>= 1;
if(s3c2410_gpio_getpin(DQ))
data |= 0x80;

udelay(50);
s3c2410_gpio_cfgpin(DQ, CFG_OUT);
s3c2410_gpio_pullup(DQ, 0);
s3c2410_gpio_setpin(DQ, 1);
udelay(2);
}
return data;
}

/*文件的写函数,没有实际意义,用户不能写文件*/
static ssize_t ds18b20_write(struct file *filp, const char *buffer,
size_t count, loff_t *ppos)
{
return 10;//随便返回一个正整数
}
/*18b20的读函数,读出的温度只保留了整数*/
static ssize_t ds18b20_read(struct file *filp, char *buffer,
size_t count, loff_t *ppos)
{
unsigned char a=0, b=0;
unsigned int t=0;
unsigned char temp=0;
unsigned char flag;

flag = init_ds();
if(flag&0x01)
return -1;

write_byte(0x0cc);
write_byte(0x44);

udelay(500);

flag = init_ds();
if(flag&0x01)
return -1;

write_byte(0x0cc);
write_byte(0x0be);

a = read_byte();
b = read_byte();

flag = init_ds();

temp = ((b & 0x7) << 4)) | (a >> 4);
copy_to_user(buffer, &temp, 1);
return 1;
}

static int ds18b20_open(struct inode *node, struct file *file)
{
unsigned char flag;

if(opencount == 1)
return -EBUSY;

flag = init_ds();

if(flag&0x01)
{
printk("uable to open device!/n");
return -1;
}
else
{
opencount++;
printk("device opened!/n");
return 0;
}
}

static int ds18b20_release(struct inode *node, struct file *file)
{
opencount--;
printk("device released!/n");
return 0;
}

static struct file_operations ds18b20_fops = {
.owner = THIS_MODULE,
.write = ds18b20_write,
.read = ds18b20_read,
.release = ds18b20_release,
.open = ds18b20_open,
};

static int ds18b20_probe(struct platform_device *pdev)
{
int ret;

s3c2410_gpio_cfgpin(DQ, CFG_OUT);
s3c2410_gpio_setpin(DQ, 0);
ret = register_chrdev(0, "ds18b20", &ds18b20_fops);
if(!ret)
printk("--------------Uable to register driver!-------------------/n");

printk("Probe for ds18b20 finished!/n");
return 0;
}

static struct platform_driver ds18b20 =
{
.probe = ds18b20_probe,
.driver = {
.name = "s3c2410-ds",
.owner = THIS_MODULE,
},
};

int __init ds18b20_init(void)
{
printk("Initial driver for ds18b20....................../n");
return platform_driver_register(&ds18b20);
}

void __exit ds18b20_exit(void)
{
return platform_driver_unregister(&ds18b20);
}

module_init(ds18b20_init);
module_exit(ds18b20_exit);

MODULE_AUTHOR("yanqiang-liu@163.com");
MODULE_DESCRIPTION("DS18B20 driver for s3c2410");
MODULE_LICENSE("GPL");
目前能正确读出温度,还没仔细测试过,不知道有没有bug。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: