#include <AT89X51.h>
#include <intrins.h>
#define TMPort P1_7
unsigned char MYWD[7]={0,0,0,0,0,'`','C'},DS1820ERR[]="NO DS1820!",TMCL[]={"TMCL"};
unsigned char disbuf[10]={0};
unsigned char trance=0,recived=0,comno=0,comzf;//发送状态、接受命令字符序号、接收的字符
unsigned int t;
bit DS1820ON,readtm;//DS1820响应、是否接收测温命令。
void initUart(void)//波特率9600,24M时钟
{
TMOD|=0x20;
SCON=0x50;
PCON|=0x80;
TH1=0xf3;
TL1=0xf3;
TR1=1;
ES=1;
}
void uart(void) interrupt 4
{
unsigned char m=0;
if(RI)
{comzf=SBUF;RI=0;recived=1;}
else
{TI=0;trance=1;}
}
void Delay_110(void) //延时110微秒,24M晶振
{EA=0;
#pragma asm
MOV R0,#34H
MOV R1,#02H
TSR2:
DJNZ R0,TSR2
MOV R0,#34H
DJNZ R1,TSR2
#pragma endasm
EA=1;}
void Delay_510(void) //延时510微秒,24M晶振
{EA=0;
#pragma asm
nop
nop
MOV R0,#7DH
MOV R1,#04H
TSR1:
DJNZ R0,TSR1
MOV R0,#7DH
DJNZ R1,TSR1
#pragma endasm
EA=1;}
void InitDS1820(void) //初始化DS1820
{ EA=0;
TMPort = 1; //拉高TMPort
_nop_();//保持一个周期
_nop_();
TMPort = 0; //拉低TMPort
Delay_510(); //延时 DS1820复位时间要500us的低电平
TMPort = 1; //拉高TMPort
Delay_110(); //延时110us 等待DS1820回应
if (!TMPort) //回应信号为低电平
{DS1820ON=1;}
else
{DS1820ON=0;}
Delay_110(); //延时
Delay_110();
TMPort=1; //拉高TMPort
EA=1;
}
void ds1820command(unsigned char a) //写ds1820命令函数。
{
EA=0;
#pragma asm
MOV A,R7
MOV R2,#8
CLR C
WR1:
CLR TMPort
MOV R3,#2//延时3us,24M时钟
DJNZ R3,$
RRC A
MOV TMPort,C
MOV R3,#68//延时70us
DJNZ R3,$
SETB TMPort
NOP
NOP
NOP
NOP
DJNZ R2,WR1
SETB TMPort
#pragma endasm
EA=1;}
void ds1820rd(unsigned char *pt)//读ds1820数据
{
EA=0;
#pragma asm
MOV R4,#9
MOV A,R1
MOV R0,A
RD18201:
MOV R2,#8
RD18202:
SETB TMPort
NOP//延时2us,24M时钟
NOP
NOP
NOP
CLR TMPort//写时间片开始
NOP//延时2us,24M时钟
NOP
NOP
NOP
SETB TMPort//置为高电平,准备输入数据
MOV R3,#10//延时11us,24M时钟
DJNZ R3,$
MOV C,TMPort
RRC A
MOV R3,#48//延时50us,24M时钟
DJNZ R3,$
DJNZ R2,RD18202
MOV @R0,A
INC R0
DJNZ R4,RD18201
#pragma endasm
EA=1;}
void tmtoc (void)
{
unsigned char sign;//符号、实际温度的10倍整数
int tm; //实际温度的10倍
sign=disbuf[1]&0x20;
if (sign)//disbuf[1]高五位为符号位,判断符号根据补码存储方式,得出真实温度
{disbuf[0]=~disbuf[0];//精确到0.1度,四舍五入
disbuf[1]=~disbuf[1];
tm=((int)disbuf[1]*256+(int)disbuf[0]+1)*0.625+0.5;}
else tm=((int)disbuf[1]*256+(int)disbuf[0])*0.625+0.5;
//tmof10=(int)tm;//输出温度各位的ASCii码
if (tm>=1000) MYWD[0]='1';
else if (sign) MYWD[0]='-';
else MYWD[0]='+';
MYWD[1]=tm/100%10+'0';
if (MYWD[0]=='0'&&MYWD[1]=='0')MYWD[1]='\0';
MYWD[2]=tm/10%10+'0';
MYWD[3]='.';
MYWD[4]=tm%10+'0';
}
void disp(char *p,unsigned char m) //输出一个字符数组,p为数组名,m为字符个数
{
unsigned char i;
i=EA;
EA=1;
for(;*p!=0&&m!=0;p++,m--)
{
SBUF=*p;
while(trance==0);
trance=0;
}
EA=i;
}
void TMCLSHOW(void)
{
InitDS1820();//发出启动转化温度指令:初始化、skiprom、启动转化
if (!DS1820ON) {disp(DS1820ERR,12);}
ds1820command(0xCC);
ds1820command(0x44);
TMPort=1;
for (t=0;t<1500;t++) Delay_510();//等待转化过程完成
InitDS1820();//读RAM中数据:初始化、skiprom、读命令、保存数据
ds1820command(0xcc);
ds1820command(0xbe);
ds1820rd(disbuf);
//disp(disbuf,9);
tmtoc();
disp("NOW,temperature is:",20);
disp(MYWD,7);
disp("\n",1);
}
void main(void)
{
DS1820ON=0; //DS1820是否存在
initUart();
InitDS1820();//发出启动转化温度指令:初始化、skiprom、启动转化
if (!DS1820ON) {disp(DS1820ERR,12);}
P1=0x55;
TMCLSHOW();
P1=0x33;
EA=1;
while (1)
if (recived==1)//判断是否为温度测量命令
{if(comzf==TMCL[comno])
{comno++;
if (comno>3)
{comno=0;
TMCLSHOW();
}
}
else comno=0;
recived=0;
}
}
评论0