关于和arduino开发板接口上温度传感器DS18B20通过USB接口进行通信的问题

查看: 7501|回复: 1
【正点原子探索者STM32F407开发板例程连载+教学】第35章 DS18B20数字温度传感器实验
主题帖子精华
在线时间32 小时
第三十五章& DS18B20数字温度传感器实验
[C] 纯文本查看 复制代码1.硬件平台:正点原子探索者STM32F407开发板
2.软件平台:MDK5.1
3.固件库版本:V1.4.0
STM32虽然内部自带了温度传感器,但是因为芯片温升较大等问题,与实际温度差别较大,所以,本章我们将向大家介绍如何通过STM32来读取外部数字温度传感器的温度,来得到较为准确的环境温度。在本章中,我们将学习使用单总线技术,通过它来实现STM32和外部温度传感器(DS18B20)的通信,并把从温度传感器得到的温度显示在TFTLCD模块上。本章分为如下几个部分:
35.1 DS18B20简介
35.2 硬件设计
35.3 软件设计
35.4 下载验证
35.1 DS18B20简介
DS18B20是由DALLAS半导体公司推出的一种的“一线总线”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的数字化温度传感器。一线总线结构具有简洁且经济的特点,可使用户轻松地组建传感器网络,从而为测量系统的构建引入全新概念,测量温度范围为-55~+125℃ ,精度为±0.5℃。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~l2位的数字值读数方式。它工作在3~5.5V的电压范围,采用多种封装形式,从而使系统设计灵活、方便,设定分辨率及用户设定的报警温度存储在EEPROM中,掉电后依然保存。其内部结构如图35.1.1所示:
8a4d74b4d0_479.jpg (0 Bytes, 下载次数: 3)
22:54 上传
&&&&&& &&&&&&&&&&&&&& 图35.1.1 DS18B20内部结构图
ROM中的64位序列号是出厂前被光记好的,它可以看作是该DS18B20的地址序列码,每DS18B20的64位序列号均不相同。64位ROM的排列是:前8位是产品家族码,接着48位是DS18B20的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。ROM作用是使每一个DS18B20都各不相同,这样就可实现一根总线上挂接多个DS18B20。
所有的单总线器件要求采用严格的信号时序,以保证数据的完整性。DS18B20共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。这里我们简单介绍这几个信号的时序:
1)复位脉冲和应答脉冲
单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60 us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲,
若为低电平,再延时480 us。
写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。
在了解了单总线时序之后,我们来看看DS18B20的典型温度读取过程,DS18B20的典型温度读取过程为:复位à发SKIP ROM命令(0XCC)à发开始转换命令(0X44)à延时à复位à发送SKIP ROM命令(0XCC)à发读存储器命令(0XBE)à连续读出两个字节数据(即温度)à结束。
DS18B20的介绍就到这里,更详细的介绍,请大家参考DS18B20的技术手册。
35.2 硬件设计
由于开发板上标准配置是没有DS18B20这个传感器的,只有接口,所以要做本章的实验,大家必须找一个DS18B20插在预留的18B20接口上。
本章实验功能简介:开机的时候先检测是否有DS18B20存在,如果没有,则提示错误。只有在检测到DS18B20之后才开始读取温度并显示在LCD上,如果发现了DS18B20,则程序每隔100ms左右读取一次数据,并把温度显示在LCD上。同样我们也是用DS0来指示程序正在运行。
所要用到的硬件资源如下:
1)& 指示灯DS0&
2) TFTLCD模块
3)& DS18B20温度传感器
&&&&&& 前两部分,在之前的实例已经介绍过了,而DS18B20温度传感器属于外部器件(板上没有直接焊接),这里也不介绍。本章,我们仅介绍开发板上DS18B20接口和STM32的连接电路,如图35.2.1所示:
962b4de8062eca9f5b78c40cd01b.jpg (0 Bytes, 下载次数: 3)
22:54 上传
&&&&&& &&&&&&&&&&&& 图35.2.1 DS18B20接口与STM32的连接电路图
从上图可以看出,我们使用的是STM32的PG9来连接U12的DQ引脚,图中U12为DHT11(数字温湿度传感器)和DS18B20共用的一个接口,DHT11我们将在下一章介绍。这里,1WIRE_DQ和DCMI_PWDN是共用PG9的,所以他们不能同时使用。
DS18B20只用到U12的3个引脚(U13的1、2和3脚),将DS18B20传感器插入到这个上面就可以通过STM32来读取DS18B20的温度了。连接示意图如图35.2.2所示:
53caeeff051cf4.jpg (0 Bytes, 下载次数: 2)
22:54 上传
图35.2.2 DS18B20连接示意图
&&&&&& 从上图可以看出,DS18B20的平面部分(有字的那面)应该朝内,而曲面部分朝外。然后插入如图所示的三个孔内。
35.3 软件设计
打开我们的DS18B20数字温度传感器实验工程可以看到我们添加了ds18b20.c文件以及其头文件ds18b20.h文件,所有ds18b20驱动代码和相关定义都分布在这两个文件中。
打开ds18b20.c,该文件代码如下:
//复位DS18B20
void DS18B20_Rst(void)&&&&& &&
{&&&&&&&&&&&&&&&&
&&&&&& DS18B20_IO_OUT();
//SET PG11 OUTPUT
DS18B20_DQ_OUT=0; //拉低DQ
delay_us(750);&&& //拉低750us
DS18B20_DQ_OUT=1; //DQ=1
&&&&&& delay_us(15);&&&& //15US
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) && &&&
&&&&&& DS18B20_IO_IN();//SET
PG11 INPUT&&&&&&
(DS18B20_DQ_IN&&retry&200) { retry++; delay_us(1); };
&&&&&& if(retry&=200)return
&&&&&& else
(!DS18B20_DQ_IN&&retry&240) {retry++; delay_us(1); };
&&&&&& if(retry&=240)return
&&&&&& return
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) &&&&&&&&&&&&&&&&&&& &&
&&&&&& DS18B20_IO_OUT();//SET
PG11 OUTPUT
DS18B20_DQ_OUT=0;
&&&&&& delay_us(2);
DS18B20_DQ_OUT=1;
&&&&&& DS18B20_IO_IN();//SET
PG11 INPUT
&&&&&& delay_us(12);
&&&&&& if(DS18B20_DQ_IN)data=1;
&&& else data=0;&&&
delay_us(50);&&&&&&&&&&
&&& return
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)&&&
&&& dat=0;
&&&&&& for
(i=1;i&=8;i++)
j=DS18B20_Read_Bit();
dat=(j&&7)|(dat&&1);
&&& }&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&
&&& return
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)&&&&
&{&&&&&&&&&&&&
&&&&&& DS18B20_IO_OUT();//SET
PG11 OUTPUT;
(j=1;j&=8;j++)
testb=dat&0x01;
dat=dat&&1;
&&&&&&& if
&&&&&&&&&&&
DS18B20_DQ_OUT=0;// Write 1
&&&&&&&&&&&
delay_us(2);&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&
DS18B20_DQ_OUT=1;
&&&&&&&&&&&
delay_us(60);&&&&&&&&&&&&
&&&&&&& else
&&&&&&&&&&&
DS18B20_DQ_OUT=0;// Write 0
&&&&&&&&&&&
delay_us(60);&&&&&&&&&&&&
&&&&&&&&&&&
DS18B20_DQ_OUT=1;
&&&&&&&&&&&
delay_us(2);&&&&&&&&&&&&&&&&&&&&&&&&&
//开始温度转换
void DS18B20_Start(void)
{&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&
DS18B20_Rst();&&&& &&
&&&&&& DS18B20_Check();&&&&&&
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在&&& & &
u8 DS18B20_Init(void)
GPIO_InitTypeDef&
GPIO_InitS
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟
& //GPIOG9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
&&DS18B20_Rst();
return DS18B20_Check();
}& //从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
short DS18B20_Get_Temp(void)
&&&&&& short
DS18B20_Start();// ds1820 start convert
DS18B20_Rst();
DS18B20_Check();&&&&&&
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0xbe);// convert &&&
TL=DS18B20_Read_Byte(); // LSB&&
TH=DS18B20_Read_Byte(); // MSB&&
&&& if(TH&7)
temp=0;&&&&&&&& //温度为负&
temp=1; //温度为正&&&& & &&& &&
&&& tem=TH; &&&&&&&&&&&&& //获得高八位
tem&&=8;&&&
&&& tem+=TL;&&&&&&&&&&&&& //获得底八位
tem=(double)tem*0.625;&&&&&& //转换&&&&
&&&&&& if(temp)return
&&&& //返回温度值
&&&&&& else
return -&&&
该部分代码就是根据我们前面介绍的单总线操作时序来读取DS18B20的温度值的,DS18B20的温度通过DS18B20_Get_Temp函数读取,该函数的返回值为带符号的短整型数据,返回值的范围为-550~1250,其实就是温度值扩大了10倍。
接下来我们打开ds18b20.h,可以看到跟IIC实验代码很类似,这里我们不做过多讲解。接下来我们看看主函数代码:
int main(void)
t=0;&&&&&&&&&&&&&&&&& &&&
&&&&&& short
&&&&&& NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
&&&&&& delay_init(168);& //初始化延时函数
&&&&&& uart_init(115200);&&&&&&&& //初始化串口波特率为115200
&&&&&& LED_Init();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //初始化LED
&&&&& LCD_Init();
POINT_COLOR=RED;//设置字体为红色
&&&&&& LCD_ShowString(30,50,200,16,16,"Explorer
STM32F4");&&&&&&
&&&&&& LCD_ShowString(30,70,200,16,16,"DS18B20
TEST");&&&&
&&&&&& LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
&&&&&& LCD_ShowString(30,110,200,16,16,"");
&&&&& while(DS18B20_Init())& //DS18B20初始化
&&&&&&&&&&&&& LCD_ShowString(30,130,200,16,16,"DS18B20
&&&&&&&&&&&&& delay_ms(200);
&&&&&& &&&&&& LCD_Fill(30,130,239,130+16,WHITE);
&&&&&&&&&&&& delay_ms(200);
&&&&&& }&&
&&&&&& LCD_ShowString(30,130,200,16,16,"DS18B20
&&&&&& POINT_COLOR=BLUE;//设置字体为蓝色
&&&&& LCD_ShowString(30,150,200,16,16,"Temp:&& . C");
&&&&&& while(1)
&&&&&& {&&&& &&& &&&&&& &&&&
&&&&&&&&&&&& if(t%10==0)//每100ms读取一次
&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &
&&&&&&&&&&&&& &&&&&& temperature=DS18B20_Get_Temp();&&&
&&&&&&&&&&&&&&&&&&&& if(temperature&0)
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowChar(30+40,150,'-',16,0);&&&&&&&&&&&&&&&&& //显示负号
&&&&&&&&&&&&&&&&&&&&&&&&&&& temperature=-&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //转为正数
&&&&&&&&&&&&&&&&&&&& }else
LCD_ShowChar(30+40,150,' ',16,0);&&&&&&&&&&&&&&&& //去掉负号
&&&&&&&&&&&&&&&&&&&& LCD_ShowNum(30+40+8,150,temperature/10,2,16);& //显示正数部分&&&& &&&
&& &&&&&&&&&&&&&&& LCD_ShowNum(30+40+32,150,temperature%10,1,16);&&&& //显示小数部分 &&&&&&&&& &&&
&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&&&&&&&& &&
&&&&&& &&&&& delay_ms(10);
&&&&&&&&&&&&& if(t==20)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& t=0;
LED0=!LED0;
&&&&&&&&&&&&& }
主函数代码比较简单,一系列硬件初始化后,在循环中调用DS18B20_Get_Temp函数获取温度值,然后显示在LCD上。至此,我们本章的软件设计就结束了。
35.4 下载验证
在代码编译成功之后,我们通过下载代码到ALIENTEK探索者STM32F4开发板上,可以看到LCD显示开始显示当前的温度值(假定DS18B20已经接上去了),如图35.4.1所示:
9bffe6867bcd07f72789fb_861.jpg (0 Bytes, 下载次数: 3)
22:54 上传
DS18B20实验效果图
&该程序还可以读取并显示负温度值的,具备条件的读者可以测试一下。
实验详细手册和源码下载地址:
正点原子探索者STM32F407开发板购买地址:
18:01 上传
点击文件名下载附件
627.64 KB, 下载次数: 1264
18:01 上传
点击文件名下载附件
522.22 KB, 下载次数: 1727
我是开源电子网?网站管理员,对网站有任何问题,请与我联系!
主题帖子精华
高级会员, 积分 731, 距离下一级还需 269 积分
在线时间92 小时
有用到& & 单总线对延时要求比较高& & 前几天刚有一批货&&出了点&&bug& &今天看到这个贴& &讲解的很详细&&
Powered by【图文】实验2.1 ZigBee之DS18B20温度传感器数据采集实验_百度文库
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
实验2.1 ZigBee之DS18B20温度传感器数据采集实验
阅读已结束,下载本文到电脑
想免费下载本文?
登录百度文库,专享文档复制特权,积分每天免费拿!
你可能喜欢STM32单片机学习(11) DS18B20温度传感器实验
本程序主要实现DS18B20温度传感器数据获取,并利用串口通信把温度数据传至计算机
注:使用普中科技开发板测试时,需要拔掉Boot1插口,因为用到的是PA15管脚, 由开发板电路图可知,需要改变PA15管脚的映射,将其设置成普通IO口
-外设篇 视频教程(Cortex-M3)-主讲人:刘洋 http://yun.baidu.com/pcloulbum/info?uk=&album_id=8632574
* 软件功能:
DS18B20温度
#include &stm32f10x.h&
#include &delay.h&
#include &.h&
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART1_Configuration(void);
void Uart1_PutChar(u8 ch);
void Uart1_PutString(u8* buf , u8 len);
int fputc(int ch, FILE *f);
函数: int main(void)
功能: main主函数
int main(void)
double temperature=0;
RCC_Configuration();
GPIO_Configuration();
delay_init(72);
USART1_Configuration();
if(!DS18B20_Is_Exist())
printf(&未检测到DS18B20温度传感器...\n&);
delay_ms(500);
printf(&检测到DS18B20温度传感器\n获取数据中...\n&);
temperature=DS18B20_Get_wd();
printf(&当前温度:%0.4lf ℃\n\n&,temperature);
函数: void RCC_Configuration(void)
功能: 复位和时钟控制 配置
void RCC_Configuration(void)
ErrorStatus HSEStartUpS
//定义外部高速晶体启动状态枚举变量
RCC_DeInit();
//复位RCC外部设备寄存器到默认值
RCC_HSEConfig(RCC_HSE_ON);
//打开外部高速晶振
HSEStartUpStatus = RCC_WaitForHSEStartUp();
//等待外部高速时钟准备好
if(HSEStartUpStatus == SUCCESS)
//外部高速时钟已经准别好
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
FLASH_SetLatency(FLASH_Latency_2);
//flash操作的延时
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//配置AHB(HCLK)时钟等于==SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置APB2(PCLK2)钟==AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div2);
//配置APB1(PCLK1)钟==AHB1/2时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
RCC_PLLCmd(ENABLE);
//使能PLL时钟
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
//等待PLL时钟就绪
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//配置时钟 = PLL时钟
while(RCC_GetSYSCLKSource() != 0x08)
//检查PLL时钟是否作为系统时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
//允许 GPIOA、USART1、AFIO时钟
函数: void GPIO_Configuration(void)
功能: GPIO配置
void GPIO_Configuration(void)
GPIO_InitTypeDef GPIO_InitS
//定义GPIO初始化结构体
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复合推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA9串口输出
//把调试设置普通IO口
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
// 改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP 禁用 + SW-DP 使能
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
函数名:USART1_Configuration
功能说明:
初始化串口硬件设备,启用中断
配置步骤:
(1)打开GPIO和USART1的时钟
(2)设置USART1两个管脚GPIO模式
(3)配置USART1数据格式、波特率等参数
(4)使能USART1接收中断功能
(5)最后使能USART1功能
void USART1_Configuration(void)
//串口配置
详见《STM32的函数说明(中文).pdf》P346
USART_InitTypeDef USART_InitS
USART_InitStructure.USART_BaudRate=9600;
//波特率为9600
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
//数据位为8
USART_InitStructure.USART_StopBits=USART_StopBits_1; //在帧结尾传输 1 个停止位
USART_InitStructure.USART_Parity=USART_Parity_No; //校验模式:奇偶失能
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_N //硬件流控制失能
USART_InitStructure.USART_Mode=USART_Mode_Tx | USART_Mode_Rx; //USART_Mode 指定了使能或者失能发送和接收模式:发送使能|接收失能
USART_Init(USART1, &USART_InitStructure);
//初始化配置
USART_Cmd(USART1,ENABLE); //使能或者失能 USART 外设
USART_ClearFlag(USART1, USART_FLAG_TC);//清除传输完成标志位,否则可能会丢失第1个字节的数据.USART_FLAG_TC为发送完成标志位
//发送一个字符
void Uart1_PutChar(u8 ch)
USART_SendData(USART1, (u8) ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成
//发送一个字符串 Input : buf为发送数据的地址 , len为发送字符的个数
void Uart1_PutString(u8* buf , u8 len)
DS18B20.h&&#ifndef __DS18B20_H
#define __DS18B20_H
#include &stm32f10x.h&
#define DS18B20_Pin GPIO_Pin_15
#define DS18B20_GPIO GPIOA
#define DS18B20_DQ_High() GPIO_SetBits(DS18B20_GPIO,DS18B20_Pin)
#define DS18B20_DQ_Low()
GPIO_ResetBits(DS18B20_GPIO,DS18B20_Pin)
void DS18B20_IO_IN(void);
void DS18B20_IO_OUT(void);
u8 DS18B20_Read_Byte(void);
void DS18B20_Write_Byte(u8 dat);
void DS18B20_Reset(void);
double DS18B20_Get_wd(void);
u8 DS18B20_Is_Exist(void);
#include &stm32f10x.h&
#include &ds.h&
#include &delay.h&
void DS18B20_IO_IN(void)
GPIO_InitTypeDef GPIO_InitS
//定义GPIO初始化结构体
GPIO_InitStructure.GPIO_Pin = DS18B20_P
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//配置成上拉输入;
GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure);
void DS18B20_IO_OUT(void)
GPIO_InitTypeDef GPIO_InitS
//定义GPIO初始化结构体
GPIO_InitStructure.GPIO_Pin = DS18B20_P
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//配置成推挽输出;
GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure);
u8 DS18B20_Read_Byte(void)
u8 i=0,TmpData=0;
for(i=0;i&8;i++)
TmpData&&=1;
DS18B20_IO_OUT();
//输出模式
DS18B20_DQ_Low();
delay_us(4);
DS18B20_DQ_High();
//拉高,释放
delay_us(10);
//延时10us
DS18B20_IO_IN();
//输入模式
if(GPIO_ReadInputDataBit(DS18B20_GPIO,DS18B20_Pin)== 1)
TmpData |=0x80; //读取数据 ,从低位开始
delay_us(45);
//延时45us
void DS18B20_Write_Byte(u8 dat)
DS18B20_IO_OUT();
//输出模式
for(i=0;i&8;i++)
DS18B20_DQ_Low();
delay_us(15);
//延时15us
if(dat&0x01==0x01)
DS18B20_DQ_High();
DS18B20_DQ_Low();
delay_us(60);
//延时60us
DS18B20_DQ_High();
//准备下一位数据的写入
//复位函数
void DS18B20_Reset(void)
DS18B20_IO_OUT();
//输出模式
DS18B20_DQ_Low();
delay_us(480);
//延时480us
DS18B20_DQ_High();
delay_us(480);
//延时480us
//返回温度值
double DS18B20_Get_wd(void)
u8 TL=0,TH=0;
u16 temp=0;
double wd=0;
DS18B20_Reset();//复位
DS18B20_Write_Byte(0xCC); //跳过ROM命令
DS18B20_Write_Byte(0x44); //温度转换命令
delay_ms(800);//延时800毫秒
DS18B20_Reset();//复位
DS18B20_Write_Byte(0xCC); //跳过ROM命令
DS18B20_Write_Byte(0xBE); //读温度命令
TL=DS18B20_Read_Byte();//LSB
TH=DS18B20_Read_Byte();//MSB
temp=(temp&&8)+TL;
if((temp&0xF800)==0xF800)//负温度判断
temp=temp+1;
wd=temp*(-0.0625);
wd=temp*0.0625;
//等待DS18B20的回应
//返回1:检测到DS18B20的存在
//返回0:不存在
u8 DS18B20_Is_Exist(void)
DS18B20_IO_OUT();
//输出模式
DS18B20_DQ_High();
//默认高电平
DS18B20_DQ_Low();
delay_us(600);
//延时600us
DS18B20_DQ_High();
delay_us(100);
//延时100us
DS18B20_IO_IN();
//输入模式
if(GPIO_ReadInputDataBit(DS18B20_GPIO,DS18B20_Pin)== 0)使用DS18B20温度传感器采集温度
单片机&嵌入式
单片机应用
嵌入式操作系统
学习工具&教程
学习和开发单片机的必备工具
(有问必答)
(带你轻松入门)
电子元件&电路模块
当前位置: >>
>> 浏览文章
使用DS18B20温度传感器采集温度
& Rainbow开发包中已经封装了DTH11温湿度传感器,按照我的想法,同类型的传感器有了一种就可以了,本不想做DS18B20的封装,但是前两天有个朋友让我给他做个项目,需要测液体的温度,用DHT11个头太大,主要用于测室温,而DS18B20有用于测量液体温度的封装,非常方便使用。迫于无奈,今天就花了半天时间做了个小小的封装,在Rainbow开发板上通过了测试。
& & 使用DS18B20非常简单,和DHT11差不多,按照下列步骤:
& & 1、定义DS18B20对象,设定DS18B20的DQ数据线所使用的GPIO,如:DS18B20 ds(PC1);
& & 2、调用read()方法进行温度采集,如果返回DS18B20::OK,表示采集成功,其它值表示失败
& & 3、采集成功之后就可以使用对象的getCelsius()和getFahrenheit()分别获取到摄氏温度和华氏温度
& & 我这次试验选用了PC3与DS18B20的DQ管脚相连,这个管脚是用于DHT11数据采集,带有一个4.7K上拉电阻,电路原理图和实际接线图如下:
& &&在软件包的&Projects\DS18B20&文件夹包含了本文的完整工程,可以直接编译、烧写和调试。来看看main.cpp的代码:
#include &WProgram.h&
#include &DS18B20.h&
//接到DHT11_DATA_PIN,通过4.7K电阻上拉
DS18B20 ds(DHT11_DATA_PIN);
void setup()
& //启用默认串口,波特率9600
& Serial.start();
void loop()
& //数据采集成功
& if(ds.read() == DS18B20::OK)
& & Serial.print(&Celsius:&);
& & Serial.println(ds.getCelsius());
& & Serial.print(&Fahrenheit:&);
& & Serial.println(ds.getFahrenheit());
& & delay(5000);
int main(void)
& //初始化开发板
& boardInit();
& setup();
& while(1) loop();
& & 程序非常简单,就不再啰嗦,将USART3和USB-TTL模块连接,在串口调试工具中可以看到运行效果:
【】【】【】【】
上一篇:下一篇:
CopyRight @
单片机教程网 51hei.com , All Rights Reserved

我要回帖

更多关于 温度传感器接口 的文章

 

随机推荐