单片机温度检测报警程序(ds18b20)

程序采用数字温度采集芯片 ds18b20 获取温度 分辨率为12位 可以由此程序获的更低分辨率温度
ds18b20 只有三个i/o接口 其中两个为电源引脚 一个为数据总线
只需要一条口线通信 简化了分布式温度传感应用 无需外部元件 可用数据总线供电
电压范围为3.0 V至5.5 V 无需备用电源 测量温度范围为-55 ° C至+125 ℃
ds18b20 相关介绍:ds18b20 百度百科
Proteus 仿真:
温度报警Proteus 仿真
Code:
    #include <reg51.h>
#include <math.h>
#define uchar unsigned char // 宏定义uchar 为无符号字符
#define uint unsigned int

sbit DQ=P2^3;
sbit alarm =P3^4; //温度告警标志位
sbit test = P1^0;

unsigned long temp; //温度值
uchar tempH,tempL,tempSign; //ds18b20 读取的温度高位 和低8位 ,最高上限温度和最低下限温度,温度符号

signed long setMax=10;
signed long setMin=-10;
float precision=0.0625; //温度精度(默认12位)
uchar seg[8]={0}; // eg. -100.0625

// 延时函数
void delay(uint t) //最大65ms 2^16
{
/TMOD = 0x01; //启用T0 计时器 工作方式1
TH0 = (65536 - t )/256;
TL0 = (65536 - t )%256;
EA = 0; //禁止中断
TR0 = 1; //开始T0计数
while( TF0 == 0);
TF0 = 0; // 清除T0 溢出标志位
TR0 = 0; //关闭T0计数
/
while(t–);
}

// ds18b20 初始化函数
uchar init(void)
{
uchar feedback;

DQ = 0 ;
delay(100);
DQ = 1;

/while(DQ); //用于获取反馈信号,返回0为成功,返回1为初始化失败
feedback = DQ;
/

delay(25);

//return feedback; //返回0复位成功,返回1复位失败

}

// 写函数

void write(uchar var) //先输出低位,再输出高位
{
uchar i;
for(i=8;i>0;i–)
{
DQ = 0;
DQ = var&0x01; // 获取最后一位数据写入数据线
delay(5);
//(DQ == 1)? delay(10):delay(70); //延时保证ds18b20 采样。写入为 1 15us 内需释放数据线;写入为 0 至少延时 60us;
DQ = 1;
var >>= 1; //右移一位
}
//delay(5);
}

// 读函数
uchar read( void )
{ //先读取低位,再读取高位
uchar feedback = 0;
uchar i;
for(i=8;i>0;i–)
{

DQ = 0;
feedback >>= 1; // 右移
DQ = 1; // 数据线拉低15us内 释放数据线
//delay(1);
if(DQ){ feedback |= 0x80;} //在feedback 在高位写入1 等待右移处理
delay(5);
}

return feedback;
}

// 配置ds18b20 参数说明:(最高温度,最低温度)
//暂不可用
void setConfig(char th,char tl)
{

uchar precision;

init();
write(0xcc);
write(0x4e);
write(th); //默认最高温度为+125
write(tl);//默认最低温度为-55

}

// 温度超限报警处理
void warning()
{
uchar maxSign=0,minSign=0; //最高温度和最低温度符号

if(setMax > 0)
{
maxSign = 1;
}
if(setMin > 0)
{
minSign = 1;
}

if( temp < labs(setMin)10000 && tempSign <= minSign ) //小于下限温度
{
alarm=0;
delay(100);
alarm=1;
delay(100);
}else{
alarm =0;
}

if( temp > setMax
10000 && tempSign >=maxSign ) //大于上限温度
{
alarm=0;
delay(100);
alarm=1;
delay(100);

}else{
alarm =0;
}

}

// 温度显示处理,转换 tampH 和 tempL ,写入数组 seg[8], 得出十进制 温度 temp
void convert()
{
uint tempC; //补码温度
uchar seg7; //温度符号位

tempC = tempH256.0 + tempL;

//tempC=tempH<<8;
//tempC|=tempL;

if(tempC > 0x0800)
{
seg7 = 0x40; //温度为负温度
tempSign = 0;
temp = (~tempC + 1); // 补码求原码,取反加一
temp=temp
precision;

}else{
tempSign = 1;
seg7 = 0x00; // 温度为正
temp = tempC ;
temp=tempprecision10000; //放大10000倍,用于取余获取各位数值
}

//temp = 1234567;
seg[7] = seg7;
seg[6] = temp/1000000;
seg[5] = temp%1000000/100000;
seg[4] = temp%1000000%100000/10000;
seg[3] = temp%1000000%100000%10000/1000;
seg[2] = temp%1000000%100000%10000%1000/100;
seg[1] = temp%1000000%100000%10000%1000%100/10;
seg[0] = temp%1000000%100000%10000%1000%100%10;
}

//数码管动态显示 ,读取数组seg[8]
void ledShow()
{

uchar i=0,m,led;

uchar tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管 0-9

uchar tabPoint[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //共阴数码管 0-9 带小数点

do{
m=seg[i];

if( i == 4 ) //数码管第四位包含小数点 单片机开发板 数码管和proteus 仿真不同
{
led = tabPoint[m];
}else if( i==7 ){ //符号位跳过译码
led = seg[7];
}else{
led = tab[m];
}

P2 = i ; //送位码 单片机开发板 数码管和proteus 仿真不同
P0 = led; //送段码

delay(100);

i++;

warning();
}while(i<8);

}

//从ds18b20 获取温度,获取 tempH 和 tempL
void getTemp()
{

init();
write(0xCC); //跳过rom搜索
write(0x44); //启动温度转换
delay(100); //温度转换最多750ms

init();
write(0xCC);
write(0xBE); //读出ds18b20 内部RAM 9直接内容
delay(100);
tempL = read(); //读出温度低字节
tempH = read(); //读出温度高字节

//tempMax = read(); //读取高温触发器
//tempMin = read(); //读取低温触发器
}

void main()
{
while(1){
getTemp();
convert();
ledShow();

}
}
程序下载:单片机 温度检测报警系统(C语言+proteus 仿真).zip