资讯详情

单片机中使用DS18B20温度传感器C语言程序(参考6)

原标题:单片机使用DS18B20温度传感器C语言程序(参考6)

/******************************************/

//

// 温度计C程序

// 2007.06.08

/******************************************/

//使用AT89C20,12MHZ晶振,用共阳数码管

//P1口输出段码,P3口扫描,P3.4接DS18B20

#include "reg51.h"

#include "intrins.h" //_nop_();延时函数用

#define Disdata P0 ///段码输出口

#define discan P2 //扫描口

#define uchar unsigned char

#define uint unsigned int

sbit DQ=P2^2; ///温度输入口

sbit DIN=P0^7; //LED小数点控制

uint h;

//

//

//**************小温度部分用查表法***********//

uchar code ditab[16]=

{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};

//

uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};

//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"

uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列扫描控制字

uchar data temp_data[2]={0x00,0x00}; ///读出温度暂放

uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个临时操作

//

//

//

/*****************11us延时函数*************************/

//

void delay(uint t)

{

for (;t>0;t--);

}

//

/****************显示扫描函数***************************/

scan()

{

char k;

for(k=0;k<4;k ) //4位LED扫描控制

{

Disdata=dis_7[display[k]]; ///数据显示

if (k==1){DIN=0;} ///小数点显示

discan=scan_con[k]; //位选

delay(90); //延时

discan=0xff;

}

}

//

//

/****************DS18B20复位函数************************/

ow_reset(void)

{

char presence=1;

while(presence)

{

while(presence)

{

DQ=1;_nop_();_nop_()

DQ=0;

delay(50); //550 us

DQ=1;

delay(6); //66 us

presence=DQ; //presence=0 成功复位,继续下一步

}

delay(45); //延时500 us

presence=~DQ;

}

DQ=1; //提高电平

}

//

//

/****************DS18B20写命令函数************************/

//向1-WIRE 上写1个字节

void write_byte(uchar val)

{

uchar i;

for(i=8;i>0;i--)

{

DQ=1;_nop_();_nop_(); //从高拉下来

DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us

DQ=val&0x01; ///最低位移

delay(6); //66 us

val=val/2; //右移1位

}

DQ=1;

delay(1);

}

//

/****************DS18B20读1字节函数************************/

///从总线上取一个字节

uchar read_byte(void)

{

uchar i;

uchar value=0;

for(i=8;i>0;i--)

{

DQ=1;_nop_();_nop_();

value>>=1;

DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us

DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us

if(DQ)value|=0x80;

delay(6); //66 us

}

DQ=1;

return(value);

}

//

/****************读取温度函数************************/

//

read_temp()

{

ow_reset(); ///总线复位

write_byte(0xcc); //发命令

write_byte(0xbe); ///发读命令

temp_data[0]=read_byte(); //温度低8位

temp_data[1]=read_byte(); //高温8位

ow_reset();

write_byte(0xcc); //Skip ROM

write_byte(0x44); //发转换命令

}

//

/****************温度数据处理函数************************/

///二进制高字节的低半字节和低字节的高半字节形成一个字节

//字节二进制转换为十进制后,是温度值的百、十、个位值,剩余

///低字节低半字节转化为十进制后,是温度值的小部分

/********************************************************/

work_temp()

{

uchar n=0;

if(temp_data[1]>127) //正负判断

{

temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1; ///负温求补码

}

display[4]=temp_data[0]&0x0f; ///取低字节的低4位-小数部分

display[0]=ditab[display[4]]; //存储小数部分

display[4]=((temp_data[0]&0xf0>>4)|((temp_data[1]&0x0f)<<4);//取整数部分

display[3]=display[4]/100; //取百位数

display[1]=display[4]0; //

display[2]=display[1]/10; //取十位数

display[1]=display[1]; //取个位数

/*****************符号位显示判断**************************/

if(!display[3])

{

display[3]=0x0a; //最高位为0时不显示

if(!display[2])

{

display[2]=0x0a; //次高位为0时不显示

}

}

if(n){display[3]=0x0b;} //负温度时最高位显示"-"

}

//

//

/****************主函数************************/

main()

{

Disdata=0xff; //初始化端口

discan=0xff;

for(h=0;h<4;h++) //开机显示"8888"

{display[h]=8;}

ow_reset(); //开机先转换一次

write_byte(0xcc); //Skip ROM

write_byte(0x44); //发转换命令

for(h=0;h<500;h++) //开机显示"8888"

{scan();}

while(1)

{

read_temp(); //读出DS18B20温度数据

work_temp(); //处理温度数据

for(h=0;h<500;h++) //显示温度值2s

{scan();}

}

}

责任编辑:

标签: con021传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台