//要注意一点,在裸机状态下可以使用data = data * 6.25来对温度值进行放大100倍,但是在内核中不能使用,但可以使用data = data * 625 / 100; 
//网上查了一下好像是内核不支持浮点.不知道是不是这回事,但是我不使用浮点驱动加载就没问题,使用后不能加载了. 
  
 
/****************************************************************************************************************
* 文件名称  :    DS18B20_drive.c
* 简介        :   OK6410 DS18B20驱动
* 作者        :    异灵元(cp1300@139.com)
* 创建时间  :    2012/09/18 20:37
* 修改时间  :    2012/09/18
* 说明        :    OK6410 开发板(S3C6410)DS18B20(GPIO)驱动
****************************************************************************************************************/
//系统头文件
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/delay.h>
#include <linux/io.h>
//--------------------------//
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
//--------------------------//
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-m.h>
#define DS18B20_ERROR   0xf000  //初始化失败
//系统US延时定义
#define Delay_US(x)     udelay(x)
//设置DS18B20 IO为推挽输出模式
void Set18b20IOout(void)
{
unsigned int reg;
reg = readl(S3C64XX_GPECON);
reg |= 1;
writel(reg,S3C64XX_GPECON);
}
//读IO
unsigned char Read18b20IO(void)
{
unsigned int reg;
reg = readl(S3C64XX_GPEDAT);
if(reg & 1)
return 1;
else
return 0;
}
//写IO
void Write18b20IO(unsigned char data)
{
unsigned int reg;
reg = readl(S3C64XX_GPEDAT);
if(data)
reg |= 1;
else
reg &= ~1;
writel(reg,S3C64XX_GPEDAT);
}
//设在DS18B20 IO输入模式
void Set18b20IOin(void)
{
unsigned int reg;
reg = readl(S3C64XX_GPECON);
reg &= (~0xf);
writel(reg,S3C64XX_GPECON);
}
//复位DS18B20
u8 DS18B20_Reset(void)
{
u8 i = 0;
Set18b20IOout();
Write18b20IO(1);
Delay_US(1);
Write18b20IO(0);
Delay_US(500);
Write18b20IO(1);
Delay_US(2);
Set18b20IOin();
while(Read18b20IO())
{
i ++;
Delay_US(1);
if(i > 100)
return 1;
}
Delay_US(250);
return 0x00;
}
//读DS18B20数据
u8 DS18B20_ReadData(void)
{
u8 i,data = 0;
for(i = 0;i < 8;i ++)
{
Set18b20IOout();
Write18b20IO(0);
data >>= 1;
Delay_US(12);
Write18b20IO(1);
Set18b20IOin();
Delay_US(1);
if(Read18b20IO())
data |= 0x80;
Delay_US(42);
}
return data;
}
//写DS18B20数据
void DS18B20_WriteData(u8 data)
{
u8 i;
Set18b20IOout();
for(i = 0;i < 8;i ++)
{
Write18b20IO(0);
Delay_US(12);
Write18b20IO(data & 0x01);
Delay_US(30);
Write18b20IO(1);
data >>= 1;
Delay_US(2);
}
}
//读取温度
int DS18B20_ReadTemper(void)
{
u8 th, tl;
int data;
if(DS18B20_Reset())
{
return DS18B20_ERROR;
}
DS18B20_WriteData(0xcc);
DS18B20_WriteData(0x44);
DS18B20_Reset();
DS18B20_WriteData(0xcc);
DS18B20_WriteData(0xbe);
tl = DS18B20_ReadData();
th = DS18B20_ReadData();
data = th;
data <<= 8;
data |= tl;
data = data * 625 / 100;
return data;
}
///
//驱动模块名称
#define DEVICE_NAME "OK6410_DS18B20"
//函数声明
///
static long OK6410_DS18B20_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg);
static ssize_t OK6410_DS18B20_write(
struct file *file,
const char __user *buff,
size_t size,
loff_t *loff);
static ssize_t OK6410_DS18B20_read(
struct file *file,
char __user *buff,
size_t size,
loff_t *loff);
///
/*  这个结构是字符设备驱动的核心
*   当应用程序操作设备文件所提供的open,read,write等函数,
*   最终会调用到这个结构中的对应函数
*/
static struct file_operations dev_fops = {
.owner              = THIS_MODULE,     //这是一个宏,指向编译模块时自动创建的__this_module变量
.unlocked_ioctl     = OK6410_DS18B20_ioctl,
.read               = OK6410_DS18B20_read,
.write              = OK6410_DS18B20_write
};
//注册驱动所使用的相关信息
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,                       //驱动模块名称
.fops = &dev_fops,
};
//DS18B20设备访问信号量
struct semaphore DS18B20_sem;
/****************************************************************************************************************
*函数名        :   static int  __init OK6410_DS18B20_init(void)
*功能       : DS18B20模块初始化函数
*参数       : 无
*返回       : 0:成功;<0:失败
*依赖       :     linux底层宏定义
*作者       : 异灵元(cp1300@139.com)
*创建时间   :   2012/09/18 20:38
*最后修改时间:    2012/09/18 20:38
*说明     :   初始化DS18B20硬件,注册DS18B20驱动
****************************************************************************************************************/
static int  __init OK6410_DS18B20_init(void)
{
int ret;
ret = misc_register(&misc);        //注册驱动
if(ret < 0)
{
printk(DEVICE_NAME " can't initialized DS18B20!\n");
return ret;
}
init_MUTEX(&DS18B20_sem);           //注册信号量
printk(DEVICE_NAME " initialized\n");
return 0;                           //返回成功
}
/****************************************************************************************************************
*函数名        :   static long OK6410_DS18B20_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
*功能       : 发送命令给DS18B20驱动模块,无实际作用,直接返回0
*参数       : 无作用
*返回       : 0
*依赖       :     无
*作者       : 异灵元(cp1300@139.com)
*创建时间   :   2012/09/18 20:38
*最后修改时间:    2012/09/18 20:38
*说明     :   无
****************************************************************************************************************/
static long OK6410_DS18B20_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
{
return 0;
}
/****************************************************************************************************************
*函数名        :   static ssize_t OK6410_DS18B20_write(
struct file *file,
const char __user *buff,
size_t size,
loff_t *loff)
*功能       : 写数据到DS18B20驱动模块,无效函数,返回0
*参数       : file:文件指针(无作用);buff:数据缓冲区指针;buff:数据数量;loff:无作用
*返回       : 0:成功;<0:失败
*依赖       :     linux底层宏
*作者       : 异灵元(cp1300@139.com)
*创建时间   :   2012/09/18 20:38
*最后修改时间:    2012/09/18 20:38
*说明     :   写无效
****************************************************************************************************************/
static ssize_t OK6410_DS18B20_write(
struct file *file,
const char __user *buff,
size_t size,
loff_t *loff)
{
return 0;
}
/****************************************************************************************************************
*函数名        :   static ssize_t OK6410_DS18B20_read(
struct file *file,
char __user *buff,
size_t size,
loff_t *loff)
*功能       : 读DS18B20状态,低电平灯亮
*参数       : file:文件指针(无作用);buff:数据缓冲区指针;buff:数据数量;loff:无作用
*返回       : 0:成功;<0:失败
*依赖       :     linux底层宏
*作者       : 异灵元(cp1300@139.com)
*创建时间   :   2012/09/18 20:38
*最后修改时间:    2012/09/18 20:38
*说明     :   读取到的是一个16位有符号的温度
****************************************************************************************************************/
static ssize_t OK6410_DS18B20_read(
struct file *file,
char __user *buff,
size_t size,
loff_t *loff)
{
int temp;
int *p;
if(down_interruptible(&DS18B20_sem))    //获取信号量
return -ERESTARTSYS;
temp = DS18B20_ReadTemper();           //读取温度
if(temp == DS18B20_ERROR)             //DS18B20初始化失败
return -1;                              //DS18B20读取失败,返回错误
p = (int *)buff;
*p = temp;                                 //将温度写入到缓冲区
up(&DS18B20_sem);                           //释放信号量
return 0;
}
/****************************************************************************************************************
*函数名        :   static void __exit OK6410_DS18B20_exit(void)
*功能       : 卸载DS18B20驱动
*参数       : 无
*返回       : 无
*依赖       :     linux底层宏
*作者       : 异灵元(cp1300@139.com)
*创建时间   :   2012/09/18 20:38
*最后修改时间:    2012/09/18 20:38
*说明     :   卸载驱动
****************************************************************************************************************/
static void __exit OK6410_DS18B20_exit(void)
{
misc_deregister(&misc);         //卸载驱动
}
//动态加载驱动接口(必须)
module_init(OK6410_DS18B20_init);
module_exit(OK6410_DS18B20_exit);
//其它信息(非必需)
MODULE_AUTHOR("cp1300@139.com");                     //驱动程序作者
MODULE_DESCRIPTION("OK6410(S3C6410) DS18B20 Driver"); //一些描述信息
MODULE_LICENSE("GPL");    //遵循的协议

makefile

ARCH=arm
CROSS_COMPILE=arm-linux-
obj-m := ds18b20_drive.o
#ds18b20_drive-objs := ds18b20_drive.o
KDIR :=/home/cfan/linux/linux-3.0.1
PWD :=$(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean

测试

/****************************************************************************************************************
* 文件名称  :    ds18b20_teset.c
* 简介        :   OK6410 DS18B20驱动测试程序
* 作者        :    异灵元(cp1300@139.com)
* 创建时间  :    2012/09/19 22:10
* 修改时间  :    2012/09/19
* 说明        :    OK6410 开发板(S3C6410)DS18B20(GPIO)驱动测试程序
****************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(void)
{
int fd;
int data;
//DS18B20测试
printf("DS18B20 test...\n");
fd = open("/dev/OK6410_DS18B20",O_RDONLY);       //open DS18B20
if(fd == -1)
{
printf("open DS18B20 error!\n");
exit(-1);
}
else
{
printf("open DS18B20 ok!\n");
}
while(1)
{
if(read(fd,&data,(size_t)2))
printf("read error!\n");
printf("ds18b20 = %d\n",data);
usleep(1000 * 1000);    //1000MS
}
}


OK6410 Linux DS18B20驱动相关推荐

  1. Linux音频设备驱动

    在Linux中,先后出现了音频设备的两种框架OSS和ALSA,本节将在介绍数字音频设备及音频设备硬件接口的基础上,展现OSS和ALSA驱动的结构. 17.1-17.2节讲解了音频设备及PCM.IIS和 ...

  2. linux设备驱动第五篇:驱动中的并发与竟态

    目录[-] 综述 信号量与互斥锁 Completions 机制 自旋锁 其他的一些选择 不加锁算法 原子变量与位操作 seqlock(顺序锁) 读取-拷贝-更新(RCU) 小结 综述 在上一篇介绍了l ...

  3. linux串口驱动分析

    linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作 ...

  4. linux音频驱动dma数据,Linux音频驱动简述

    3.2 mixer接口 int register_sound_mixer(structfile_operations *fops, int dev); 上述函数用于注册1个混音器,第1个参数fops即 ...

  5. Linux驱动无硬件设备,Linux设备驱动与硬件通信

    Linux物理设备驱动,主要有几种类型,如:IO类.内存类.总线类.IO类我们平时接触的最多,其主要特点是,通过IO设备的寄存器操作硬件,具体需要去查看硬件手册. 1. IO端口和IO内存 在硬件层, ...

  6. Linux主机驱动与外设驱动分离思想

    - by 宋宝华(Barry Song) 1主机.外设驱动分离的意义 在Linux设备驱动框架的设计中,除了有分层设计实现以外,还有分隔的思想.举一个简单的例子,假设我们要通过SPI总线访问某外设,在 ...

  7. Linux 网卡驱动学习(一)(分析一个虚拟硬件的网络驱动样例)

    在Linux,网络分为两个层,各自是网络堆栈协议支持层,以及接收和发送网络协议的设备驱动程序层. 网络堆栈是硬件中独立出来的部分.主要用来支持TCP/IP等多种协议,网络设备驱动层是连接网络堆栈协议层 ...

  8. 《Android深度探索(卷1):HAL与驱动开发》——1.6节 Linux设备驱动

    本节书摘来自异步社区<Android深度探索(卷1):HAL与驱动开发>一书中的第1章,第1.6节 Linux设备驱动,作者李宁,更多章节内容可以访问云栖社区"异步社区" ...

  9. linux设备驱动归纳总结

    前言: (总结已经基本写完,这段时间我会从新排版和修正.错误总会有的,望能指正!) 前段时间学习了嵌入式驱动,趁着没开始找工作,这段时间我会每天抽出时间来复习. 我的总结是根据学习时的笔记(李杨老师授 ...

最新文章

  1. 序列化/反序列化,我忍你很久了,淦!
  2. HBase-scan API 通过scan读取表中数据
  3. windows Service循环任务.服务启动后无法停止重启的解决办法
  4. SAP Spartacus RouteReducer
  5. 我,宇宙最强编辑器,支持远程开发
  6. (转)在Eclipse中用TODO标签管理任务(Task)
  7. ESLint is disabled since its execution has not been approved or denied yet
  8. CCTextureCache的多线程加载原理和使用
  9. JQUERY方法给TABLE动态增加行
  10. 基于Android的家庭财务管理流程图,SYL_Android_FamilyFinaceSystem 双鱼林基于安卓Android家庭财务管理系统毕业课程设计源码 - 下载 - 搜珍网...
  11. filter:alpha(opacity=100,style=1)
  12. 2019-07-10
  13. Android ThreadPool
  14. Eratosthenes筛法
  15. java如何快速入门Hadoop大数据技术?
  16. 汉诺塔(Hanoi)图解递归算法
  17. ansys workbench汉化教程_ARP8.1企业版安装及汉化教程 I 学之乎
  18. 南京大学计算机科学与技术,南京大学计算机科学与技术系简介
  19. 五、ELK设置用户密码登陆
  20. MarkDown中使用gif的神器:LICEcap

热门文章

  1. C语言黑洞数字123,20175234 2018-2019-2 个人项目:数字黑洞(三):圣经数
  2. MySQL Select 语句查询
  3. 大金中央空调拆装空调维修4008660030
  4. 中式台球 规则 ( ChinaBilliards )
  5. vb.net 模拟鼠标 失去焦点_我用MATLAB进行了十万次模拟,终于发现了一种几乎可以百分百进洞的台球打法!...
  6. OpenCV 图形识别
  7. Linux十大免费视频编辑软件大放送
  8. CSDN新星计划新玩法、年度勋章挑战赛开启
  9. Seagate 酷鱼七代添加ROM方法
  10. 典型微型计算机系统的硬件,微型计算机系统原理及应用