OK6410 Linux DS18B20驱动

来源:互联网 发布:淘宝质量好的女包店 编辑:程序博客网 时间:2024/05/22 12:50
//要注意一点,在裸机状态下可以使用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_ERROR0xf000//初始化失败//系统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);}//读IOunsigned char Read18b20IO(void){unsigned int reg;reg = readl(S3C64XX_GPEDAT);if(reg & 1)return 1;elsereturn 0;}//写IOvoid Write18b20IO(unsigned char data){unsigned int reg;reg = readl(S3C64XX_GPEDAT);if(data)reg |= 1;elsereg &= ~1;writel(reg,S3C64XX_GPEDAT);}//设在DS18B20 IO输入模式void Set18b20IOin(void){unsigned int reg;reg = readl(S3C64XX_GPECON);reg &= (~0xf);writel(reg,S3C64XX_GPECON);}//复位DS18B20u8 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=armCROSS_COMPILE=arm-linux-obj-m := ds18b20_drive.o#ds18b20_drive-objs := ds18b20_drive.oKDIR :=/home/cfan/linux/linux-3.0.1 PWD :=$(shell pwd)all:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:$(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 DS18B20if(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}}




原创粉丝点击