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);