搜索
bottom↓
回复: 14

发个我刚写好的 DS18B20 linux 2.4驱动 (目标板 S3C2440)

[复制链接]

出0入0汤圆

发表于 2009-12-27 15:36:25 | 显示全部楼层 |阅读模式
刚开始学linux驱动,摸索了好多天,刚开始GPIO口不知道怎么驱动,上网找了无数资料,测试了无数遍才搞定,希望对刚学linux 驱动的朋友有些帮助!

文件名:DS18B20.c 用途linux 驱动程序
//-------DS18B20.c文件开始-------------------
//Design by 001friend (2009.12.27)
//DS18B20 Drive for linux2.4.20 (target: S3C2440)
//1-wire bus interface drive via GPG7

#ifndef _KERNEL_
        #define _KERNEL_
#endif
#ifndef MODULE
        #define MODULE
#endif

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/version.h>
#include <asm/arch-s3c2440/S3C2440.h>
#include <asm/uaccess.h>
#include <linux/delay.h>
#include <linux/unistd.h>
#include <stdio.h>
#include <math.h>
#include <float.h>

#define MAJOR_NUM 98 //主设备号

//*************DS18B20 operation begin********
#define        dat_1820_hign        GPGDAT|=1<<7;GPGCON&=~(3<<14)

#define        dat_1820_low        GPGDAT&=~(1<<7);GPGCON=(GPGCON&(~(3<<14)))|(1<<14)


//18B20 reset

unsigned char DS18B20_Reset(void)

{

        unsigned char dr=0;

        dat_1820_low;

        udelay(600);                //delay 600uS

        dat_1820_hign;

        udelay(80);                //delay 80uS

        if(!(GPGDAT&(1<<7)))

        dr=1;

        udelay(500);                //delay 400uS

        return dr;

}


void DS18B20_Write(unsigned char dw)

{

        unsigned char wr;

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

        {

                dat_1820_low;

                if(dw&0x01)

                {

                        udelay(5);

                        dat_1820_hign;

                        udelay(60);

                }

                else

                {                       

                        udelay(75);                       

                }

                dat_1820_hign;

                dw>>=1;

                udelay(3);

        }

        udelay(5);               

}



//read a byte from 1-wire bus

unsigned char DS18B20_Read(void)

{

        unsigned char dr,dr1=0;

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

        {

                dr1>>=1;

                dat_1820_low;

                udelay(2);

                dat_1820_hign;

                udelay(10);

                if(GPGDAT&(1<<7))

                dr1|=0x80;

                udelay(60);

        }

        return dr1;

}



//read the temperature

short DS18B20_ReadTemp(void)

{

        float dt3;

        short dt;

        unsigned char dt1,dt2;

        DS18B20_Reset();

        DS18B20_Write(0xcc);

        DS18B20_Write(0x44);
        GPGDAT|=1<<7;GPGCON=(GPGCON&(~(3<<14))) | (1<<14 );        //power supply for DS18B20

        mdelay(1000);                //delay 1S

        dat_1820_hign;

        DS18B20_Reset();

        DS18B20_Write(0xcc);

        DS18B20_Write(0xbe);

        dt1=DS18B20_Read();

        dt2=DS18B20_Read();

        dt=dt2*0x100+dt1;       

        DS18B20_Reset();

/*        if(dt&(1<<15))

        {

                dt=0xffff-dt+1;

                dt3=dt*0.0625*10;

                dt=0x8000+dt3;               

        }

        else

//        {

                dt3=(float)dt*0.0625*10;

                dt=dt3;               

//        }*/
//        dt3=((float)dt)*0.0625;

        return dt;

}
//*************DS18B20 operation end**********

static ssize_t DS18B20_read(struct file *file, char *buff, size_t size, loff_t *loff_t)
{
        short tp;
        tp=DS18B20_ReadTemp();
        copy_to_user(buff, &tp, sizeof(short));
        return sizeof(short);
}

struct file_operations DS18B20_fops=
{
        read:DS18B20_read,
};

static int __init DS18B20_init(void)
{
        int ret=0;
        short tp=0;

        dat_1820_hign;
        GPGUP&=~(1<<7);

        mdelay(1000);
        tp=DS18B20_ReadTemp();

        printk("temperature is %i\n",tp);

        ret=register_chrdev(MAJOR_NUM,"DS18B20",&DS18B20_fops);
        if(ret)
        {
                printk("DS18B20 register failure");
        }
        else
        {
                printk("DS18B20 register success\n");
        }
        return ret;
}

static void __exit DS18B20_exit(void)
{
        int ret=0;
        dat_1820_hign;

        ret=unregister_chrdev(MAJOR_NUM,"DS18B20");
        if(ret)
        {
                printk("DS18B20 unregister failure");
        }
        else
        {
                printk("DS18B20 unregister success\n");
        }
}

MODULE_LICENSE("GPL");
module_init(DS18B20_init);
module_exit(DS18B20_exit);
//-------DS18B20.c文件结束-------------------

编译步骤
在终端里运行
编译命令 arm-linux-gcc -D__KERNEL__ -D MODULE -I /usr/src/s3c2440_2.4.20/include -c DS18B20.c
编译成功会生成文件 DS18B20.o  这个文件就是我们需要的驱动模块了
注:
arm-linux-gcc 这是交叉编译器(当然你电脑里要首先安装交叉编译器)
/usr/src/s3c2440_2.4.20/include 这是S3C2440 linux内核源代码地址,你的可能不一样

接下来我们需要把 DS18B20.o 通过U盘拷贝到S3C2440开发板上

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2009-12-27 15:44:16 | 显示全部楼层
接着把DS18B20.o 通过U盘拷贝到S3C2440开发板上,此步骤省略可能过U盘 串口 网口ftp等 (默认放在 /usr 下)

加载模块
命令 insmod DS18B20.o
加载成功后终端会显示如下内容:
temperature is 295
DS18B20 register success
上面的 295是什么意思呢,可不是295度,怎么高的温度,要不我都成烧鹅了。295*0.0625=18.4度,这才是真正的温度

加载模块后我们输入命令 cat /proc/devices 可以看到 有一行文字这样写的 98 DS18B20 这就表示模块已经成功的被加载了,而且在系统里也查有实据了。至于98这是数字代表什么,这可不是乱写的,在DS18B20.c这个文件里自己找一下98就知道了。

输入命令 ls /dev 你可以看到你系统的设备都在里面,但还没有DS18B20这个设备
这时我们需要手动建立一个名叫DS18B20的节点
命令 mknod /dev/DS18B20 c 98 0
节点建立后 这时再输入 ls /dev 看看 DS18B20就显示在里面了
至此DS18B20已经完全成为你系统里注册的设备了,你可以在你的项目里使用它了。



接下来再写个 测试程序来试试DS18B20的驱动,当然这个程序就相当简单了
//-------test.c文件开始-------------------
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
#include <float.h>

main()
{
  int fd;short num;float tp;
  //打开"/dev/DS18B20"
  fd = open("/dev/DS18B20", O_RDWR, S_IRUSR | S_IWUSR);
  if (fd != -1 )
  {
    //读DS18B20
    read(fd, &num, sizeof(short));
        tp=num*0.0625;
    printf("Now Temperatre is %.1f ℃\nThis demo design by 001friend.\nThank you!\n",tp);

    //关闭"/dev/DS18B20"
    close(fd);
  }
  else
  {
    printf("Device open failure\n");
  }
}
//-------test.c文件结束-------------------

编译test.c
编译命令 arm-linux-gcc test.c
结果生成了 a.out这个程序

把a.out从电脑拷贝到开发板的 /usr 下
再运行 /usr/a.out
终端会显示:
Now Temperatre is 18.3 ℃                                                      
This demo design by 001friend.                                                  
Thank you!

哈哈,恭喜你,DS18B20可以正常使用了

出0入59汤圆

发表于 2009-12-27 16:12:15 | 显示全部楼层
把18B20挂在2440是嵌入式应用的一大错误

出0入0汤圆

发表于 2009-12-27 16:48:48 | 显示全部楼层
顶楼主,在学校时用2440学过一段时间linux驱动,工作不是这个都慢慢忘记了,哎。。。。。

出0入20汤圆

发表于 2009-12-27 17:57:58 | 显示全部楼层
可以作为初学者使用

出0入0汤圆

发表于 2010-2-24 22:45:17 | 显示全部楼层
回复【2楼】polarbear 枫叶
把18B20挂在2440是嵌入式应用的一大错误
-----------------------------------------------------------------------

讲点缘由啊?

出0入0汤圆

发表于 2010-2-26 23:33:01 | 显示全部楼层
楼主很棒!

出0入0汤圆

发表于 2010-2-27 12:01:46 | 显示全部楼层
mark下

出0入0汤圆

发表于 2010-3-7 01:04:45 | 显示全部楼层
linux下的驱动不用考虑互斥访问吗?连自旋锁都没用到阿

出0入0汤圆

发表于 2010-3-8 16:57:54 | 显示全部楼层
回复【楼主位】001friend
刚开始学linux驱动,摸索了好多天,刚开始GPIO口不知道怎么驱动,上网找了无数资料,测试了无数遍才搞定,希望对刚学linux 驱动的朋友有些帮助!
文件名:DS18B20.c 用途linux 驱动程序
//-------DS18B20.c文件开始-------------------
//Design by 001friend (2009.12.27)
//DS18B20 Drive for linux2.4.20 (target: S3C2440)
//1-wire bus interface drive via GPG7
#ifndef _KERNEL_
        #define _KERNEL_
#endif
#ifndef MODULE
        #define MODULE
#endif
#include <linux/kernel.......
-----------------------------------------------------------------------

为什么才回来的温度要乘以0.0625,不是0.5的分辨率吗?

出0入0汤圆

发表于 2010-3-31 19:50:49 | 显示全部楼层
记号!

出0入0汤圆

发表于 2010-4-28 09:36:35 | 显示全部楼层
有空试试

出0入0汤圆

发表于 2010-5-3 13:44:01 | 显示全部楼层
有空试试

出0入0汤圆

发表于 2010-7-28 15:47:32 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 13:44

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表