ds18b20驱动程序Linux,基于linux下的ds18b20驱动程序的编写
基于Linux操作系统下面的驱动程序的编写
一、所用的平台:
硬件平台:Mini2440
Size of NAND:256M
linux kernel:linux-2.6.32.2
二、编写ds18b20驱动程序所需要用到的硬件资源是操作s3c2440的引脚以及该引脚所对应的一些数据寄存器,那么该驱动程序例程是用引脚是S3C2410_GPG(0)。
三、编写驱动时首先要对编写的对象的时序要了解,那么ds18b20的时序如下:
DS18B20时序详解
初始化时序:
DS18B20的所有通信都是以由复位脉冲组成的初始化序列开始的。该初始化序列由主机发出,后跟由DS18B20发出的存在脉冲(presence
pulse)。
DS18B20发出存在脉冲,以通知主机它在总线上并且准备好操作了。
在初始化时序中,总线上的主机通过拉低单总线至少480μs来发送复位脉冲。然后总线主机释放总线并进入接收模式。总线释放后,4.7kΩ的上拉电阻把单总线上的电平拉回高电平。当DS18B20检测到上升沿后等待15到60us,然后以拉低总线60-240us的方式发出存在脉冲。
如上所述,主机将总线拉低最短480us,之后释放总线。由4.7kΩ上拉电阻将总线恢复到高电平。DS18B20检测到上升沿后等待15到60us,发出存在脉冲:拉低总线60-240us。至此,初始化和存在时序完毕。
写时序: 主机在写时隙向DS18B20写入数据,在读时隙从DS18B20读取数据。在单总线上每个时隙只传送一位数据。
有两种写时隙:写“0”时间隙和写“1”时间隙。总线主机使用写“1”时间隙向DS18B20写入逻辑1,使用写“0”时间隙向DS18B20写入逻辑0.所有的写时隙必须有最少60us的持续时间,相邻两个写时隙必须要有最少1us的恢复时间。两种写时隙都通过主机拉低总线产生。
为了产生写1时隙,在拉低总线后主机必须在15μs内释放总线。在总线被释放后,由于4.7kΩ上拉电阻将总线恢复为高电平。为了产生写0时隙,在拉低总线后主机必须继续拉低总线以满足时隙持续时间的要求(至少60μs)。
在主机产生写时隙后,DS18B20会在其后的15到60us的一个时间窗口内采样单总线。在采样的时间窗口内,如果总线为高电平,主机会向DS18B20写入1;如果总线为低电平,主机会向DS18B20写入0。
如上所述,所有的写时隙必须至少有60us的持续时间。相邻两个写时隙必须要有最少1us的恢复时间。所有的写时隙(写0和写1)都由拉低总线产生。
读时序: DS18B20只有在主机发出读时隙后才会向主机发送数据。因此,在发出读暂存器命令
[BEh]或读电源命令[B4h]后,主机必须立即产生读时隙以便DS18B20提供所需数据。另外,主机可在发出温度转换命令T
[44h]或Recall命令E 2[B8h]后产生读时隙,以便了解操作的状态。
所有的读时隙必须至少有60us的持续时间。相邻两个读时隙必须要有最少1us的恢复时间。所有的读时隙都由拉低总线,持续至少1us后再释放总线(由于上拉电阻的作用,总线恢复为高电平)产生。在主机产生读时隙后,DS18B20开始发送0或1到总线上。DS18B20让总线保持高电平的方式发送1,以拉低总线的方式表示发送0.当发送0的时候,DS18B20在读时隙的末期将会释放总线,总线将会被上拉电阻拉回高电平(也是总线空闲的状态)。DS18B20输出的数据在下降沿(下降沿产生读时隙)产生后15us后有效。因此,主机释放总线和采样总线等动作要在15μs内完成。
温度转换和读温度时序:
四、驱动程序:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DS18B20_MAJOR 200
#define DEVICE_NAME "ds18b20"
#define DATA_IO S3C2410_GPG(0)
#define DATA_OUT S3C2410_GPIO_OUTPUT
#define DATA_IN S3C2410_GPIO_INPUT
#define LEVEL_HIGHT 1
#define LEVEL_LOW 0
#define
PULL_UP 1
#define PULL_NULL 0
#define index 0
int init_ds18b20(void);
unsigned char read_byte(void);
void write_byte(unsigned char data);
struct ds18b20_cdev{
struct cdev cdev;
};
struct ds18b20_cdev *ds18b20_char_dev;
int init_ds18b20(void)
{
int
get_data=0x01;
s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);
s3c2410_gpio_pullup(DATA_IO,PULL_UP);
s3c2410_gpio_setpin(DATA_IO,LEVEL_LOW);
udelay(520);
s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);
udelay(80);
s3c2410_gpio_cfgpin(DATA_IO,DATA_IN);
s3c2410_gpio_pullup(DATA_IO,PULL_NULL);
get_data=s3c2410_gpio_getpin(DATA_IO);
udelay(200);
s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);
s3c2410_gpio_pullup(DATA_IO,PULL_UP);
return
get_data;
}
void write_byte(unsigned char data)
{
unsigned
char Data,i;
Data=data;
s3c2410_gpio_pullup(DATA_IO,PULL_UP);
for(i=0;i<8;i++)
{
s3c2410_gpio_setpin(DATA_IO,LEVEL_LOW);
udelay(2);
if((Data&0x01)==0x01)
{
s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);
}
udelay(60);
Data= Data>>1;
s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);
}
}
unsigned char read_byte(void)
{
unsigned char data=0,i;
for(i=0;i<8;i++)
{
s3c2410_gpio_setpin(DATA_IO,LEVEL_LOW);
udelay(2);
s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);
udelay(20);
s3c2410_gpio_cfgpin(DATA_IO,DATA_IN);
s3c2410_gpio_pullup(DATA_IO,PULL_NULL);
if(s3c2410_gpio_getpin(DATA_IO))
{
data=data|0x80;
}
data=data>>1;
udelay(50);
s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);
s3c2410_gpio_pullup(DATA_IO,PULL_UP);
s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);
udelay(1);
}
s3c2410_gpio_cfgpin(DATA_IO,DATA_OUT);
s3c2410_gpio_pullup(DATA_IO,PULL_UP);
s3c2410_gpio_setpin(DATA_IO,LEVEL_HIGHT);
return data;
}
static ssize_t temper_read(struct file *filep,char __user
*buf,size_t count,loff_t *f_pos)
{
int
check;
char
result[2];
unsigned
long error;
check=
init_ds18b20();
if((check&0x01)==0x01)
{
printk("\n Warning : Fail the init ds18b20 ");
return -1; }
write_byte(0xcc);
write_byte(0x44);
udelay(500);
init_ds18b20();
write_byte(0xcc);
write_byte(0xbe);
result[0]= read_byte();
result[1]= read_byte();
error=copy_to_user(buf,result,sizeof(result));
if(!error)
{
return 0;
}
else
return min(sizeof(result),count);
}
static int ds18b20_open(struct inode *inode,struct file
*filep)
{
unsigned char flag;
flag=init_ds18b20();
if(flag)
{
printk("\n warning:Fail the init ds18b20 \n");
return -1; }
else
printk("\n open:successful");
return 0;
}
static struct file_operations ds18b20_fops={
.open=ds18b20_open,
.owner=THIS_MODULE,
.read=temper_read,
};
static void ds18b20_setup_cdev(void)
{
int error;
dev_t dev_num;
dev_num=MKDEV(DS18B20_MAJOR,index);
cdev_init(&ds18b20_char_dev->cdev,&ds18b20_fops);
ds18b20_char_dev->cdev.owner=THIS_MODULE;
ds18b20_char_dev->cdev.ops=&ds18b20_fops;
error=cdev_add(&ds18b20_char_dev->cdev,dev_num,1);
if(error)
{
printk("error:add the ds18b20 driver \n %d,%d",error,index);
} }
static int __init ds18b20_init(void)
{
int
error;
dev_t
dev_num;
dev_num=MKDEV(DS18B20_MAJOR,index);
if(dev_num)
{
error=register_chrdev_region(dev_num,0,DEVICE_NAME);
}
else
{
error=alloc_chrdev_region(&dev_num,0,1,DEVICE_NAME);
}
if(error<0)
{
return -1;
}
ds18b20_char_dev=kmalloc(sizeof(struct
ds18b20_cdev),GFP_KERNEL);
if(!ds18b20_char_dev)
{
goto delete_error;
}
memset(ds18b20_char_dev,0,sizeof(struct ds18b20_cdev));
ds18b20_setup_cdev();
return 0;
delete_error:
unregister_chrdev_region(dev_num,1);
return error;
}
static void __exit ds18b20_exit(void)
{
dev_t
dev_num;
dev_num=MKDEV(DS18B20_MAJOR,index);
cdev_del(&ds18b20_char_dev->cdev);
kfree(ds18b20_char_dev);
unregister_chrdev_region(dev_num,1);
}
module_init(ds18b20_init);
module_exit(ds18b20_exit);
Makefile文件:
1 obj-m := ds18b20.o
2 CC = arm-linux-gcc
3 KDIR := /opt/linux-2.6.32.2
4 PWD := $(shell pwd)
5 default:
6 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
7 clean:
8 rm -rf *.o
9 rm -rf *.ko
10 rm -rf .*.cmd
11 rm -rf *.mod.*
五、上层应用程序
#include
#include
#include
#include
void udelay(unsigned int time)
{
int i,j;
for(i=0;i
{
for(j=0;j<50000;j++);
}
}
int main()
{
int fd,value=0;
float temper=0;
unsigned char flag=0;
char result[2];
fd=open("/dev/ds18b20",0);
if(fd<0)
{
printf("\n error:the fail open document");
return -1;
}
while(1)
{
read(fd,result,sizeof(result));
value=result[1];
value=(value<<8)|result[0];
if((result[1]&0xf0)==0x0f)
{
value=~value+1; flag=1;
} temper=(float)value*0.0625;
printf("\n The temper is:%f",temper);
udelay(50);
}
}
Makefile:
1 CC:= arm-linux-gcc
2
3 ds18b20_app:ds18b20_app.o
4 $(CC) -o ds18b20_app ds18b20_app.c
5
6 clean:
7 rm -rf ds18b20_*.o*~
ds18b20驱动程序Linux,基于linux下的ds18b20驱动程序的编写相关推荐
- 通信核心网linux,基于linux的双模智能手机实现方案
双模智能手机是能利用CS域和IMS域进行通讯的移动终端设备.在分析采用的三种技术后,再从系统架构.硬件平台.软件平台,再到DMS进行设计,从而完成整个系统的设计,并结合实际使用的实物器件进行具体实现. ...
- ansole终端链接linux,基于Linux系统的智能家居远程控制系统设计论文.doc
基于Linux系统的智能家居远程控制系统设计论文 学科分类号 0801 北京邮电大学毕业论文 题目 (中文):基于Linux系统的智能家居远程控制系统设计 (英文):The smart home re ...
- 单机版游戏 linux,[基于linux系统图形单机版农场游戏.ppt
[基于linux系统图形单机版农场游戏 07届毕业设计论文答辩 基于linux系统图形单机版农场游戏 通信xxxx xxxx 指导老师:XX 专业:通信工程 院系:计算机与通信工程 姓名:XXX 学号 ...
- linux键盘驱动程序分析,基于Linux按键驱动分析与编程
硬件平台:Mini2440 Size of NAND:256M linux kernel:linux-2.6.32.2 一.首先编写按键驱动要用到的Mini2440的硬件是中断控制器和定时器 那么li ...
- 1x1 11b g n linux,基于RN1810下的2.4 GHz IEEE 802.11b/g/n无线模块
特性 • 符合IEEE 802.11b/g/n的收发器 • 2.4 GHz IEEE 802.11n单流1x1 • 与主机控制器的UART接口(4线,包括RTS/CTS) • 易于集成到最终产品中-- ...
- 串口服务器 linux,基于Linux的串口服务器设计与实现
随着互联网的迅猛发展,在使用计算机进行网络互联的同时,各种家电设备.仪器仪表以及工业生产中的数据采集和控制设备也在逐步地走向网络化,以便共享网络资源.所以,在电子设备日趋网络化的今天,利用串口服务器来 ...
- 三星 摄像头 linux,基于Linux 3.0.8 Samsung FIMC(S5PV210) 的摄像头驱动框架解读(一)...
FIMC这个名字应该是从S5PC1x0开始出现的,在s5pv210里面的定义是摄像头接口,但是它同样具有图像数据颜色空间转换的作用.而exynos4412对它的定义看起来更清晰些,摄像头接口被定义为F ...
- 文件系统加密 嵌入式Linux,基于Linux的NAND Flash加密文件系统的设计与实现
摘要: NAND Flash以其大容量,低成本,低功耗,抗震荡在非易失存储介质中占据重要地位,已经被广泛应用于消费型电子,航空设备等领域.但是由于NANDFlash的物理特性不同于磁盘存储设备,需要为 ...
- 基于Linux的USB 主/从设备之间通讯的三种方式
转载:http://archive.eet-china.com/www.eet-china.com/ART_8800323770_617693_TA_eda530e7.HTM 随着简单易用的USB接口 ...
最新文章
- [USACO19JAN]Train Tracking 2——神仙结论题+DP
- spring boot 热更新,热部署
- 计算机组成实验六MIPS汇编器,杭电计组实验6-MIPS汇编器与模拟器实验.doc
- ubuntu16.04+Virtualenv+python2.7+Caffe安装(CPU版本,无opencv)
- linux裸机网络安装,linux下PXEServer实现网络安装【实验】
- 洛谷P3845-球赛【离散化,贪心】
- 怎么测试本地网页在不同分辨率下电脑显示效果_4K商用超值利器 飞利浦272P7VPTKEB显示器评测...
- 从零开始react实战:云书签-1 react环境搭建
- Octave与MATLAB
- Java初学者作业——声明变量储存商品信息并进行输出
- Struts2拦截器-MethodFilterInterceptor
- 参加百度开放云编程马拉松后一点总结
- 辞职信微信html,微信退款处理.html
- 任天堂服务器维护2021,《怪物猎人:崛起》太火爆 任天堂服务器紧急维护
- flutter 自定义进度条progress
- IE/Firefox 自动关闭窗口
- 云计算中Region、AZ、POD的三角关系
- 制造业MES系统如何管理生产车间
- 吴恩达机器学习(二十)神经网络(II)
- 怎么建立网站?如何写网站建设策划方案?
热门文章
- Receptive Field Block Net for Accurate and Fast Object Detection
- 腾讯云快速增长背后 三大短板仍需补足
- AipOcr百度文字识别API Key和Secret Key申请及应用例子说明
- Android使用App Architecture打造最佳体验和高质量应用《一》
- Go在迅雷P2P连通系统中的性能优化实践-朱文
- 【笔记】c++ - 正则表达式: GNU Regex Library、PCRE, PCRE++、Boost.Regex
- 理解 Mach-O 并提高程序启动速度
- 打新股和打新债有什么区别?
- java身份证号/手机号隐藏中间几位
- *UVALive 6657 - GCD XOR(数学)