0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Openwrt开发指南 第27章 DS18B20温度传感器

嵌入式大杂烩 来源:嵌入式大杂烩 作者:嵌入式大杂烩 2023-07-15 16:13 次阅读

开发环境:

主机:Ubuntu12.04

开发板:RT5350

Openwrt:Openwrt15.05

1 硬件原理

下图是我们温度传感器的接入引脚,3.3V 供电,io 口接 P07的 GP0( GPIO0 的简称 )。

DS18B20 数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有 LTM8877,LTM8874 等等。主要根据应用场合的不同而改变其外观。封装后的 DS18B20 可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

2 单总线的概念

目前常用的微机与外设之间进行数据传输的串行总线主要有 I2C 总线、 SPI 总线和 SCI总线。其中 I2C 总线以同步串行 2 线方式进行通信(一条时钟线,一条数据线) ,SPI 总线则以同步串行 3 线方式进行通信(一条时钟线,一条数据输入线,一条数据输出线),而 SCI 总线是以异步方式进行通信(一条数据输入线,一条数据输出线) 。这些总线至少需要两条或两条以上的信号线。

1-wire , 即 单 线 总 线 , 又 叫 单 总 线 。 近 年 来 , 美 国 的 达 拉 斯 半 导 体 公 司(DALLASSEMICONDUCTOR) 推出了一项特有的单总线(1-Wire Bus)技术。该技术与上述总线不同,它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的,因而这种单总线技术具有线路简单,硬件开销少,成本低廉,便于总线扩展和维护等优点。

3 ds18b20 相关时序

  • 初始化(复位)时序图:

1.png

(1) 先将数据线置高电平“ 1” 。

(2) 延时(该时间要求的不是很严格,但是尽可能的短一点)

(3) 数据线拉到低电平“ 0” 。

(4) 延时 750 微秒(该时间的时间范围可以从 480 到 960 微秒) 。

(5) 数据线拉到高电平“ 1” 。

(6) 延时等待(如果初始化成功则在 15 到 60 微秒时间之内产生一个由 DS18B20 所

返回的低电平“ 0” 。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制) 。

(7) 若 CPU 读到了数据线上的低电平“ 0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要 480 微秒。

(8) 将数据线再次拉高到高电平“ 1”后结束。

  • 写 ds18b20 时序图:
    2.png

(1) 数据线先置低电平“ 0” 。

(2) 延时确定的时间为 15 微秒。

(3) 按从低位到高位的顺序发送字节(一次只发送一位) 。

(4) 延时时间为 45 微秒。

(5) 将数据线拉到高电平。

(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。

(7) 最后将数据线拉高。

  • 读 ds18b20 时序图:
    3.png

(1)将数据线拉高“ 1” 。

(2)延时 2 微秒。

(3)将数据线拉低“ 0” 。

(4)延时 3 微秒。

(5)将数据线拉高“ 1” 。

(6)延时 5 微秒。

(7)读数据线的状态得到 1 个状态位,并进行数据处理。

(8)延时 60 微秒。

4 驱动程序

关于字符设备驱动程序的使用,我们可以参照点亮 led 灯的那个实验,这里只给出跟ds18b20 密切相关的驱动程序,详细的程序请查看我们的驱动文件!

//配置连接温度传感器的引脚
#define DS18B20_L		*GPIO21_0_DATA &= ~(1< < 0)  //低电平	
#define DS18B20_H		*GPIO21_0_DATA |=  (1< < 0)  //高电平
#define DS18B20_OUT	        *GPIO21_0_DIR  |=  (1< < 0)  //输出	
#define DS18B20_IN		*GPIO21_0_DIR  &= ~(1< < 0)  //输入	
#define DS18B20_STA		*GPIO21_0_DATA & 0x01	

//寄存器定义
volatile unsigned long *GPIO21_0_DIR;
volatile unsigned long *GPIO21_0_DATA;	


/****************  基本定义 **********************/
//初始化函数必要资源定义
//用于初始化函数当中
//device number;
	dev_t dev_num;
//struct dev
	struct cdev ds18b20_cdev;
//auto "mknode /dev/ds18b20 c dev_num minor_num"
struct class *ds18b20_class = NULL;
struct device *ds18b20_device = NULL;

/********************  ds18b20有关的函数   ****************************/
//复位ds18b20传感器
static unsigned char ds18b20_reset(void)
{
	unsigned char ret = 0;
	unsigned char count = 0;

	DS18B20_OUT;
	DS18B20_H;
	udelay(100);			
	DS18B20_L;			
	udelay(600);			
	DS18B20_H;			
	udelay(45);			

	DS18B20_IN;			
	do
	{
		ret = DS18B20_STA;
		udelay(1);			
		count++;
	}
	while(ret != 0 && count< 50);

	DS18B20_OUT;

	udelay(400);			
	DS18B20_H;			

	return ret;
}

//从ds18b20读取一个字节
static unsigned char read_byte(void)
{
	unsigned char i,byte=0;

	DS18B20_OUT;
	DS18B20_H;
	udelay(100);

	for(i = 0; i< 8; i++)
	{
		byte > >= 1;
		DS18B20_L;
		udelay(4);
		DS18B20_H;
		udelay(2);
		if(DS18B20_STA == 1)
			byte |= 0x80;
		udelay(10);
	}

	return byte;
}

//向ds18b20写入一个字节
static unsigned char write_byte(unsigned char byte)
{
	unsigned char i;

	DS18B20_OUT;
	DS18B20_H;
	udelay(100);

	for(i = 0; i< 8; i++)
	{
		DS18B20_L;
		if( byte & 0x01 )
			DS18B20_H;
		else
			DS18B20_L;
		udelay(40);
		DS18B20_H;
		byte > >= 1;
	}
	udelay(10);
}

//从ds18b20中读出温度数据
static unsigned int read_temp(void)
{
	unsigned int t = 0 , l = 0;

	if(ds18b20_reset())
	{
		printk("step1,reset_ds18b20 error!n");
		return 0;
	}

	write_byte(0xcc);
	write_byte(0x44);
	udelay(4);

	if(ds18b20_reset())
	{
		printk("step2,reset_ds18b20 error!n");
		return 0;
	}

	write_byte(0xcc);
	write_byte(0xbe);

	l = read_byte();
	t = read_byte();
	t < <= 8;
	t += l;

	return t;
}


/**********************************************************************/

/**************** 结构体 file_operations 成员函数 *****************/
//open
static int ds18b20_open(struct inode *inode, struct file *file)
{
	printk("ds18b20 drive open...n");

	DS18B20_OUT; //初始化该引脚为输出;

	return 0;
}

//close
static int ds18b20_close(struct inode *inode , struct file *file)
{
	return 0;
}

//read
static ssize_t ds18b20_read(struct file *file, char __user *buffer,
			size_t len, loff_t *pos)
{
	unsigned int temp;
	printk("ds18b20 drive read...n");

	temp = read_temp();
	copy_to_user(buffer, &temp, 4);
	
	return 4;
}
/***************** 结构体: file_operations ************************/
//struct
static const struct file_operations ds18b20_fops = {
	.owner   = THIS_MODULE,
	.open	 = ds18b20_open,
	.release = ds18b20_close,	
	.read	 = ds18b20_read,
};


/*************  functions: init , exit*******************/
//条件值变量,用于指示资源是否正常使用
unsigned char init_flag = 0;
unsigned char add_code_flag = 0;

//init
static __init int ds18b20_init(void)
{
	int ret_v = 0;
	printk("ds18b20 drive init...n");

	//函数alloc_chrdev_region主要参数说明:
	//参数2: 次设备号
	//参数3: 创建多少个设备
	if( ( ret_v = alloc_chrdev_region(&dev_num,0,1,"ds18b20") ) < 0 )
	{
		goto dev_reg_error;
	}
	init_flag = 1; //标示设备创建成功;

	printk("The drive info of ds18b20:nmajor: %dnminor: %dn",
		MAJOR(dev_num),MINOR(dev_num));

	cdev_init(&ds18b20_cdev,&ds18b20_fops);
	if( (ret_v = cdev_add(&ds18b20_cdev,dev_num,1)) != 0 )
	{
		goto cdev_add_error;
	}

	ds18b20_class = class_create(THIS_MODULE,"ds18b20");
	if( IS_ERR(ds18b20_class) )
	{
		goto class_c_error;
	}

	ds18b20_device = device_create(ds18b20_class,NULL,dev_num,NULL,"ds18b20");
	if( IS_ERR(ds18b20_device) )
	{
		goto device_c_error;
	}
	printk("auto mknod success!n");

	//------------   请在此添加您的初始化程序  --------------//
       

	GPIO21_0_DATA = (volatile unsigned long *)ioremap(0x10000620, 4);
	GPIO21_0_DIR =  (volatile unsigned long *)ioremap(0x10000624, 4);

        //如果需要做错误处理,请:goto ds18b20_error;	

	 add_code_flag = 1;
	//----------------------  END  ---------------------------// 

	goto init_success;

dev_reg_error:
	printk("alloc_chrdev_region failedn");	
	return ret_v;

cdev_add_error:
	printk("cdev_add failedn");
 	unregister_chrdev_region(dev_num, 1);
	init_flag = 0;
	return ret_v;

class_c_error:
	printk("class_create failedn");
	cdev_del(&ds18b20_cdev);
 	unregister_chrdev_region(dev_num, 1);
	init_flag = 0;
	return PTR_ERR(ds18b20_class);

device_c_error:
	printk("device_create failedn");
	cdev_del(&ds18b20_cdev);
 	unregister_chrdev_region(dev_num, 1);
	class_destroy(ds18b20_class);
	init_flag = 0;
	return PTR_ERR(ds18b20_device);

//------------------ 请在此添加您的错误处理内容 ----------------//
ds18b20_error:
		

	add_code_flag = 0;
	return -1;
//--------------------          END         -------------------//
    
init_success:
	printk("ds18b20 init success!n");
	return 0;
}

//exit
static __exit void ds18b20_exit(void)
{
	printk("ds18b20 drive exit...n");	

	if(add_code_flag == 1)
 	{   
           //----------   请在这里释放您的程序占有的资源   ---------//
	    printk("free your resources...n");	               

		iounmap(GPIO21_0_DATA);
		iounmap(GPIO21_0_DIR);

	    printk("free finishn");		               
	    //----------------------     END      -------------------//
	}					            

	if(init_flag == 1)
	{
		//释放初始化使用到的资源;
		cdev_del(&ds18b20_cdev);
 		unregister_chrdev_region(dev_num, 1);
		device_unregister(ds18b20_device);
		class_destroy(ds18b20_class);
	}
}


/**************** module operations**********************/
//module loading
module_init(ds18b20_init);
module_exit(ds18b20_exit);

//some infomation
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("from Jafy");
MODULE_DESCRIPTION("ds18b20 drive");

5 应用程序

int main(int argc, char **argv)
{
	int fd;
	float t;
	unsigned int tmp = 0;

	//打开温度传感器驱动模块
	fd = open("/dev/ds18b20", O_RDWR | O_NONBLOCK);
	if (fd < 0)
	{
		printf("can't open!n");
		return -1;
	}

	read(fd, &tmp, sizeof(tmp));
	t = tmp * 0.0625;
	printf("the current temperature is %fn",t);

	close(fd);
	
	return 0;
}

编译模块驱动,不熟悉的朋友可看LED驱动相关。

$make package/kernel/ds18b20/compile V=99

编译模块驱动和应用程序

$make package/ds18b20_app/compile V=99

$make package/ds18b20_app/install V=99

$make package/index V=99

复制文件传给开发板测试

6 实验结果

4.png
审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 温度传感器
    +关注

    关注

    48

    文章

    2888

    浏览量

    155743
  • DS18B20
    +关注

    关注

    10

    文章

    777

    浏览量

    80629
  • 引脚
    +关注

    关注

    16

    文章

    1169

    浏览量

    50116
  • 开发板
    +关注

    关注

    25

    文章

    4883

    浏览量

    97004
  • OpenWrt
    +关注

    关注

    10

    文章

    126

    浏览量

    39240
收藏 人收藏

    评论

    相关推荐

    基于STM32的DS18B20温度传感器设计

    DS18B20内置了64位产品序列号,方便识别身份,在一根线上可以挂接多个DS18B20传感器,通过64位身份验证,可以分别读取来至不同传感器采集的
    的头像 发表于 03-07 11:44 1.3w次阅读
    基于STM32的<b class='flag-5'>DS18B20</b><b class='flag-5'>温度</b><b class='flag-5'>传感器</b>设计

    DS18B20温度传感器实验

    单片机驱动DS18B20温度传感器实现温度的串口打印显示,本实验中STM32基于HAL库开发。本文全程记录实验过
    发表于 08-18 07:44

    外设温度传感器DS18B20概述

    参看:《嵌入式-STM32开发指南》第三部分 外设篇 - 2 温度传感器DS18B20这篇文
    发表于 01-05 07:17

    数字温度传感器DS18B20的设计及应用

    数字温度传感器DS18B20的设计及应用 1引言 DS18B20是DALLAS公司生产的一线式数字温度
    发表于 04-02 18:00 2768次阅读
    数字<b class='flag-5'>温度</b><b class='flag-5'>传感器</b><b class='flag-5'>DS18B20</b>的设计及应用

    DS18B20完成温度检测的技巧

    介绍了DS18B20 温度传感器 的结构和特点以及用DS18B20温度传感器进行
    发表于 08-23 10:44 190次下载
    <b class='flag-5'>DS18B20</b>完成<b class='flag-5'>温度</b>检测的技巧

    DS18B20数字温度传感器

    本设计基于单片机STM32开发板,对DS18B20数字温度传感器进行控制,有源代码
    发表于 05-11 14:54 42次下载

    温度传感器DS18B20

    温度传感器DS18B20 51例程,亲测可用
    发表于 06-14 15:36 20次下载

    智能温度传感器DS18B20的原理与应用

    DS18B20是DALLAS公司生产的单线数字温度传感器,他具有独特的单线总线接口方式。文章详细的介绍了单线数字温度传感器
    发表于 10-11 18:19 48次下载

    ds18b20的特性_ds18b20温度传感器应用

    本文首先介绍了ds18b20的特性,其次介绍了DS18B20工作原理,最后介绍了ds18b20温度传感器应用。
    发表于 04-24 09:10 1.1w次阅读
    <b class='flag-5'>ds18b20</b>的特性_<b class='flag-5'>ds18b20</b><b class='flag-5'>温度</b><b class='flag-5'>传感器</b>应用

    8051单片机Proteus仿真与开发实例--DS18B20温度传感器仿真

    DS18B20温度传感器仿真DS18B20传感器是常用的数字温度
    发表于 11-21 12:21 20次下载
    8051单片机Proteus仿真与<b class='flag-5'>开发</b>实例--<b class='flag-5'>DS18B20</b><b class='flag-5'>温度</b><b class='flag-5'>传感器</b>仿真

    【正点原子FPGA连载】第二十七DS18B20数字温度传感器实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    【正点原子FPGA连载】第二十七DS18B20数字温度传感器实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1
    发表于 11-25 11:06 28次下载
    【正点原子FPGA连载】第二十七<b class='flag-5'>章</b><b class='flag-5'>DS18B20</b>数字<b class='flag-5'>温度</b><b class='flag-5'>传感器</b>实验 -摘自【正点原子】新起点之FPGA<b class='flag-5'>开发指南</b>_V2.1

    ds18b20温度传感器如何使用

    DS18B20是一款广泛使用的数字温度传感器,它具有高精度、低功耗和易于使用的特点。 DS18B20温度
    的头像 发表于 09-03 16:51 457次阅读

    ds18b20温度传感器怎么接线

    DS18B20是一种广泛使用的数字温度传感器,它基于1-Wire(一线)通信协议工作。这种传感器因其高精度、易用性和低成本而受到欢迎。 DS18B2
    的头像 发表于 10-18 14:50 402次阅读

    ds18b20传感器的使用方法

    Integrated开发的一种数字温度传感器,它能够提供9位到12位的温度测量精度,测量范围从-55°C到+125°C。这种传感器非常适合
    的头像 发表于 10-18 14:52 244次阅读

    DS18B20温度传感器的工作原理和硬件设计

    通过本文可以了解DS18B20温度传感器工作原理、硬件设计、DS18B20单总线接口驱动编写。
    的头像 发表于 10-24 14:38 301次阅读
    <b class='flag-5'>DS18B20</b><b class='flag-5'>温度</b><b class='flag-5'>传感器</b>的工作原理和硬件设计