原创 单片机控制DS18B20测温度1602显示

2009-8-12 20:17 2912 3 3 分类: MCU/ 嵌入式
//管脚连接见注释,其中1602的R/W我固定了为0电平。另外,1602的VL脚最好连接电位器的可调端,以选好偏压,否则会容易出现鬼影或屏幕无显示。

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P3^3;  //连接DS18B20
sbit en=P3^5;   //连接1602 E脚
sbit rs=P3^7;   //连接1602 RS脚
//sbit rw= P3^4;  //连接1602 的R/W脚,可选择是否编译
uchar code table[]="TEMP IS";
uchar tplsb,tpmsb; // 温度值低位、高位字节 
uint temp; 
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*******************产生复位脉冲初始化DS18B20**************/
void reset(void)
{
uint i;
DQ=0;
i=100;
while(i--);
DQ=1;// 产生上升沿
i=4;
while(i--);
}
/********************* 等待应答脉冲*********************/
void wait(void)
{
uint i;
while(DQ);
while(~DQ); // 检测到应答脉冲 
i=4;
while(i--);
}
bit readbit(void)
{
uint i;
bit b;
DQ=0;
i++;
DQ=1;
i++;i++;// 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
b=DQ;
i=10;
while(i--);
return (b);
}
/******************* 读取数据的一个字节**************************/
uchar readbyte(void)
{
uchar i,j,b;
b=0;
for(i=0;i<8;i++)
{
j=readbit();
b=(j<<7)|(b>>1);
}
return(b);
}
/******************写数据的一个字节,满足写1和写0的时隙要求************/
void writebyte(uchar b)
{
uint i;
uchar j;
bit btmp;
for(j=0;j<8;j++)
{
btmp=b&0x01;
b=b>>1; // 取下一位(由低位向高位)
if(btmp)
{
DQ=0;
i++;i++;
DQ=1;
i=10;
while(i--);// 整个写1时隙不低于60us
}
else
{
DQ=0;
i=10;
while(i--); // 保持低在60us到120us之间
DQ=1;
i++;i++;
}
}
}
/************************* 启动温度转换********************/
void convert(void)
{
reset();// 产生复位脉冲,初始化DS18B20
wait();//等待DS18B20给出应答脉冲
writebyte(0xcc);// skip rom 命令
writebyte(0x44);// convert T 命令
}
/********************* 读取温度值****************************/
uint readtemp(void)
{
float tt;
reset();
wait();
delay(1);
writebyte(0xcc);// skip rom 命令
writebyte(0xbe);// read scratchpad 命令
tplsb=readbyte();// 温度值低位字节(其中低4位为二进制的"小数"部分)
tpmsb=readbyte();// 高位值高位字节(其中高5位为符号位)
temp=tpmsb;
temp<<=8;
temp=temp|tplsb;
tt=temp*0.0625;
temp=tt*10+0.5;
return (temp);
}
void write1602_com(uint com)
{
rs=0;
// rw=0;
P1=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write1602_date(uchar date)
{
rs=1;
// rw=0;
P1=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init1602(void) //1602初始化
{
write1602_com(0x38);
write1602_com(0x0c);
write1602_com(0x06);
write1602_com(0x01);
}
void display(uint temp)
{
uchar a1,a2,a3,a4;
a1=temp/100;
a2=temp%100;
a3=a2/10;
a4=a2%10;
write1602_com(0x80+0x09);//第一行第9个位置显示温度的十位、个位和小数点后一位
write1602_date(a1+0x30);
delay(1);
write1602_date(a3+0x30);
delay(1);
write1602_date(a4+0x30);
delay(1);
}
void display1()
{
uchar num;
write1602_com(0x80);  //在第一行开头显示“TEMP IS”
for(num=0;num<7;num++)
{
write1602_date(table[num]);
delay(5);
}
}
void main()
{
init1602();
convert();
delay(1000);// 启动温度转换,需要750ms
readtemp(); // 读取温度
while(1)
{
display1();
convert();
display(readtemp());
}
}



PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /1 下一条