标题:
多点(八组DS18B20)温度测量的单片机仿真+代码
[打印本页]
作者:
ddddyyyy
时间:
2018-11-25 09:26
标题:
多点(八组DS18B20)温度测量的单片机仿真+代码
多点温度测量仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(18.13 KB, 下载次数: 26)
下载附件
2018-11-25 15:51 上传
单片机源程序如下:
//头文件包含
#include <AT89X51.H>
#include <Intrins.h>
#include "DS18B20.H"
//引脚定义
sbit DQ = P2^7; //数据线端口
//DS18B20序列号,通过调用GetROMSequence()函数在P1口读出(读8次)
const unsigned char code ROMData1[8] = {0x28, 0x33, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xD7}; //U1
const unsigned char code ROMData2[8] = {0x28, 0x30, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x8E}; //U2
const unsigned char code ROMData3[8] = {0x28, 0x31, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xB9}; //U3
const unsigned char code ROMData4[8] = {0x28, 0x32, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xE0}; //U4
const unsigned char code ROMData5[8] = {0x28, 0x34, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x52}; //U5
const unsigned char code ROMData6[8] = {0x28, 0x35, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x65}; //U6
const unsigned char code ROMData7[8] = {0x28, 0x36, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x3C}; //U7
const unsigned char code ROMData8[8] = {0x28, 0x37, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x0B}; //U8
//延时16us子函数
void Delay16us()
{
unsigned char a;
for (a = 0; a < 4; a++);
}
//延时60us子函数
void Delay60us()
{
unsigned char a;
for (a = 0; a < 18; a++);
}
//延时480us子函数
void Delay480us()
{
unsigned char a;
for (a = 0; a < 158; a++);
}
//延时240us子函数
void Delay240us()
{
unsigned char a;
for (a = 0; a < 78; a++);
}
//延时500ms子函数
void Delay500ms()
{
unsigned char a, b, c;
for (a = 0; a < 250; a++)
for (b = 0; b < 3; b++)
for (c = 0; c < 220; c++);
}
//芯片初始化
void Initialization()
{
while(1)
{
DQ = 0;
Delay480us(); //延时480us
DQ = 1;
Delay60us(); //延时60us
if(!DQ) //收到ds18b20的应答信号
{
DQ = 1;
Delay240us(); //延时240us
break;
}
}
}
//写一个字节(从低位开始写)
void WriteByte(unsigned char btData)
{
unsigned char i, btBuffer;
for (i = 0; i < 8; i++)
{
btBuffer = btData >> i;
if (btBuffer & 1)
{
DQ = 0;
_nop_();
_nop_();
DQ = 1;
Delay60us();
}
else
{
DQ = 0;
Delay60us();
DQ = 1;
}
}
}
//读一个字节(从低位开始读)
unsigned char ReadByte()
{
unsigned char i, btDest;
for (i = 0; i < 8; i++)
{
btDest >>= 1;
DQ = 0;
_nop_();
_nop_();
DQ = 1;
Delay16us();
if (DQ) btDest |= 0x80;
Delay60us();
}
return btDest;
}
//序列号匹配
void MatchROM(const unsigned char *pMatchData)
{
unsigned char i;
Initialization();
WriteByte(MATCH_ROM);
for (i = 0; i < 8; i++) WriteByte(*(pMatchData + i));
}
//得到64位ROM序列(在P1口显示,必须与Proteus联调且在单步调试下才能得到)
/*void GetROMSequence()
{
unsigned char i;
Initialization();
WriteByte(READ_ROM);
for (i = 0; i < 8; i++)
P1 = ReadByte();
}*/
//读取温度值
TEMPDATA ReadTemperature()
{
TEMPDATA TempData;
unsigned int iTempDataH;
unsigned char btDot, iTempDataL;
static unsigned char i = 0;
TempData.btNegative = 0; //为0温度为正
i++;
if (i == 9) i = 1;
Initialization();
WriteByte(SKIP_ROM); //跳过ROM匹配
WriteByte(TEMP_SWITCH); //启动转换
Delay500ms(); //调用一次就行
Delay500ms();
Initialization();
//多个芯片的时候用MatchROM(ROMData)换掉WriteByte(SKIP_ROM)
switch (i)
{
case 1 : MatchROM(ROMData1); break; //匹配1
case 2 : MatchROM(ROMData2); break; //匹配2
case 3 : MatchROM(ROMData3); break; //匹配3
case 4 : MatchROM(ROMData4); break; //匹配4
case 5 : MatchROM(ROMData5); break; //匹配5
case 6 : MatchROM(ROMData6); break; //匹配6
case 7 : MatchROM(ROMData7); break; //匹配7
case 8 : MatchROM(ROMData8); break; //匹配8
}
//WriteByte(SKIP_ROM); //跳过ROM匹配(单个芯片时用这句换掉上面的switch)
WriteByte(READ_MEMORY); //读数据
iTempDataL = ReadByte();
iTempDataH = ReadByte();
iTempDataH <<= 8;
iTempDataH |= iTempDataL;
if (iTempDataH & 0x8000)
{
TempData.btNegative = 1;
iTempDataH = ~iTempDataH + 1; //负数求补
}
//为了省去浮点运算带来的开销,而采用整数和小数部分分开处理的方法(没有四舍五入)
btDot = (unsigned char)(iTempDataH & 0x000F); //得到小数部分
iTempDataH >>= 4; //得到整数部分
btDot *= 5; //btDot*10/16得到转换后的小数数据
btDot >>= 3;
//数据处理
TempData.btThird = (unsigned char)iTempDataH / 100;
TempData.btSecond = (unsigned char)iTempDataH % 100 / 10;
TempData.btFirst = (unsigned char)iTempDataH % 10;
TempData.btDecimal = btDot;
return TempData;
}
复制代码
所有资料51hei提供下载:
多点温度测量.zip
(82.37 KB, 下载次数: 55)
2018-11-25 09:25 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1