您当前的位置:五五电子网电子知识单片机-工控设备51单片机51单片机ADC0809+AD590温度检测、报警程序 正文
51单片机ADC0809+AD590温度检测、报警程序

51单片机ADC0809+AD590温度检测、报警程序

点击数:7184 次   录入时间:03-04 11:37:43   整理:http://www.55dianzi.com   51单片机

#include "reg52.h"//头文件
#include "intrins.h"
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义
sbit RS=P1^0;//LCD1602定义I/O的硬件接口
sbit RW=P1^1;//LCD1602定义I/O的硬件接口
sbit E=P1^2;//LCD1602定义I/O的硬件接口

sbit key_1=P1^3;//按键1定义I/O的硬件接口////Alarm_Value;//温度报警值+1度
sbit key_2=P1^4;//按键2定义I/O的硬件接口////Alarm_Value;//温度报警值-1度
sbit key_3=P1^5;//按键3定义I/O的硬件接口
sbit key_4=P1^6;//按键4定义I/O的硬件接口
sbit AD590_2=P1^7;//A定义I/O的硬件接口,通道选择//C、D接地
sbit key_6=P3^7;//按键6定义I/O的硬件接口//控制 温度报警标志位

//

sbit ST=P3^0; //ST和ALE接在一起
sbit OE=P3^1;
sbit EOC=P3^2;
sbit CLK=P3^3;
sbit SPK=P3^4; //喇叭,蜂鸣器报警
sbit LED1=P3^5; //LED报警
sbit LED2=P3^6;


#define DPDR P2//LCD1602并行数据输出接口定义
#define DPDR_1 P0//ADC0809并行数据输入接口定义

uchar temp;//最终温度值

unsigned long temp2;//平均温度
unsigned long temp1;//温度1,,AD590_1接IN0
unsigned long temp2;//温度2,,AD590_2接IN1

uchar Alarm_Value;//温度报警值
bit Alarm_Value_bit;//温度报警标志位


uchar code DispTab_1[]={'0','1','2','3','4','5','6','7','8','9'};//1602:0-9 数字
uchar code DispTab_2[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//温度符号
uchar DispBuf[6]; //6字节的显示缓冲区
char char_char_1[]={" Temperature: "};//定义字符串


void delay(uint z)//1ms延时
{
uchar x,x1;
for(;z>0;z--)
{
for(x=0;x<114;x++)
{
for(x1=0;x1<1;x1++);
}
}
}


void write_Directive(uchar a)//写LCD指令
{
RS=0;
RW=0;
delay(5);
E=0;
DPDR=a;
delay(5);
E=1;
delay(5);
E=0;
delay(5);
}

void write_Data(uchar a)//写LCD数据
{
RS=1;
RW=0;
delay(5);
E=0;
DPDR=a;
delay(5);
E=1;
delay(5);
E=0;
delay(5);

}

void LCD_init()//LCD初始化
{ uchar i;
delay(15);
write_Directive(0x38);
delay(5);
write_Directive(0x38);
delay(5);
write_Directive(0x38);
write_Directive(0x01);
write_Directive(0x02);//初始化后数据地址为0x80;即第一行,第一个位置
write_Directive(0x0c);//不显示光标
//write_Directive(0x0f);//显示光标
write_Directive(0x80+0x00);//第一行第一位地址
for(i=0;i<16;i++)
{
write_Data(char_char_1[i]);//显示字符串" Temperature "
}
}

void write_Data_String()//显示温度函数
{
uchar i;
DispBuf[0]=temp/100;//显示十位
temp=temp%100;

DispBuf[1]=temp/10;//显示个位
temp=temp%10;

DispBuf[2]=temp%10;//显示小数点后一位:0.0


DispBuf[0]=DispTab_1[i];//查表,取字符
i=DispBuf[1];
DispBuf[1]=DispTab_1[i];
i=DispBuf[2];
DispBuf[2]=DispTab_1[i];


write_Directive(0x80+0x40);//第二行,第一个位置地址

write_Data(DispBuf[0]);//第二行,第一个位置

write_Data(DispBuf[1]);//第二行,第二个位置

write_Data('.');//第二行,第三个位置

write_Data(DispBuf[2]);//第二行,第四个位置

write_Data(0x00);//第二行,第五个位置显示温度符号

}

void ADC0809_init()//ADC0809复位
{
ST=0;
OE=0;
SPK=1;
LED1=1;
TMOD=0x12;
TH0=0x216;
TL0=0x216;
TH1=(65536-40000)/256;
TL1=(65536-40000)%256;
TR1=0;
TR0=1;
ET0=1;
ET1=1;
EA=1;
}

void t0(void) interrupt 1 using 0
{
CLK=~CLK;
}

void t1(void) interrupt 3 using 0
{
TH1=(65536-40000)/256;
TL1=(65536-40000)%256;
SPK=~SPK;
LED1=~LED1;
}

void temp1_start()//启动温度1 转换
{
AD590_2=0;//通道选择
ST=1;
delay(1);//延时1ms
ST=0;
delay(1);//延时1ms
ST=1;
delay(1);//延时1ms
ST=0;
while(!EOC);//查询转换结束否
_nop_();
_nop_();
OE=1;//OE=0,输出数据线呈高阻;OE=1,输出转换得到的数据。
delay(1);//延时1ms
temp1=DPDR_1;
}

void temp2_start()//启动温度2 转换
{
AD590_2=1;//通道选择
ST=1;
delay(1);//延时1ms
ST=0;
delay(1);//延时1ms
ST=1;
delay(1);//延时1ms
ST=0;
while(!EOC);//查询转换结束否
_nop_();
_nop_();
OE=1;//OE=0,输出数据线呈高阻;OE=1,输出转换得到的数据。
delay(1);//延时1ms
temp2=DPDR_1;
}

void temp1_Calculated()//温度1 计算
{
temp1=(temp1*2350/128)-2732;
}

void temp2_Calculated()//温度2 计算
{
temp2=(temp2*2350/128)-2732;
}

void Temperature_Alarm()//温度报警
{
if(Alarm_Value_bit==1)
{
if(Alarm_Value==temp)
TR1=1;//启动定时器1
else
{
SPK=1;
LED1=1;
TR1=0;
}
}
else
{
SPK=1;
LED1=1;
TR1=0;
}
}

void key_Detection()//按键检测
{
if(key_6==0)
{
delay(20);//延时20ms
while(!key_6);
delay(20);//延时20ms
Alarm_Value=~Alarm_Value;
//break;
}
///////////////////////////////////////////
if(key_1==0)
{
delay(20);//延时20ms
while(!key_1);
delay(20);//延时20ms
if(Alarm_Value>=100)
{
temp=99;
return;
}
else
{
Alarm_Value++;
return;
}
}
///////////////////////////////////////////
if(key_2==0)
{
delay(20);//延时20ms
while(!key_2);
delay(20);//延时20ms
if(Alarm_Value<=0)
{
Alarm_Value=0;
return;
}
else
{
Alarm_Value--;
return;
}
}
}

void main()
{ uchar i;

ADC0809_init();//ADC0809复位
LCD_init();//LCD复位
delay(5);//延时
for(i=0;i<8;i++)
{
write_Directive(0x40+i);//写入温度符号
write_Data(DispTab_2[i]);
}

while(1)
{
key_Detection();//按键检测

temp1_start();//启动温度1 转换
temp2_start();//启动温度2 转换

temp1_Calculated();//温度1 计算
temp2_Calculated();//温度2 计算

temp=(temp1+temp2)/2;//取温度1和温度2的平均值

Alarm_Value=temp;

Temperature_Alarm();//温度报警条件查询

write_Data_String();//显示温度

}


}

1.温度传感器AD590基本知识
   AD590产生的电流与绝对温度成正比,它可接收的工作电压为4V-30V,检测的温度范围为-55℃-+150℃,它有非常好的线性输出性能,温度每增加1℃,其电流增加1uA。
   AD590温度与电流的关系如下表所示

摄氏温度  AD590电流  经10KΩ电压 
0℃  273.2 uA  2.732V 
10℃  283.2 uA  2.832 V 
20℃  293.2 uA  2.932 V 
30℃  303.2 uA  3.032 V 
40℃  313.2 uA  3.132 V 
50℃  323.2 uA  3.232 V 
60℃  333.2 uA  3.332 V 
100℃  373.2 uA  3.732 V 


实验任务
   利用AD590温度传感器完成温度的测量,把转换的温度值的模拟量送入ADC0809的其中一个通道进行A/D转换,将转换的结果进行温度值变换之后进行监控。

由于AD590的温度变化范围在-55℃-+150℃之间,经过10KΩ之后采样到的电压变化在2.182V-4.232V之间,不超过5V电压所表示的范围,因此参考电压取电源电压VCC,(实测VCC=4.70V)。由此可计算出经过A/D转换之后的摄氏温度显示的数据为:
   如果(D*2350/128)<2732,则显示的温度值为-(2732-(D*2350/128))
   如果(D*2350/128)≥2732,则显示的温度值为+((D*2350/128)-2732)




本文关键字:单片机  程序  温度检测  51单片机单片机-工控设备 - 51单片机