数值温度传感器18b20驱动分析

来源:互联网 发布:android完整项目源码 编辑:程序博客网 时间:2024/05/12 13:18
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/cdev.h>
#include <linux/device.h>

#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>

#define DEVICE_NAME "Tem"
#define tp_MAJOR  232

unsigned char sdata;
unsigned char xiaoshu1;
unsigned char xiaoshu2;
unsigned char xiaoshu;

//初始化
void tmreset (void)
{      
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));//配置GPE0为输出
gpio_set_value(S3C64XX_GPE(0), 1);//设置GPE0为1
udelay(100);//延时100us
gpio_set_value(S3C64XX_GPE(0), 0);//设置GPE0为0
udelay(600);//延时600us
gpio_set_value(S3C64XX_GPE(0), 1);//设置GPE0为1
udelay(100);//延时100us
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(0));//配置GPE0为输入
}  
//写字节
void tmwbyte (unsigned char dat)
{                       
unsigned char j;
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));//配置GPE0为输出
for (j=1;j<=8;j++)      

gpio_set_value(S3C64XX_GPE(0), 0); //设置GPE0为0
udelay(1); //延迟1us
if((dat&0x01)==1)
{
gpio_set_value(S3C64XX_GPE(0), 1);//设置GPE0为1 
}  
udelay(60);//延迟60us
gpio_set_value(S3C64XX_GPE(0), 1);//设置GPE0为1
udelay(15);//延迟15us
dat = dat >> 1;
}  
gpio_set_value(S3C64XX_GPE(0), 1);//设置GPE0为1

//读字节
unsigned char tmrbyte (void)
{   
unsigned char i,u=0;      

for (i=1;i<=8;i++)      
{
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(1));//设置GPE0为输出
gpio_set_value(S3C64XX_GPE(0), 0); //设置GPE0为0
udelay(1);//延迟1us
u >>= 1; 
gpio_set_value(S3C64XX_GPE(0), 1);//设置GPE为1
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C_GPIO_SFN(0));//设置GPE0为输入 
if( gpio_get_value(S3C64XX_GPE(0))) //读取GPE0值
u=u|0x80;
udelay(60);  //延迟60us
}  
return (u);   
}

void DS18B20PRO(void)         
{    
unsigned char a,b; 
tmreset();//输出话         
udelay(420);//延时420us
tmwbyte(0xcc);//0xcc跳过ROM        
tmwbyte(0x44);//0x44温度变换      
mdelay(750);//延时750ms
tmreset ();//初始化    
udelay(400);//延迟400us
tmwbyte (0xcc); //0xcc跳过ROM  
tmwbyte (0xbe);//0xbe读暂存存储器  
a = tmrbyte ();
b= tmrbyte ();
sdata = a/16+b*16;   
}
//读方法
static ssize_t  s3c6410_18b20_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
DS18B20PRO();
*buf=sdata;
return 1;
}
//设备文件的操作函数集合
static struct file_operations s3c6410_18b20_fops = {
.owner = THIS_MODULE,
.read =s3c6410_18b20_read,
};
//定义字符设备结构
static struct cdev cdev_18b20;
//驱动加载函数
static int __init s3c6410_18b20_init(void)
{
int result;
dev_t devno = MKDEV(tp_MAJOR,0);
struct class *tem_class;
//申请设备号
result = register_chrdev_region(devno,1,DEVICE_NAME);
if(result)
{
printk(KERN_NOTICE "Error %d register 18b20",result);
return result;
}
//初始化cdev结构体
  cdev_init(&cdev_18b20,&s3c6410_18b20_fops);
//添加cdev结构体
result = cdev_add(&cdev_18b20,devno,1);
if(result)
{
printk(KERN_NOTICE "Error %d adding 18b20",result);
return result;
}
//在/sys/class/目录下创建一个名为tem_class的类
tem_class = class_create(THIS_MODULE, "tem_class");
//在/dev下创建设备节点
device_create(tem_class, NULL, MKDEV(tp_MAJOR, 0), "ds18b20","tem%d", 0);

return 0;
}
//驱动卸载函数
static void __exit s3c6410_18b20_exit(void)
{
//删除cdev
cdev_del(&cdev_18b20);
//释放设备号
unregister_chrdev_region(MKDEV(tp_MAJOR,0),1);
}

module_init(s3c6410_18b20_init);
module_exit(s3c6410_18b20_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("FORLINX Inc.");
0 0
原创粉丝点击