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");
时间: 2024-11-09 18:42:58

Linux嵌入式学习-ds18b20驱动的相关文章

Linux嵌入式学习-烟雾传感器驱动-字符设备驱动-按键驱动

MQ-2烟雾气敏传感器模块在X210v3开发板上的驱动. 现在需要一个MQ-2烟雾气敏传感器模块的驱动.其检测烟雾超过一定的标准后,会返回一个不同的电平,和按键驱动差不多. 但是在编写驱动的时候,需要用GPH2_3号引脚.但是在内核中先ioremap地址然后配置,发现无法控制gpio,也无法进入中断. 后来发现,如果需要使用gpio,需要先申请,然后才能使用. 具体程序如下: #include <linux/module.h> #include <linux/init.h> #in

Linux嵌入式学习-远程过程调用-Binder系统

Binder系统的C程序使用示例IPC : Inter-Process Communication, 进程间通信RPC : Remote Procedure Call, 远程过程调用 这里我们直接只用android系统中已经实现好的Bindrt系统. 具体源代码在 frameworks\native\cmds\servicemanager\目录下. service_manager.c :a. binder_openb. binder_become_context_managerc. binder

Linux内核调用I2C驱动_以MPU6050为例

Linux内核调用I2C驱动_以MPU6050为例 0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于没有人打扰,有这个奢侈的大块时间,可以一个人安安静静的在教研室看看Linux内核驱动的东西.按照Linux嵌入式学习的进程,SPI驱动搞完了之后就进入到I2C驱动的学习当中,十一还算是比较顺利,I2C的Linux驱动完成了. 为了测试I2C是否好用,选择一个常用的I2C传感器,手头有个MPU6050,刚好作为I2C的

十年研发经验工程师的嵌入式学习书籍大推荐

转自:http://www.51hei.com/bbs/forum.php?mod=viewthread&tid=26458&page=1&authorid=62883 从事嵌入式研发行业十年,认为学习就是要不断的吸纳知识,在研发过程中,经常会遇到一些问题,这种发现问题并解决问题的过程就是进步. 为什么选择学习嵌入式? 嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之一,同时也是当今IT领域仅存的几个金领职位之一.当前的中国IT人才面临严重的“后继乏人”, 而且这种缺口由于培

嵌入式Linux操作系统学习规划

开发板用友善之臂的吧mini2440 连3.5寸屏500块钱的样子有好几张DVD学习光盘 这款口碑比较高 嵌入式Linux操作系统学习规划ARM+LINUX路线,主攻嵌入式Linux操作系统及其上应用软件开发目标: (1) 掌握主流嵌入式微处理器的结构与原理(初步定为arm9) (2) 必须掌握一个嵌入式操作系统 (初步定为uclinux或linux,版本待定) (3) 必须熟悉嵌入式软件开发流程并至少做一个嵌入式软件项目. 从事嵌入式软件开发的好处是: (1)目前国内外这方面的人都很稀缺.这一

嵌入式linux如何学习

俗话说万事开头难(然后中间难,最后难?),刚开始的时候,你是否根本就不知如何开始,上网查资料被一堆堆新名词搞的找不到北,去图书馆看书也是找不到方向?又是arm,又是linux,又是uboot头都大了.不知道自己究竟从哪里开始? 简单说,从arm基础知识到裸机编程,从uCOSII到linux,从linux基础的命令到shell编程,从u-boot到文件系统,最后到现在的linux驱动程序.从简单到复杂,从基础到高级基本是按照这个来的. 第一阶段:嵌入式硬件基础以及裸机程序开发 1.知识点: (1)

linux嵌入式驱动-总线设备驱动模型

一个农夫想要合理的理财,他给你未来N天的每天支出(1<=N<=100000), 并计划把这N天分成M个部分(1 <=M <=N)(每个部分的天数是连续的),要求求出这些部分里花费最和最大值最小,输出这个最大值. 100 400 300 100 500 101 400 可以这么划分(100 400) (300 100) (500) (101)(400) ,五个分组里最大值是500,这个划是最佳的了,因为在其他划分里肯定有部分是大于500的,如(100) (400 300) (100

&#183;转」linux的学习路线

原文地址:http://blog.csdn.net/u010236550/article/details/19328363 1首先 你要学习嵌入式的的有一个基础:大概如下 1. 计算机.电子.通信.自动化.微电等理工科类大3以上的大学生及已毕业的工程技术人员:(大一大二建议学习基础) 2. 有一定C.C++.Java.C#等编程程序语言基础,喜欢并有志投身于嵌入式研发事业: 3. 希望通过实际工程项目训练,成为一名有深度的嵌入式工程师,来改变现有生活状况,提高生活品质: 有了这些,才是你继续学习

与一线Linux嵌入式开发project师的对话

转:与一线Linux嵌入式开发project师的对话 陈project师一直做Linux的嵌入式开发.作为在开发一线的project师.他对非常多问题的看法可能更切合实际需求,于是,通过邮件.就嵌入式开发方面的问题,请他谈了一下自己的看法: 问:关于嵌入式开发.我们准备给同学们解说一些入门知识.从你一线开发经验来说,给我们一些建议: 陈工回答: 对于嵌入式Linux入门,假设有一定基础,可以从驱动開始:假设没有基础.我个人建议还是从应用程序開始.由于从应用程序開始是最easy的,也是 最直观的.