蓝桥杯之单片机学习(十五)——DS18B20的基本应用
·
一、DS18B20的温度转换与读取流程
- DS18B20复位
- 写入字节0XCC,跳过ROM指令
- 写入字节0X44,开始温度转换
- 延时700-900ms
- DS18B20复位
- 写入字节0XCC,跳过ROM指令
- 写入字节0XBE,读取高速暂存器
- 读取暂存器的第0字节,即温度数据的LSB
- 读取暂存器的第1字节,即温度数据的MSB
- DS18B20复位,表示读取数据结束
- 将LSB和MSB整合成为一个16位数据
- 判断读取结果的符号进行正负温度的数据读取
二、DS18B20的数据处理
- DS18B20以16位带符号位扩展的二进制补码形式读出
- 低4位为小数部分,中间7位为整数部分,高5位为符号位

- DS18B20的分辨率为0.0625。读出数据为正温度时,将LSB和MSB整合成的16位整数,直接乘以0.0625即可。读出数据为负温度时,则需要将LSB和MSB整合成的16位整数,取反加1后,再乘以0.0625
- 注意:在上电复位的时候,温度寄存器中的值为0X0550,即**+85**摄氏度
三、代码展示
main.c
#include "reg52.h"
#include "onewire.h"
typedef unsigned int uint;
typedef unsigned char uchar;
uint temp = 0;
uchar SMG_duanma[18] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};//分别是0-9(对应下标),A-F,“-”,“.”
uchar SMGDot_AC[10] =
{0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//配置HC138
void SelectHC138(uchar channel)
{
switch(channel)
{
case 4: //LED
P2 = (P2 & 0X1F) | 0X80;
break;
case 5: //蜂鸣器和继电器
P2 = (P2 & 0X1F) | 0Xa0;
break;
case 6: //位码
P2 = (P2 & 0X1F) | 0Xc0;
break;
case 7: //段码
P2 = (P2 & 0X1F) | 0Xe0;
break;
case 0: //锁住所有寄存器
P2 = (P2 & 0X1F) | 0X00;
break;
}
}
void Delay_SMG(uint t)
{
while(t--);
}
//在pos位码上,显示value段码
void DisplaySMG_Bit(uchar pos, uchar value)
{
SelectHC138(6);
P0 = 0X01 << pos;
SelectHC138(7);
P0 = value;
}
void Initsys()
{
SelectHC138(5);
P0 = 0X00;//关闭蜂鸣器和继电器
SelectHC138(4);
P0 = 0XFF;//关闭LED
}
void Display_All(uchar dat)
{
SelectHC138(6);
P0 = 0XFF;
SelectHC138(7);
P0 = dat;
}
void DisplaySMG_Temp()
{
DisplaySMG_Bit(7,SMG_duanma[temp % 10]);
Delay_SMG(100);
DisplaySMG_Bit(6,SMGDot_AC[(temp % 100) / 10]);
Delay_SMG(100);
DisplaySMG_Bit(5,SMG_duanma[temp / 100]);
Delay_SMG(100);
DisplaySMG_Bit(4,0XFF);
Delay_SMG(100);
DisplaySMG_Bit(3,0XFF);
Delay_SMG(100);
DisplaySMG_Bit(2,0XFF);
Delay_SMG(100);
DisplaySMG_Bit(1,0XFF);
Delay_SMG(100);
DisplaySMG_Bit(0,0XFF);
Delay_SMG(100);
Display_All(0XFF);
}
void Delay_temp(uint t)
{
while(t--)
{
DisplaySMG_Temp();
}
}
//**********************读取温度***************************/
void read_DS18B20_temp()
{
uchar LSB,MSB; //LSB低八位,MSB高八位
//温度转换
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0x44); //开始温度转换
Delay_OneWire(200); //等待温度转换完成
//读温度
init_ds18b20(); //初始化DS18B20
Write_DS18B20(0xcc); //跳过ROM
Write_DS18B20(0xbe); //开始读温度
//读温度
LSB = Read_DS18B20(); //读取低八位数据
MSB = Read_DS18B20(); //读取高八位数据
temp = MSB;
temp <<= 8; //高八位右移8位
temp = temp | LSB; //将独立的高、低8位合并为16位
if((temp & 0xf800) == 0x0000) //判断temp的高五位来判断温度的正负,高5位全为0表示为正,全为1表示负
{
temp >>= 4;
temp = temp * 10; //temp先右移四位在乘上10相当于整数部分乘以0.625倍
temp = temp + (LSB & 0x0f) * 0.625; //整数部分 * 0.625 + 小数部分 *0.625
}
}
void main()
{
Initsys();
while(1)
{
read_DS18B20_temp();
DisplaySMG_Temp();
}
}
onewire.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(50);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(50);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(50);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(120);
DQ = 0;
Delay_OneWire(800);
DQ = 1;
Delay_OneWire(100);
initflag = DQ;
Delay_OneWire(50);
return initflag;
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
Delay_OneWire(uint);
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
#endif
更多推荐


所有评论(0)