51单片机ADC0809+AD590温度检测、报警程序
时间:2023-07-24 18:37:00
#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^三、/按键1定义I/O的硬件接口Alarm_Value;///温度报警值 1度
sbit key_2=P1^四、/按键2定义I/O的硬件接口Alarm_Value;//温度报警值-1度
sbit key_3=P1^5.//按键3定义I/O的硬件接口
sbit key_4=P1^六、/按键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//LCD定义并行数据输出接口
#define DPDR_1 P0//ADC定义并行数据输入接口
uchar temp;///最终温度值
unsigned long temp二、/平均温度
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 数字
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=temp0;
DispBuf[1]=temp/10;//显示个位
temp=temp;
DispBuf[2]=temp;///显示小数点后的一个: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)%6;
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)%6;
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=输出数据线为高阻;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();//显示温度
}
}
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)