#include "reg51.h"
#include"absacc.h"
#include"math.h"
#include "string.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define uint unsigned int
#define uchar unsigned char
#define FOSC 11059200L
#define BAUD 115200
BYTE ah,al;
BYTE temp;
bit send_busy;
char temperature[2]; //存放温度数据
int nun;
uchar code addnum1 []={0xf8, 0x00, 0x14, 0x51, 0x1f, 0x9e, 0xff, 0x28};//0b 00 14 51 20 92 ff 28
uchar code addnum2 []={0x32, 0x03, 0x15, 0xa1, 0x6d, 0x53, 0xff, 0x28};//7d 04 15 a1 53 fd ff 28
uchar code addnum3 []={0x0c, 0x00, 0x00, 0x04, 0xe5, 0x53, 0xc0, 0x28};//0c 00 00 04 e5 53 c0 28
float wen_val;
sbit b=P2^0;
sbit c=P2^1;
sbit d=P2^2;
sbit DS1820_DQ= P1^7; //单总线引脚
void DS18B20_Init() ; //DS18B20 初始化
bit DS1820_Reset(); //DS1820 复位
void DS1820_WriteData(BYTE wData); //写数据到DS1820
BYTE DS1820_ReadData(); //读数据
int a,n=0;
void read_wendu();
void DelayXus(WORD n);
void Delay2(WORD n);
/**********************************************************
*DS18B20 初始化
*函数名称:DS1820_WriteData()
*说明:本初始化程序可以不要,因为18B20 在出厂时就被配置为12 位精度了
**********************************************************/
void DS18B20_Init()
{
DS1820_Reset();
DS1820_WriteData(0xCC); // 跳过ROM
DS1820_WriteData(0x4E); // 写暂存器
DS1820_WriteData(0x20); // 往暂存器的第三字节中写上限值
DS1820_WriteData(0x00); // 往暂存器的第四字节中写下限值
DS1820_WriteData(0x7F); // 将配置寄存器配置为12 位精度
DS1820_Reset();
}
/**********************************************************
*DS1820 复位及存在检测(通过存在脉冲可以判断DS1820 是否损坏)
*函数名称:DS1820_Reset()
*说明:函数返回一个位标量(0 或1)flag=0 存在,反之flag=1 不存在
**********************************************************/
bit DS1820_Reset()
{
bit flag;
DS1820_DQ = 0; //拉低总线
DelayXus(480); //延时480 微秒,产生复位脉冲
DS1820_DQ = 1; //释放总线
DelayXus(80); //延时80 微秒对总线采样
flag = DS1820_DQ; //对数据脚采样
DelayXus(400); //延时400 微秒等待总线恢复
return (flag); //根据flag 的值可知DS1820 是否存在或损坏,可加声音告警提示DS1820 故障
}
/**********************************************************
*写数据到DS1820
*函数名称:DS1820_WriteData()
**********************************************************/
void DS1820_WriteData(BYTE wData)
{
BYTE i;
for (i=8;i>0;i--)
{
DS1820_DQ = 0; //拉低总线,产生写信号
DelayXus(4); //延时4us
DS1820_DQ = wData&0x01; //发送1 位
DelayXus(60); //延时60us,写时序至少要60us
DS1820_DQ = 1; //释放总线,等待总线恢复
wData>>=1; //准备下一位数据的传送
}
}
/**********************************************************
*从DS1820 中读出数据
*函数名称:DS1820_ReadData()
**********************************************************/
BYTE DS1820_ReadData()
{
BYTE i,TmepData;
for (i=8;i>0;i--)
{
TmepData>>=1;
DS1820_DQ = 0; //拉低总线,产生读信号
DelayXus(4); //延时4us
DS1820_DQ = 1; //释放总线,准备读数据
DelayXus(8); //延时8 微秒读数据
if (DS1820_DQ == 1)
{TmepData |= 0x80;}
DelayXus(60); //延时60us
DS1820_DQ = 1; //拉高总线,准备下一位数据的读取.
}
return (TmepData);//返回读到的数据
}
/*********************************************************
*延时n 微秒程序
**********************************************************/
void DelayXus(WORD n)
{
while(--n);
}
/*********************************************************
*读取温度程序
**********************************************************/
void read_wendu()
{
BYTE i;
DS1820_Reset(); //复位
//NO 1
if(nun==1)
{
DS1820_WriteData(0x55);//发出ROM 匹配指令
for(i=8;i>0;i--)
DS1820_WriteData(addnum1[i-1]);
}
//NO 2
if(nun==2)
{
DS1820_WriteData(0x55);//发出ROM 匹配指令
for(i=8;i>0;i--)
DS1820_WriteData(addnum2[i-1]);
}
//NO 3
if(nun==3)
{
DS1820_WriteData(0x55);//发出ROM 匹配指令
for(i=8;i>0;i--)
DS1820_WriteData(addnum3[i-1]);
}
DS1820_WriteData(0x44); //温度转换命令
DS1820_Reset(); //复位
if(nun==1)
{
DS1820_WriteData(0x55);//发出ROM 匹配指令
for(i=8;i>0;i--)
DS1820_WriteData(addnum1[i-1]);
}
//NO 2
if(nun==2)
{
DS1820_WriteData(0x55);//发出ROM 匹配指令
for(i=8;i>0;i--)
DS1820_WriteData(addnum2[i-1]);
}
//NO3
if(nun==3)
{
DS1820_WriteData(0x55);//发出ROM 匹配指令
for(i=8;i>0;i--)
DS1820_WriteData(addnum3[i-1]);
}
DS1820_WriteData(0xbe); //读DS1820 温度暂存器命令
for (i=0;i<2;i++)
{
temperature[i]=DS1820_ReadData(); //采集温度
}
DS1820_Reset(); //复位,结束读数据
}
/*********************************************************
*显示温度程序
**********************************************************/
void crt_wendu()
{
read_wendu();
ah=temperature[1]<<4;
ah&=0xf0;
al=temperature[0]>>4;
al&=0x0f;
ah=ah|al;
al=temperature[0]&0x0f;
if ((ah&0x80)!=0)
{
if (al==0)
{
ah=~ah;ah=ah+1;
}
else
{
ah=~ah;al=~al;al=al+1;al&=0x0f;
}
wen_val=ah*(-1.0)+al*(-0.0625);
}
else
{
wen_val=ah*1.0+al*0.0625;
}
}
void Delay2(WORD n)
{
WORD x;
while(n--)
{
x=5000;
while(x--);
}
}
/********************************发送初始化****************************************/
void ser_init()
{
TMOD=0x20;
TH1=TL1=-(FOSC/12/32/BAUD);
SCON=0x50;
AUXR=0x15;
BRT=256-(FOSC>>5)/BAUD;
EA=1;
ES=1;
}
void ser1() interrupt 4
{
if(RI)
{
RI=0;
}
if(TI)
{
TI=0;
send_busy=0;
}
}
/******************************发送***********************************************/
void send(float t)
{
int k;
k=((int)(wen_val*t))%10;
SBUF=k;
while(send_busy);
}
/********************************接收函数****************************************/
void sers_init()
{
SCON=0x50;
AUXR=0x15;
BRT=256-(FOSC>>5)/BAUD;
EA=1;
ES=1;
}
void sers() interrupt 8
{
if(RI)
{
RI=0;
a=SBUF;
n++;
if(n==3) n=0;
}
if(TI)
{
TI=0;
}
}
/******************************接收***********************************************/
void jieshou_key()
{
a=SBUF;
if(a==1)
{
nun=1;
}
if(a==2)
{
nun=2;
}
if(a==3)
{
nun=3;
}
}
/********************************main*********************************************/
void main()
{
ser_init();
sers_init();
DS18B20_Init();
while(1)
{
crt_wendu();
send(0.1);
send(1.0);
send(10.0);
Delay2(10);
jieshou_key();
}
}