DS18B20程序
- 格式:doc
- 大小:60.00 KB
- 文档页数:11
Lesson11-1:数字温度传感器DS18B20,采用3位数码管显示,仿真通过
#include
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; // 定义DS18B20接口
uchar time=100;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//不带小数点编码。
uchar code table1[]=
{0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带小数点编码。
void mdelay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
///////功能:串口初始化,波特率9600,方式1///////
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) // DS18B20初始化
{
uint i;
DS=0; // 首先拉低,要求480us
i=103;
while(i>0)i--;
DS=1; // 上升沿,要求15~60us
i=4;
while(i>0)i--;
}
void rxwait()//等待应答脉冲
{
uint i; while(DS);
while(~DS);
i=8;while(i>0)i--;
}
bit tmpreadbit(void) //读一位
{
uint i;
bit dat;
DS=0;
i++; //1us延时
DS=1;//15us内,主机必须停止将DS引脚置低
i++;i++; //15us延时
dat=DS;
i=8;while(i>0)i--;//读时隙不低于60us延时
return (dat);
}
uchar tmpread(void) // 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat) //写一个字节到DS18B20里
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else {
DS=0; //写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //发送温度转换命令
{
dsreset();//初始化DS18B20
rxwait(); //等待应答脉冲
mdelay(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
uint tmp() //获得温度
{
float tt;
uchar a,b;
uint temp; // 存放温度值
dsreset();
rxwait();//等待应答脉冲
mdelay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8; //出厂默认设置为12位分辨率
temp=temp|a; //两字节合成一个整型变量。
tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度。
temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
return temp; //返回温度值
}
/*void readrom() //read the serial 读取温度传感器的序列号
{ //本程序中没有用到此函数
uchar sn1,sn2;
dsreset();
delay(1);
tmpwritebyte(0x33);
sn1=tmpread(); sn2=tmpread();
}*/
void display(uint temp) //显示程序
{
uchar A1,A2,A3,ser;
ser=temp/10; //分离出三位要显示的数字
SBUF=ser;
A1=temp/100;
A2=temp%100/10;
A3=temp%10;
dula=1; //显示百位
P0=table[A1];
dula=0;
wela=1;
P0=0x7e;
wela=0;
mdelay(time);
dula=1; //显示十位 带小数点的
P0=table1[A2];
dula=0;
wela=1;
P0=0x7d;
wela=0;
mdelay(time);
dula=1; //显示个位
P0=table[A3];
dula=0;
wela=1;
P0=0x7b;
wela=0;
mdelay(time);
}
void main() //主函数
{
uchar a;
Init_Com(); //初始化串口
do
{
tmpchange(); //温度转换 for(a=10;a>0;a--)
{
display(tmp()); //显示十次
}
}while(1);
}
Lesson11-2:数字温度传感器DS18B20,采用1602液晶显示,仿真通过
#include
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2;
sbit dula=P2^6;
sbit wela=P2^7;
sbit E=P3^4;
sbit RS=P3^5;
sbit RW=P3^6;
const uchar NoDisp=0;
const uchar NoCur=1;
const uchar CurNoFlash=2;
const uchar CurFlash=3;
void mdelay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void WaitIdle()
{
RS=0;
RW=1;
//_nop_();也可以不要
E=1;
mdelay(5);
while((P0&0x80)==0x80)
{
E=0; //这两句protues仿真必须加;仿真器仿真也通过。
E=1;
};
E=0;
}
void LcdWcn(uchar c)
{
RS=0;
RW=0;
P0=c;
mdelay(5);
E=1;
mdelay(5);
E=0;
}
void LcdWc(uchar c)
{
WaitIdle();
LcdWcn(c);
}
void LcdWd(uchar c)
{
WaitIdle();
RS=1;
RW=0;
P0=c;
mdelay(5);
E=1;
mdelay(5);
mdelay(5);
E=0;
}
void ClrLcd()
{
LcdWc(0x01);
}
void RstLcd()
{
dula=0;//关闭数码管锁存端,避免电流不够
wela=0;
E=0;
LcdWc(0x38);