C51---13 DS18B20温度传感器
C51---13 DS18B20温度传感器
- DS18B20介绍
- 引脚及电路
- 内部结构图
- 存储器的结构
- 单总线介绍
- 单总线电路规范
- 单总线时序结构❗
- DS18B20操作流程
- DS18B20数据帧
- 温度存储格式
- DS18B20温度读取✨
- 代码
- main.c
- DS18B20.c
- oneWire.c
- 实验结果
- DS18B20温度报警✨
- 代码
- main.c
- DS18B20.c
- key.c
- timer0.c
- onewire.c
- AT24C02.C
- I2C.c
- 实验结果
DS18B20介绍
引脚及电路
内部结构图
存储器的结构
单总线介绍
单总线电路规范
单总线时序结构❗
DS18B20操作流程
DS18B20数据帧
温度存储格式
DS18B20温度读取✨
在LCD上显示温度
代码
main.c
#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"float T;void main()
{DS18B20_ConvertT(); //上电先转换一次温度,防止第一次读数据错误Delay(1000); //等待转换完成LCD_Init();LCD_ShowString(1,1,"Temperature:");while(1){DS18B20_ConvertT(); //转换温度T=DS18B20_ReadT(); //读取温度if(T<0) //如果温度小于0{LCD_ShowChar(2,1,'-'); //显示负号T=-T; //将温度变为正数}else //如果温度大于等于0{LCD_ShowChar(2,1,'+'); //显示正号}LCD_ShowNum(2,2,T,3); //显示温度整数部分LCD_ShowChar(2,5,'.'); //显示小数点LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);//显示温度小数部分}
}
DS18B20.c
#include <REGX52.H>
#include "OneWire.h"//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE/*** @brief DS18B20开始温度变换* @param 无* @retval 无*/
void DS18B20_ConvertT(void)
{OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_CONVERT_T);
}/*** @brief DS18B20读取温度* @param 无* @retval 温度数值*/
float DS18B20_ReadT(void)
{unsigned char TLSB,TMSB;int Temp;float T;OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_READ_SCRATCHPAD);TLSB=OneWire_ReceiveByte();TMSB=OneWire_ReceiveByte();Temp=(TMSB<<8)|TLSB;T=Temp/16.0;return T;
}
oneWire.c
#include <REGX52.H>//引脚定义
sbit OneWire_DQ=P3^7;/*** @brief 单总线初始化* @param 无* @retval 从机响应位,0为响应,1为未响应*/
unsigned char OneWire_Init(void)
{unsigned char i;unsigned char AckBit;OneWire_DQ=1;OneWire_DQ=0;i = 247;while (--i); //Delay 500usOneWire_DQ=1;i = 32;while (--i); //Delay 70usAckBit=OneWire_DQ;i = 247;while (--i); //Delay 500usreturn AckBit;
}/*** @brief 单总线发送一位* @param Bit 要发送的位* @retval 无*/
void OneWire_SendBit(unsigned char Bit)
{unsigned char i;OneWire_DQ=0;i = 4;while (--i); //Delay 10usOneWire_DQ=Bit;i = 24;while (--i); //Delay 50usOneWire_DQ=1;
}/*** @brief 单总线接收一位* @param 无* @retval 读取的位*/
unsigned char OneWire_ReceiveBit(void)
{unsigned char i;unsigned char Bit;OneWire_DQ=0;i = 2;while (--i); //Delay 5usOneWire_DQ=1;i = 2;while (--i); //Delay 5usBit=OneWire_DQ;i = 24;while (--i); //Delay 50usreturn Bit;
}/*** @brief 单总线发送一个字节* @param Byte 要发送的字节* @retval 无*/
void OneWire_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){OneWire_SendBit(Byte&(0x01<<i));}
}/*** @brief 单总线接收一个字节* @param 无* @retval 接收的一个字节*/
unsigned char OneWire_ReceiveByte(void)
{unsigned char i;unsigned char Byte=0x00;for(i=0;i<8;i++){if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}}return Byte;
}
实验结果
DS18B20温度报警✨
按键设置温度阈值
key1 最高温度+1
key2 最高温度- 1
key3 最低温度+1
key4 最低温度- 1
当温度超出最高温度 或者 低于最低温度时 将在LCD上显示报警
代码
main.c
#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Key.h"
#include "Timer0.h"float T,TShow;
char TLow,THigh;
unsigned char KeyNum;void main()
{DS18B20_ConvertT(); //上电先转换一次温度,防止第一次读数据错误Delay(1000); //等待转换完成THigh=AT24C02_ReadByte(0); //读取温度阈值数据TLow=AT24C02_ReadByte(1);if(THigh>125 || TLow<-55 || THigh<=TLow){THigh=20; //如果阈值非法,则设为默认值TLow=15;}LCD_Init();LCD_ShowString(1,1,"T:");LCD_ShowString(2,1,"TH:");LCD_ShowString(2,9,"TL:");LCD_ShowSignedNum(2,4,THigh,3);LCD_ShowSignedNum(2,12,TLow,3);Timer0_Init();while(1){KeyNum=Key();/*温度读取及显示*/DS18B20_ConvertT(); //转换温度T=DS18B20_ReadT(); //读取温度if(T<0) //如果温度小于0{LCD_ShowChar(1,3,'-'); //显示负号TShow=-T; //将温度变为正数}else //如果温度大于等于0{LCD_ShowChar(1,3,'+'); //显示正号TShow=T;}LCD_ShowNum(1,4,TShow,3); //显示温度整数部分LCD_ShowChar(1,7,'.'); //显示小数点LCD_ShowNum(1,8,(unsigned long)(TShow*100)%100,2);//显示温度小数部分/*阈值判断及显示*/if(KeyNum){if(KeyNum==1) //K1按键,THigh自增{THigh++;if(THigh>125){THigh=125;}}if(KeyNum==2) //K2按键,THigh自减{THigh--;if(THigh<=TLow){THigh++;}}if(KeyNum==3) //K3按键,TLow自增{TLow++;if(TLow>=THigh){TLow--;}}if(KeyNum==4) //K4按键,TLow自减{TLow--;if(TLow<-55){TLow=-55;}}LCD_ShowSignedNum(2,4,THigh,3); //显示阈值数据LCD_ShowSignedNum(2,12,TLow,3);AT24C02_WriteByte(0,THigh); //写入到At24C02中保存Delay(5);AT24C02_WriteByte(1,TLow);Delay(5);}if(T>THigh) //越界判断{LCD_ShowString(1,13,"OV:H");}else if(T<TLow){LCD_ShowString(1,13,"OV:L");}else{LCD_ShowString(1,13," ");}}
}void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值T0Count++;if(T0Count>=20){T0Count=0;Key_Loop(); //每20ms调用一次按键驱动函数}
}
DS18B20.c
#include <REGX52.H>
#include "OneWire.h"//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE/*** @brief DS18B20开始温度变换* @param 无* @retval 无*/
void DS18B20_ConvertT(void)
{OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_CONVERT_T);
}/*** @brief DS18B20读取温度* @param 无* @retval 温度数值*/
float DS18B20_ReadT(void)
{unsigned char TLSB,TMSB;int Temp;float T;OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_READ_SCRATCHPAD);TLSB=OneWire_ReceiveByte();TMSB=OneWire_ReceiveByte();Temp=(TMSB<<8)|TLSB;T=Temp/16.0;return T;
}
key.c
#include <REGX52.H>
#include "Delay.h"unsigned char Key_KeyNumber;/*** @brief 获取按键键码* @param 无* @retval 按下按键的键码,范围:0,1~4,0表示无按键按下*/
unsigned char Key(void)
{unsigned char Temp=0;Temp=Key_KeyNumber;Key_KeyNumber=0;return Temp;
}/*** @brief 获取当前按键的状态,无消抖及松手检测* @param 无* @retval 按下按键的键码,范围:0,1~4,0表示无按键按下*/
unsigned char Key_GetState()
{unsigned char KeyNumber=0;if(P3_1==0){KeyNumber=1;}if(P3_0==0){KeyNumber=2;}if(P3_2==0){KeyNumber=3;}if(P3_3==0){KeyNumber=4;}return KeyNumber;
}/*** @brief 按键驱动函数,在中断中调用* @param 无* @retval 无*/
void Key_Loop(void)
{static unsigned char NowState,LastState;LastState=NowState; //按键状态更新NowState=Key_GetState(); //获取当前按键状态//如果上个时间点按键按下,这个时间点未按下,则是松手瞬间,以此避免消抖和松手检测if(LastState==1 && NowState==0){Key_KeyNumber=1;}if(LastState==2 && NowState==0){Key_KeyNumber=2;}if(LastState==3 && NowState==0){Key_KeyNumber=3;}if(LastState==4 && NowState==0){Key_KeyNumber=4;}
}
timer0.c
#include <REGX52.H>/*** @brief 定时器0初始化,1毫秒@12.000MHz* @param 无* @retval 无*/
void Timer0_Init(void)
{TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0=1;EA=1;PT0=0;
}/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值T0Count++;if(T0Count>=1000){T0Count=0;}
}
*/
onewire.c
#include <REGX52.H>//引脚定义
sbit OneWire_DQ=P3^7;/*** @brief 单总线初始化* @param 无* @retval 从机响应位,0为响应,1为未响应*/
unsigned char OneWire_Init(void)
{unsigned char i;unsigned char AckBit;EA=0;OneWire_DQ=1;OneWire_DQ=0;i = 247;while (--i); //Delay 500usOneWire_DQ=1;i = 32;while (--i); //Delay 70usAckBit=OneWire_DQ;i = 247;while (--i); //Delay 500usEA=1;return AckBit;
}/*** @brief 单总线发送一位* @param Bit 要发送的位* @retval 无*/
void OneWire_SendBit(unsigned char Bit)
{unsigned char i;EA=0;OneWire_DQ=0;i = 4;while (--i); //Delay 10usOneWire_DQ=Bit;i = 24;while (--i); //Delay 50usOneWire_DQ=1;EA=1;
}/*** @brief 单总线接收一位* @param 无* @retval 读取的位*/
unsigned char OneWire_ReceiveBit(void)
{unsigned char i;unsigned char Bit;EA=0;OneWire_DQ=0;i = 2;while (--i); //Delay 5usOneWire_DQ=1;i = 2;while (--i); //Delay 5usBit=OneWire_DQ;i = 24;while (--i); //Delay 50usEA=1;return Bit;
}/*** @brief 单总线发送一个字节* @param Byte 要发送的字节* @retval 无*/
void OneWire_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){OneWire_SendBit(Byte&(0x01<<i));}
}/*** @brief 单总线接收一个字节* @param 无* @retval 接收的一个字节*/
unsigned char OneWire_ReceiveByte(void)
{unsigned char i;unsigned char Byte=0x00;for(i=0;i<8;i++){if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}}return Byte;
}
AT24C02.C
#include <REGX52.H>
#include "I2C.h"#define AT24C02_ADDRESS 0xA0/*** @brief AT24C02写入一个字节* @param WordAddress 要写入字节的地址* @param Data 要写入的数据* @retval 无*/
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_SendByte(Data);I2C_ReceiveAck();I2C_Stop();
}/*** @brief AT24C02读取一个字节* @param WordAddress 要读出字节的地址* @retval 读出的数据*/
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(AT24C02_ADDRESS|0x01);I2C_ReceiveAck();Data=I2C_ReceiveByte();I2C_SendAck(1);I2C_Stop();return Data;
}
I2C.c
#include <REGX52.H>//引脚定义
sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;/*** @brief I2C开始* @param 无* @retval 无*/
void I2C_Start(void)
{I2C_SDA=1;I2C_SCL=1;I2C_SDA=0;I2C_SCL=0;
}/*** @brief I2C停止* @param 无* @retval 无*/
void I2C_Stop(void)
{I2C_SDA=0;I2C_SCL=1;I2C_SDA=1;
}/*** @brief I2C发送一个字节* @param Byte 要发送的字节* @retval 无*/
void I2C_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){I2C_SDA=Byte&(0x80>>i);I2C_SCL=1;I2C_SCL=0;}
}/*** @brief I2C接收一个字节* @param 无* @retval 接收到的一个字节数据*/
unsigned char I2C_ReceiveByte(void)
{unsigned char i,Byte=0x00;I2C_SDA=1;for(i=0;i<8;i++){I2C_SCL=1;if(I2C_SDA){Byte|=(0x80>>i);}I2C_SCL=0;}return Byte;
}/*** @brief I2C发送应答* @param AckBit 应答位,0为应答,1为非应答* @retval 无*/
void I2C_SendAck(unsigned char AckBit)
{I2C_SDA=AckBit;I2C_SCL=1;I2C_SCL=0;
}/*** @brief I2C接收应答位* @param 无* @retval 接收到的应答位,0为应答,1为非应答*/
unsigned char I2C_ReceiveAck(void)
{unsigned char AckBit;I2C_SDA=1;I2C_SCL=1;AckBit=I2C_SDA;I2C_SCL=0;return AckBit;
}
实验结果
C51---13 DS18B20温度传感器相关推荐
- 基于C51单片机+DS18B20温度传感器+LCD1602显示器的智能水温控制系统(PID)
基于AT89C52的温度控制系统 一.DS18B20传感器相关介绍 DS18B20特性 封装形式与引脚说明 供电方式(外部电源供电.寄生电源供电.寄生电源强上拉) DS18B20指令(ROM指令操作) ...
- 【ESP32】13.DS18B20温度传感器实验(OneWire和DallasTemperature库)
上一篇: [ESP32]12.I2C LCD1602液晶显示实验(LiquidCrystal_I2C库) 前言: 先放电路连接图: DS18B20是单总线温度传感器.比较有特色的是该模块仅仅需要一个接 ...
- 智能温度系统(C51+DS18B20温度传感器+LM016L显示屏)
单片机课程设计,C51+DS18B20温度传感器+LM016L显示屏 重点在于两个外设的时序控制 模块化的设计结构清晰明了 一.题目 温度测量系统的设计 二.要求 1.温度测量范围:-55℃ ~ 12 ...
- 【C51单片机学习笔记----DS18B20温度传感器LCD1602液晶屏直流电机调速与呼吸灯AD模数转换红外外部中断】
文章目录 一.DS18B20温度传感器 1.DS18B20温度传感器连接原理图 2.DS18B20温度传感器单总线通信时序 3.DS18B20温度传感器代码模块 二.LCD1602液晶屏 1.LCD1 ...
- 【51单片机】AT24C02存储器(I²C总线)/DS18B20温度传感器(单总线)
目录 一.AT24C02存储器 1.AT24C02存储器介绍 2.存储器简化模型 3.AT24C02存储器原理图 二.I²C总线 1.I²C总线的介绍 2.I²C电路 3.I²C时序图 3.1I²C开 ...
- STC15系列读取DS18B20温度传感器串口显示代码
STC15系列读取DS18B20温度传感器串口显示代码 调试通过,复制粘贴即编译可使用,无需调试,晶振:22.1184M,串口输出,波特率:115200 为方便大家调试,特附该程序的项目文件,下载打开 ...
- java 获取温度_Java利用RXTX串口通信工具类获取DS18B20温度传感器的温度值
环境:Windows10,Eclipse4.5.2,JDK1.7 设备:DS18B20温度传感器(4线,485接口),USB转485接口转换器,笔记本电脑 注意点:RTU传输,使用的是字节,那么在程序 ...
- DS18B20温度传感器FPGA实现
一. 简介 通过原理图可以看出,DS18B20温度传感器只有一条总线,可想而知,其结构的简单化,导致了其操作的复杂化. 更多关于该传感器的一些特性参数,以及性能指标,可以详细阅读官网提供的数据手册. ...
- 嵌入式设计与开发项目-DS18B20温度传感器程序设计
嵌入式设计与开发项目-DS18B20温度传感器程序设计 一.实现的功能 二.根据功能实现代码 1.主文件main.c 2.DS18B20的头文件"ds18b20.h" 3.DS18 ...
最新文章
- InputStream、OutputStream、String的相互转换(转)
- C++11 - 返回类型后置
- linux 键盘记录,学习笔记 kali linux 关于MS17-101漏洞攻击与键盘记录
- cp210x驱动怎么安装_电脑声卡驱动怎么安装,教你三步搞定声卡驱动
- c语言之图形编程 pdf,《C语言图形编程》.pdf
- Altium Designer 21 实例贴片0603封装的创建
- 如何在EDEM中添加颗粒的bond
- 电脑从windows变成linux,从Windows换到Linux下来
- 很好用的搜网盘资源工具。很多都能找到
- 点击图标分享页面到QQ,微信,微博 等
- 掌握Android图像显示原理(中)
- 主流智能手机屏幕材质介绍
- 苹果听天由命 未雇佣游说公司处理欧盟补税案
- Talk预告 | 微软亚洲研究院王希廷:基于逻辑规则推理的深度自可解释模型
- linux 下dump文件放在那里,怎么查看dump文件目录
- 过滤器与拦截器的区别?
- 3.1 详细讲解直线段工具 [Illustrator CC教程]
- H5之外部浏览器访问微信客户端网页
- Git命令问题:Found a swap file by the name “.git/.MERGE_MSG.swp”
- 南方科技大学计算机学院怎么样,南方科技大学和深圳大学,哪个实力更强?一起来看看吧!...
热门文章
- YOLOV7详细解读(一)网络架构解读
- vue中遍历呈现数据
- Free Video to JPG Converter(视频转图片的软件)简体中文版V5.0.101.201 | 如何将视频转图片
- k6新一代性能测试工具
- 【poj1013】 Counterfeit Dollar
- 【实战】1341- 仿【得物】微信小程序实战全教程
- 异常java.io.NotSerializableException
- 【Introduction to Artificial Intelligence and Data Analytics】(TBC)
- 开发过程中 勘误表errata注意事项
- Winbond W25Q128JVSIQ 串行闪存