stm32制作ds18b20温度传感器

合集下载

基于STM32的室内温度控制系统

基于STM32的室内温度控制系统

基于STM32的室内温度控制系统题目基于STM32的室内温度控制系统_______学生姓名学号_____所在学院理工学院____________专业班级电子信息工程________________ 指导教师 __________________完成地点物理与电信工程实验室__________基于STM32的室内温度控制系统[摘要] 本设计是以STM32单片机为核心的温度控制系统。

采用DS18B20温度传感器实现对温度的采集,并用TFT液晶屏对温度进行显示。

通过对元器件的选择,设计系统的硬件电路,从而设计相关应用程序,制作实物,实现温度采集、显示、控制等功能。

结果表明,所设计的温度控制系统基本能够完成所需功能,并且具有测量精准高、实时性好、使用方便等特点。

[关键词] 温度控制; DS18B20;STM32单片机Indoor temperature control system based on STM32Abstract This design is based on STM32 microcontroller as the core of the temperature control ing DS18B20 temperature sensor to achieve the temperature of the collection, the use of TFT LCD screen to display the temperature. the hardware circuit of the system is designed through the selection of components; So as to design the related application, make the object, realize the function of temperature acquisition, display, control and other functions.The results show that the designed temperature control system can basically complete the required functions, and has the characteristics of high precision, good real-time performance, easy to use, and so on.Keywords temperature control;DS18B20;STM32 single chip microcompute目录绪论 (1)1 系统总体设计 (2)1.1系统功能要求 (2)1.2系统方案论证 (2)1.3系统设计框图 (2)1.4 具体控制选择 (2)1.4.1 控制器选择 (2)1.4.2 温度传感器 (3)2 硬件设计 (4)2.1硬件构成 (4)2.2 控制模块 (4)2.2.1 STM32简介 (4)2.2.2 STM32的主要优点 (5)2.2.3 STM32开发板 (6)2.3 最小系统设计 (7)2.4 温度采集模块 (8)2.4.1 DS18B20的介绍 (8)2.4.2 DS18B20工作原理介绍 (8)2.4.3 DS18B20使用中的注意事项 (9)2.4.4 DS18B20与STM32单片机的连接电路 (9)2.5 显示模块 (10)2.5.1 TFTLCD液晶显示简介 (10)2.5.2 ALIENTEK 2.8液晶简介 (10)2.6 按键模块 (11)2.7 电源模块 (12)2.8 风机模块 (12)3 系统软件设计 (13)3.1 主程序 (13)3.2 温度采集子程序 (14)3.4 按键子程序 (16)4 系统调试 (17)4.1 硬件调试 (17)4.2 软件调试 (17)4.3 联合调试 (17)4.4 故障分析 (17)5 总结与展望 (19)5.1 总结 (19)5.2 展望 (19)致谢 (20)参考文献 (21)附录A 外文及翻译 (22)原文 (22)译文 (29)附录B 系统电路图 (35)附录C 实物图 (36)附录D 程序清单 (37)绪论在人类的生活环境中,温度扮演着极其重要的角色。

使用DS18B20制作电子温度计

使用DS18B20制作电子温度计

使用DS18B20制作电子温度计——中北大学:马政贵本制作中使用单总线数字温度传感器DS18B20进行温度的测定,并通过51单片机控制1602液晶进行显示。

制作好的电子温度计如下图所示(显示当前温度为20.5摄氏度):第一部分:DS18B20的使用先介绍一下单总线的特点:单总线即只有一根数据线,系统中的数据交换,控制都由这根线完成。

单总线通常要求外接一个约为 4.7K —10K 的上拉电阻,这样,当总线闲置时其状态为高电平。

再介绍一下DS18B20的特点:( 1 )采用单总线的接口方式,与微处理器连接时,仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。

单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。

( 2 )测量温度范围宽,测量精度高: DS18B20 的测量范围为 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C 范围内,精度为 ± 0.5°C 。

( 3 )在使用中不需要任何外围元件。

( 4 )支持多点组网功能:多个 DS18B20 可以并联在惟一的单线上,实现多点测温。

( 5 )供电方式灵活:DS18B20 可以通过内部寄生电路从数据线上获取电源。

因此,当数据线上的时序满足一定的要求时,可以不接外部电源,从而使系统结构更趋简单,可靠性更高。

( 6 )测量参数可配置 DS18B20 的测量分辨率可通过程序设定 9~12 位。

( 7 )负压特性电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。

( 8 )掉电保护功能 DS18B20 内部含有 EEPROM ,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

DS18B20 具有体积更小、适用电压更宽、更经济、可选更小的封装方式,更宽的电压适用范围,适合于构建自己的经济的测温系统,因此也就被设计者们所青睐。

DS18B20温度传感器设计原理图及c程序代码

DS18B20温度传感器设计原理图及c程序代码

/*******************代码部分**********************//*************** writer:shopping.w ******************/ #include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}sbit DQ = P3^3;sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;uchar code Temp_Disp_Title[]={"Current Temp : "};uchar Current_Temp_Display_Buffer[]={" TEMP: "};uchar code Temperature_Char[8] ={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};uchar code df_Table[]=0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};uchar CurrentT = 0;uchar Temp_Value[]={0x00,0x00}; uchar Display_Digit[]={0,0,0,0};bit DS18B20_IS_OK = 1;void DelayXus(uint x){uchar i;while(x--){for(i=0;i<200;i++);}}bit LCD_Busy_Check(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;delayNOP();result = (bit)(P0&0x80);LCD_EN=0;return result;}void Write_LCD_Command(uchar cmd) {while(LCD_Busy_Check());LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();P0 = cmd;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}void Write_LCD_Data(uchar dat){while(LCD_Busy_Check());LCD_RS = 1;LCD_RW = 0;LCD_EN = 0;P0 = dat;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}void LCD_Initialise(){Write_LCD_Command(0x01);DelayXus(5);Write_LCD_Command(0x38);DelayXus(5);Write_LCD_Command(0x0c);DelayXus(5);Write_LCD_Command(0x06);DelayXus(5);}void Set_LCD_POS(uchar pos){Write_LCD_Command(pos|0x80); }void Delay(uint x){while(--x);}uchar Init_DS18B20(){uchar status;DQ = 1;Delay(8);DQ = 0;Delay(90);DQ = 1;Delay(8);DQ = 1;return status;}uchar ReadOneByte(){uchar i,dat=0;DQ = 1;_nop_();for(i=0;i<8;i++){DQ = 0;dat >>= 1;DQ = 1;_nop_();_nop_();if(DQ)dat |= 0X80;Delay(30);DQ = 1;}return dat;}void WriteOneByte(uchar dat) {uchar i;for(i=0;i<8;i++){DQ = 0;DQ = dat& 0x01;Delay(5);DQ = 1;dat >>= 1;}}void Read_Temperature(){if(Init_DS18B20()==1)DS18B20_IS_OK=0;else{WriteOneByte(0xcc);WriteOneByte(0x44);Init_DS18B20();WriteOneByte(0xcc);WriteOneByte(0xbe);Temp_Value[0] = ReadOneByte();Temp_Value[1] = ReadOneByte();DS18B20_IS_OK=1;}}void Display_Temperature(){uchar i;uchar t = 150, ng = 0;if((Temp_Value[1]&0xf8)==0xf8){Temp_Value[1] = ~Temp_Value[1];Temp_Value[0] = ~Temp_Value[0]+1;if(Temp_Value[0]==0x00)Temp_Value[1]++;ng = 1;}Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);Display_Digit[3] = CurrentT/100;Display_Digit[2] = CurrentT%100/10;Display_Digit[1] = CurrentT%10;Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';Current_Temp_Display_Buffer[10] = '.';Current_Temp_Display_Buffer[9] = Display_Digit[1] + '0';Current_Temp_Display_Buffer[8] = Display_Digit[2] + '0';Current_Temp_Display_Buffer[7] = Display_Digit[3] + '0';if(Display_Digit[3] == 0)Current_Temp_Display_Buffer[7] = ' ';if(Display_Digit[2] == 0&&Display_Digit[3]==0)Current_Temp_Display_Buffer[8] = ' ';if(ng){if(Current_Temp_Display_Buffer[8] == ' ')Current_Temp_Display_Buffer[8] = '-';else if(Current_Temp_Display_Buffer[7] == ' ')Current_Temp_Display_Buffer[7] = '-';elseCurrent_Temp_Display_Buffer[6] = '-';}Set_LCD_POS(0x00);for(i=0;i<16;i++){Write_LCD_Data(Temp_Disp_Title[i]);}Set_LCD_POS(0x40);for(i=0;i<16;i++){Write_LCD_Data(Current_Temp_Display_Buffer[i]);}Set_LCD_POS(0x4d);Write_LCD_Data(0x00);Set_LCD_POS(0x4e);Write_LCD_Data('C');}void main(){LCD_Initialise();Read_Temperature();Delay(50000);Delay(50000);while(1){Read_Temperature();if(DS18B20_IS_OK)Display_Temperature();DelayXus(100);}}。

stm32--温度传感器DS18B20使用

stm32--温度传感器DS18B20使用
ቤተ መጻሕፍቲ ባይዱ
void Delay_us(u32 Nus)
{
SysTick->LOAD=Nus*9;
//时间加载
SysTick->CTRL|=0x01;
//开始倒数
while(!(SysTick->CTRL&(1<<16))); //等待时间到达
SysTick->CTRL=0X00000000;
//关闭计数器
SysTick->VAL=0X00000000;
//清空计数器
}
unsigned char ResetDS18B20(void) { unsigned char resport; SetDQ(); Delay_us(50);
ResetDQ(); Delay_us(500); //500us (该时间的时间范围可以从480到960微秒) SetDQ(); Delay_us(40); //40us //resport = GetDQ(); while(GetDQ()); Delay_us(500); //500us SetDQ(); return resport; }
void DS18B20WriteByte(unsigned char Dat) { unsigned char i; for(i=8;i>0;i--) {
ResetDQ(); //在15u内送数到数据线上,DS18B20在15-60u读数 Delay_us(5); //5us if(Dat & 0x01) SetDQ(); else ResetDQ(); Delay_us(65); //65us SetDQ(); Delay_us(2); //连续两位间应大于1us Dat >>= 1; } }

STM制作DSB温度传感器定稿版

STM制作DSB温度传感器定稿版

S T M制作D S B温度传感器HUA system office room 【HUA16H-TTMS2A-HUAS8Q8-HUAH1688】折腾了一晚上,才把DS18B20的驱动移植到STM32上来。

以前在51上使用过单个和多个连接的DS18B20,有现成的程序了,以为很快就能弄好,结果还是被卡住了,下面说下几个关键点吧:首先是延时的问题,STM32上若用软件延时的话不太好算时间,所以要么用定时器要么用SysTick这个定时器来完成延时的计算。

相比之下用SysTick来的简单方便点。

接着是STM32 IO脚的配置问题,因为51是双向的IO,所以作为输入输出都比较方便。

STM32的IO是准双向的IO,网上查了下资料,说将STM32的IO配置成开漏输出,然后外接上拉即可实现双向IO。

于是我也按规定做了,但调了老半天都不成功,是因为DS18B20没有响应的信号。

在烦躁之际只有试下将接DQ的IO分别拉低和拉高看能不能读入正确的信号。

结果果然是读入数据不对,原来我将IO配成开漏输出后相当然的以为读数据是用GPIO_ReadOutputDataBit(),这正是问题所在,后来将读入的函数改为GPIO_ReadInputDataBit()就OK了。

现在温度是现实出来了,但跟我家里那台德胜收音机上显示的温度相差2度,都不知道是哪个准了,改天再找个温度计验证下。

下面引用一段DS18B20的时序描述,写的很详细:DS18B20的控制流程根据DS18B20的通信协议,DS18B20只能作为从机,而单片机系统作为主机,单片机控制DS18B20完成一次温度转换必须经过3个步骤:复位、发送ROM指令、发送RAM指令。

每次对DS18B20的操作都要进行以上三个步骤。

复位过程为:单片机将数据线拉低至少480uS,然后释放数据线,等待15-60uS让DS18B20接收信号,DS18B20接收到信号后,会把数据线拉低60-240uS,主机检测到数据线被拉低后标识复位成功;发送ROM指令:ROM指令表示主机对系统上所接的全部DS18B20进行寻址,以确定对那一个DS18B20进行操作,或者是读取某个DS18B20的ROM序列号。

基于STM32开发板的多功能温度计设计报告

基于STM32开发板的多功能温度计设计报告

生产实习设计报告设计题目:基于STM32F107开发板的多功能温度计设计一、概述本设计基于STM32F107开发板,利用核心板上的STM32控制基板上的温度传感器DS18B20,实现DS18B20与STM32的双向通信;通过DS18B20实现温度测量,然后STM32对DS18B20转换后的数据进行读取和处理,转换成实际温度值后得到温度显示码,最后在OLED显示测得的温度(显示出温度值的符号位和整数位,以及一位小数)。

该多功能温度计除具备测温功能外,还有如下附加功能:可手动切换显示温度、日期、星期和时间;手动校时、调整日期;最高∕最低温度记忆功能;℃∕℉切换显示;每日闹钟功能;可通过RS232串口传输当前温度和时间至PC机。

本设计最终通过Matlab实现了温度标定,提高了测温准确度。

二、总体设计1.总体系统结构2.模块划分⑴.测温模块⑵.OLED显示模块⑶.按键、拨码开关模块⑷.蜂鸣器模块⑸.串行通信模块3.人员分工张家明完成源程序的编写,以及代码的修改、编译、下载、调试等工作;孙凯强、魏国祥、温琛林、王学良负责DS18B20、OLED相关资料的搜集和整理;王植阳、魏征、田开负责日历时钟芯片PCF8563相关资料的搜集和整理;王如胜、王江、王圣南负责最后产品各项功能的验证。

三、关键模块设计⑴.测温模块DS18B20是由DALLAS半导体公司推出的一种“一线总线”接口的温度传感器。

DS18B20工作在3V~5.5V 的电压范围,可以程序设定9~12位的分辨率,测温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃。

本设计中,DS18B20通过程序将其分辨率设为12位(温度分辨为0.0625℃)。

DS18B20与STM32的连接电路⑵.OLED显示模块OLED使用的控制器为SSD1305,可通过写入不同的命令字来设置对比度、显示开关、电荷泵、页地址等。

OLED被配置为使用I2C的方式。

STM32 实验22 DS18B20实验

STM32 实验22 DS18B20实验

} //从 DS18B20 读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void)
// read one bit
{
u8 data;
DS18B20_IO_OUT();//SET PA0 OUTPUT
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_OUT(); //SET PA0 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) { u8 retry=0; DS18B20_IO_IN();//SET PA0 INPUT while (DS18B20_DQ_IN&&retry<200) {
DS18B20 的介绍就到这里,更详细的介绍,请大家参考 DS18B20 的技术手册。
3.22.2 硬件设计
由于开发板上标准配置是没有 DS18B20 这个传感器的,只有接口,所以大家需要自己焊接 一个 DS18B20 上去。
本节实验功能简介:开机的时候先检测是否有 DS18B20 存在,如果没有,则提示错误。 只有在检测到 DS18B20 之后才开始读取温度并显示在 LCD 上,如果发现了 DS18B20,则程 序每隔 200ms 左右读取一次数据,并把温度显示在 LCD 上。同样我们也是用 LED0 来指示程 序正在运行。

51单片机DS18B20温度测量制作(有程序电路)

51单片机DS18B20温度测量制作(有程序电路)

51单片机DS18B20温度测量制作(有程序电路)单总线温度传感器DS18B20简介DS18B20是DALLAS公司生产的单总线式数字温度传感器,它具有微型化、低功耗、高性能、搞干扰能力强、易配处理器等优点,特别适用于构成多点温度测控系统,可直接将温度转化成串行数字信号(提供9位二进制数字)给单片机处理,且在同一总线上可以挂接多个传感器芯片。

它具有3引脚TO-92小体积封装形式,温度测量范围为-55 ℃~+125 ℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625 ℃,被测温度用符号扩展的16位数字量方式串行输出,其工作电源既可在远端引入,也可采用寄生电源方式产生,多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与多个DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。

以上特点使DS18B20非常适用于远距离多点温度检测系统。

DS18B20外形及引脚说明外形及引脚如图2所示:图2 管脚排列图在TO-92和SO-8的封装中引脚有所不同,具体差别请查阅PDF手册,在TO-92封装中引脚分配如下:1(GND):地2(DQ):单线运用的数据输入输出引脚3(VDD):可选的电源引脚DS18B20工作过程及时序DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。

高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。

初始时,温度寄存器被预置成 -55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。

初始时,计数器1预置的是与-55℃相对应的一个预置值。

以后计数器1每一个循环的预置数都由斜率累加器提供。

为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。

计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

折腾了一晚上,才把DS18B20的驱动移植到STM32上来。

以前在51上使用过单个和多个连接的DS18B20,有现成的程序了,以为很快就能弄好,结果还是被卡住了,下面说下几个关键点吧:首先是延时的问题,STM32上若用软件延时的话不太好算时间,所以要么用定时器要么用SysTick这个定时器来完成延时的计算。

相比之下用SysTick来的简单方便点。

接着是STM32 IO脚的配置问题,因为51是双向的IO,所以作为输入输出都比较方便。

STM32的IO是准双向的IO,网上查了下资料,说将STM32的IO配置成开漏输出,然后外接上拉即可实现双向IO。

于是我也按规定做了,但调了老半天都不成功,是因为DS18B20没有响应的信号。

在烦躁之际只有试下将接DQ的IO分别拉低和拉高看能不能读入正确的信号。

结果果然是读入数据不对,原来我将IO配成开漏输出后相当然的以为读数据是用GPIO_ReadOutputDataBit(),这正是问题所在,后来将读入的函数改为GPIO_ReadInputDataBit()就OK了。

现在温度是现实出来了,但跟我家里那台德胜收音机上显示的温度相差2度,都不知道是哪个准了,改天再找个温度计验证下。

下面引用一段DS18B20的时序描述,写的很详细:DS18B20的控制流程根据DS18B20的通信协议,DS18B20只能作为从机,而单片机系统作为主机,单片机控制DS18B20完成一次温度转换必须经过3个步骤:复位、发送ROM指令、发送RAM指令。

每次对DS18B20的操作都要进行以上三个步骤。

复位过程为:单片机将数据线拉低至少480uS,然后释放数据线,等待15-60uS让DS18B20接收信号,DS18B20接收到信号后,会把数据线拉低60-240uS,主机检测到数据线被拉低后标识复位成功;发送ROM指令:ROM指令表示主机对系统上所接的全部DS18B20进行寻址,以确定对那一个DS18B20进行操作,或者是读取某个DS18B20的ROM序列号。

发送RAM指令:RAM指令用于单片机对DS18B20内部RAM进行操作,如读取寄存器的值,或者设置寄存器的值。

具体的RAM和RAM指令请查阅DS18B20的数据手册。

下面简单介绍:1、ROM操作命令:DS18B20采用一线通信接口。

因为一线通信接口,必须在先完成ROM设定,否则记忆和控制功能将无法使用。

一旦总线检测到从属器件的存在,它便可以发出器件ROM操作指令,所有ROM 操作指令均为8位长度,主要提供以下功能命令:1 )读ROM(指令码0X33H):当总线上只有一个节点(器件)时,读此节点的64位序列号。

如果总线上存在多于一个的节点,则此指令不能使用。

2 )ROM匹配(指令码0X55H):此命令后跟64位的ROM序列号,总线上只有与此序列号相同的DS18B20才会做出反应;该指令用于选中某个DS18B20,然后对该DS18B20进行读写操作。

3 )搜索ROM(指令码0XF0H):用于确定接在总线上DS18B20的个数和识别所有的64位ROM序列号。

当系统开始工作,总线主机可能不知道总线上的器件个数或者不知道其64位ROM序列号,搜索命令用于识别所有连接于总线上的64位ROM序列号。

4 )跳过ROM(指令码0XCCH):此指令只适合于总线上只有一个节点;该命令通过允许总线主机不提供64位ROM序列号而直接访问RAM,以节省操作时间。

5 )报警检查(指令码0XECH):此指令与搜索ROM指令基本相同,差别在于只有温度超过设定的上限或者下限值的DS18B20才会作出响应。

只要DS18B20一上电,告警条件就保持在设置状态,直到另一次温度测量显示出非告警值,或者改变TH或TL的设置使得测量值再一次位于允许的范围之内。

储存在EEPROM内的触发器用于告警。

2、RAM指令DS18B20有六条RAM命令:1)温度转换(指令码0X44H):启动DS18B20进行温度转换,结果存入内部RAM。

2)读暂存器(指令码0XBEH):读暂存器9个字节内容,此指令从RAM 的第1个字节(字节0)开始读取,直到九个字节(字节8,CRC值)被读出为止。

如果不需要读出所有字节的内容,那么主机可以在任何时候发出复位信号以中止读操作。

3)写暂存器(指令码0X4EH):将上下限温度报警值和配置数据写入到RAM的2、3、4字节,此命令后跟需要些入到这三个字节的数据。

4)复制暂存器(指令码0X48H):把暂存器的2、3、4字节复制到EEPROM 中,用以掉电保存。

5)重新调E2RAM(指令码0XB8H):把EEROM中的温度上下限及配置字节恢复到RAM的2、3、4字节,用以上电后恢复以前保存的报警值及配置字节。

6)读电源供电方式(指令码0XB4H):启动DS18B20发送电源供电方式的信号给主CPU。

对于在此命令送至DS18B20后所发出的第一次读出数据的时间片,器件都会给出其电源方式的信号。

“0”表示寄生电源供电。

“1”表示外部电源供电。

下面是结合实际测试总结出来的DS18B20的操作流程:1、DS18B20的初始化(1)先将数据线置高电平“1”。

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

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

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

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

(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。

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

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

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

2、DS18B20的写操作(1)数据线先置低电平“0”。

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

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

(4)延时时间为62(大于60)微秒。

(5)将数据线拉到高电平,延时2(小于15)微秒。

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

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

3、 DS18B20的读操作(1)将数据线拉高“1”。

(2)延时2微秒。

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

(4)延时2(小于15)微秒。

(5)将数据线拉高“1”,同时端口应为输入状态。

(6)延时4(小于15)微秒。

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

(8)延时62(大于60)微秒。

顺便把程序也贴上来吧,给大家参考下。

使用的方法:只要调用一次 ds18b20_start() 来初始化DS18B20,然后每次读温度时直接调用 ds18b20_read()就可以了。

如ds18b20_start();while(1){for(i=1000000;i>0;i--);val = ds18b20_read();}1//========================================================23// By ligh45//========================================================67#include "STM32Lib//"8#include ""9101112#define EnableINT()13#define DisableINT()1415#define DS_PORT GPIOA16#define DS_DQIO GPIO_Pin_117#define DS_RCC_PORT RCC_APB2Periph_GPIOA18#define DS_PRECISION 0x7f //精度配置寄存器 1f=9位; 3f=10位; 5f=11位; 7f=12位; 19#define DS_AlarmTH 0x6420#define DS_AlarmTL 0x8a21#define DS_CONVERT_TICK 10002223#define ResetDQ() GPIO_ResetBits(DS_PORT,DS_DQIO)24#define SetDQ() GPIO_SetBits(DS_PORT,DS_DQIO)25#define GetDQ() GPIO_ReadInputDataBit(DS_PORT,DS_DQIO)262728static unsigned charTempX_TAB[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x0 9,0x09};293031void Delay_us(u32 Nus)32{33 SysTick->LOAD=Nus*9; //时间加载34 SysTick->CTRL|=0x01; //开始倒数35while(!(SysTick->CTRL&(1<<16))); //等待时间到达36 SysTick->CTRL=0X00000000; //关闭计数器37 SysTick->VAL=0X00000000; //清空计数器38}39404143{44 unsigned char resport;45 SetDQ();46 Delay_us(50);4748 ResetDQ();49 Delay_us(500); //500us (该时间的时间范围可以从480到960微秒)50 SetDQ();51 Delay_us(40); //40us52 //resport = GetDQ();53while(GetDQ());54 Delay_us(500); //500us55 SetDQ();56return resport;57}5859void DS18B20WriteByte(unsigned char Dat)60{61 unsigned char i;62for(i=8;i>0;i--)63 {64 ResetDQ(); //在15u内送数到数据线上,DS18B20在15-60u读数65 Delay_us(5); //5us66if(Dat & 0x01)67 SetDQ();68else69 ResetDQ();70 Delay_us(65); //65us71 SetDQ();73 Dat >>= 1;74 }75}767778unsigned char DS18B20ReadByte(void)79{80 unsigned char i,Dat;81 SetDQ();82 Delay_us(5);83for(i=8;i>0;i--)84 {85 Dat >>= 1;86 ResetDQ(); //从读时序开始到采样信号线必须在15u内,且采样尽量安排在15u的最后87 Delay_us(5); //5us88 SetDQ();89 Delay_us(5); //5us90if(GetDQ())91 Dat|=0x80;92else93 Dat&=0x7f;94 Delay_us(65); //65us95 SetDQ();96 }97return Dat;98}99100101void ReadRom(unsigned char *Read_Addr)103 unsigned char i;104105 DS18B20WriteByte(ReadROM);106107for(i=8;i>0;i--)108 {109 *Read_Addr=DS18B20ReadByte();110 Read_Addr++;111 }112}113114115void DS18B20Init(unsigned char Precision,unsigned char AlarmTH,unsigned char AlarmTL) 116{117 DisableINT();118 ResetDS18B20();119 DS18B20WriteByte(SkipROM);120 DS18B20WriteByte(WriteScratchpad);121 DS18B20WriteByte(AlarmTL);122 DS18B20WriteByte(AlarmTH);123 DS18B20WriteByte(Precision);124125 ResetDS18B20();126 DS18B20WriteByte(SkipROM);127 DS18B20WriteByte(CopyScratchpad);128 EnableINT();129130while(!GetDQ()); //等待复制完成 ///////////131}134void DS18B20StartConvert(void)135{136 DisableINT();137 ResetDS18B20();138 DS18B20WriteByte(SkipROM);139 DS18B20WriteByte(StartConvert);140 EnableINT();141}142143void DS18B20_Configuration(void)144{145 GPIO_InitTypeDef GPIO_InitStructure;146147 RCC_APB2PeriphClockCmd(DS_RCC_PORT, ENABLE);148149 = DS_DQIO;150 = GPIO_Mode_Out_OD; //开漏输出151 = GPIO_Speed_50MHz; //2M时钟速度152 GPIO_Init(DS_PORT, &GPIO_InitStructure);153}154155156void ds18b20_start(void)157{158 DS18B20_Configuration();159 DS18B20Init(DS_PRECISION, DS_AlarmTH, DS_AlarmTL); 160 DS18B20StartConvert();161}164unsigned short ds18b20_read(void)165{166 unsigned char TemperatureL,TemperatureH;167 unsigned int Temperature;168169 DisableINT();170 ResetDS18B20();171 DS18B20WriteByte(SkipROM);172 DS18B20WriteByte(ReadScratchpad);173 TemperatureL=DS18B20ReadByte();174 TemperatureH=DS18B20ReadByte();175 ResetDS18B20();176 EnableINT();177178if(TemperatureH & 0x80)179 {180 TemperatureH=(~TemperatureH) | 0x08;181 TemperatureL=~TemperatureL+1;182if(TemperatureL==0)183 TemperatureH+=1;184 }185186 TemperatureH=(TemperatureH<<4)+((TemperatureL&0xf0)>>4); 187 TemperatureL=TempX_TAB[TemperatureL&0x0f];188189 //bit0-bit7为小数位,bit8-bit14为整数位,bit15为正负位190 Temperature=TemperatureH;191 Temperature=(Temperature<<8) | TemperatureL;193 DS18B20StartConvert();194195return Temperature;196}197198199200201202//============================================203204//205206//============================================207208#ifndef __DS18B20_H209#define __DS18B20_H210211#define SkipROM 0xCC //跳过ROM212#define SearchROM 0xF0 //搜索ROM213#define ReadROM 0x33 //读ROM214#define MatchROM 0x55 //匹配ROM215#define AlarmROM 0xEC //告警ROM216217#define StartConvert 0x44 //开始温度转换,在温度转换期间总线上输出0,转换结束后输出1218#define ReadScratchpad 0xBE //读暂存器的9个字节219#define WriteScratchpad 0x4E //写暂存器的温度告警TH和TL220#define CopyScratchpad 0x48 //将暂存器的温度告警复制到EEPROM,在复制期间总线上输221#define RecallEEPROM 0xB8 //将EEPROM的温度告警复制到暂存器中,复制期间输出0,复制完成后输出1222#define ReadPower 0xB4 //读电源的供电方式:0为寄生电源供电;1为外部电源供电223224225void ds18b20_start(void);226unsigned short ds18b20_read(void);227228229#endif。

相关文档
最新文档