嘿嘿,调了好几天终于弄好了 程序如下
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar dis[]="0123456789";
sbit rs=P1^0;
sbit lcden=P1^2;
sbit rw=P1^1;
sbit tx=P1^4;
sbit DQ=P1^3;
sbit in=P3^2;
uchar k,d;
uint date,ju,jl,O;
uchar time;
uchar TH,TL,TZ;
uchar dis1[]={"0123456789-"};
uchar temp[]={"WENDU:"};
uchar cent[]={"Cent"};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delaynus(uint n)
{
while(n--);
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void write(uchar *p)
{
while(*p)
{
write_date(*p);
p++;
}
}
bit initb(void)
{
bit flag; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在
DQ = 1; //先将数据线拉高
for(time=0;time<2;time++) //略微延时约6微秒
;
DQ = 0; //再将数据线从高拉低,要求保持480~960us
for(time=0;time<200;time++) //略微延时约600微秒
; //以向DS18B20发出一持续480~960us的低电平复位脉冲
DQ = 1; //释放数据线(将数据线拉高)
for(time=0;time<10;time++)
; //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在)
for(time=0;time<200;time++) //延时足够长时间,等待存在脉冲输出完毕
;
return (flag); //返回检测成功标志
}
void init1()
{
rw=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
// write_com(0x02);
write_com(0x80+0x40);
write("Distance");
}
void xianshi()
{
uchar t;
write_com(0x80);
for(t=0;t<5;t++)
{
write_date(temp[t]);
}
write_com(0x8a);
for(t=0;t<4;t++)
{
write_date(cent[t]);
}
}
uchar readonechar(void)
{
uchar i=0;
uchar dat; //储存读出的一个字节数据
for (i=0;i<8;i++)
{
DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
_nop_(); //等待一个机器周期
DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备
for(time=0;time<2;time++); //延时约6us,使主机在15us内采样
dat>>=1;
if(DQ==1)
dat|=0x80; //如果读到的数据是1,则将1存入dat
else
dat|=0x00;//如果读到的数据是0,则将0存入dat
//将单片机检测到的电平信号DQ存入r
for(time=0;time<8;time++); //延时3us,两个读时序之间必须有大于1us的恢复期
}
return(dat); //返回读出的十六进制数据
}
void writeonechar(uchar shu0)
{
uchar j;
for(j=0;j<8;j++)
{
DQ=1;
_nop_();
DQ=0;
DQ=shu0&0x01; //并将其送到数据线上等待DS18B20采样
delaynus(20); //延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1;
delaynus(3); //延时5us,两个写时序间至少需要1us的恢复期
shu0>>=1;
}
delaynus(12); // 稍作延时,给硬件一点反应时间
}
void readyread() //做好读温度的准备
{
initb();
writeonechar(0xcc); // 跳过读序号列号的操作
writeonechar(0x44); // 启动温度转换
delay(200); //转换一次需要延时一段时间
initb();
writeonechar(0xcc);
writeonechar(0xBE);
}
void xianshiwen(uchar shu2)
{
write_com(0x86);
write_date(dis[shu2/100]);
write_date(dis[(shu2%100)/10]);
write_date(dis[shu2%10]);
delay(50);
}
void xianshic()
{
write_com(0x80+0x49);
write_date(dis[jl/1000]);
write_date(dis[jl/100%10]);
write_date(dis[jl%100/10]);
write_date(dis[jl%10]);
write_date('m');
write_date('m');
}
void init()
{
IT0=0; //外部中断低电平触发
TMOD=0X21;
TH0=0x00;
TL0=0x00;
TH1=TL1=0xfc;
EA=1;
ET0=1;
ET1=1;
// TR1=1;
}
void init2()
{
//T2CON=0x0c;
RCAP2H=(65536-5)/256;
RCAP2L=(65536-5)%256;
TH2=(65536-5)/256;
TL2=(65536-5)%256;
EA=1;
ET2=1;
TR2=1;
// PT2=1; //T2设为高优先级
}
void main()
{
init1(); //液晶初始化
xianshi(); //温度字母
init2(); //T2初始化
tx=0;
IT0=0; //外部中断低电平触发
init(); //定时器初始化
while(1);
}
void timer1() interrupt 3
{
tx=~tx;
k++;
if(k==3)
{
k=0;
TR0=0;
TR0=1;
delaynus(6); //除共振
EX0=1;
//for(d=0;d<3;d++);
// in=0;
}
}
void int0() interrupt 0
{
IE0=0; //中断触发位
EX0=0; //关中断
TR1=0;
ET1=0;
TR0=0;
ET0=0;
date=TH0*256+TL0;
date+=500;
if(TZ>=0&&TZ<=10)
{
jl=(date*0.161);
}
if(TZ>10&&TZ<=20)
{
jl=(date*0.169);
}
if(TZ>20&&TZ<=30)
{
jl=(date*0.172);
}
if(TZ>30&&TZ<=40)
{
jl=(date*0.174);
}
if(TZ>40&&TZ<=500)
{
jl=(date*0.175);
}
xianshic();
for(d=800;d>0;d--);
TH0=0x00;
TL0=0x00;
ET1=1;
TR1=1;
O++;
if(O==100)
{
O=0;
TR1=0;
ET1=0;
TR2=1;
ET2=1;
}
}
void timer0() interrupt 1 //计时
{
TR1=0;
TR0=0;
TH0=0X00;
TL0=0X00;
TR1=1;
}
void timer2() interrupt 5
{
TF2=0;
EXF2=0;
TR2=0;
ET2=0;
// xianshi(); //温度字母
readyread();
TL=readonechar();
TH=readonechar();
TZ=TH*16+TL/16;
xianshiwen(TZ);
delay(10);
TR1=1;
ET1=1;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>