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

2018-01-14 20:25:14编辑:什么鱼 关键字:51单片机  ADC0809  AD590  温度检测  报警程序

#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单片机  ADC0809  AD590  温度检测  报警程序

来源: eefocus 引用地址:http://www.eeworld.com.cn/mcu/article_2018011437354.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:SD7218A数码管驱动芯片实例程序
下一篇:LED点阵显示与编程

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

51单片机实现LED流水灯(数组方式和位运算方式)

/* 名称:51单片机实现LED流水灯(数组方式和位运算方式)说明:今天又重新开始系统的学习51了,LED就算个开端吧。 要注意两点: 1、sfr和sbit是C语言扩展出来的关键字。其中sfr用于对特殊功能寄存器进行声明,sbit用于对某些特殊功能寄存器的某位进行声明。这里和宏定义很相似,但是不能用宏定义进行替换,对于前者是因为51单片机的寄存器存在于内部空间0x80-0xFF,这空间属于直接寻址,51特殊功能寄存只能直接寻址,不能间接寻址。如果用宏定义的话,在翻译成汇编时就会认为是通过总线访问对应的外部地址了。对于后者,sbit是定义一个标志位,也叫位变量。而类似于#define key1 P3
发表于 2018-07-21 13:08:22

51单片机之按键实验

/* 名称:51单片机之按键实验 说明:键盘是计算机最基础、最重要的输入设备之一。对于键盘来说,其工作任务大体可以分为以下三项: (1)、按键识别。即判断有无按键按下。 (2)、求键值。判断哪个键被按下。 (3)、执行相应的操作。 在这里,实验所用到的键盘为独立键盘和矩阵键盘。对于独立键盘,它的每个按键需要占用一个IO口。一般来说,按键一端接地,另一端接IO口。当按键按下时,线路被导通,IO口被拉低,即状态为‘0’。所以在使用是我们一般把对应IO口置成高电平,然后不断检测此IO口是否被拉低,从而判断按键是否按下。 对于矩阵键盘来说,它用较少的IO口完成较多个按键
发表于 2018-07-21 13:07:26

51单片机之数码管显示实验

/* 名称:51单片机之数码管显示实验 说明:对于数码管来说,其本质上可以理解为按照一定规则组合的多个二极管。其使用只需按照特定规则显示对应的二极管即可。要稍微注意一点的就是多个数码管的显示分为静态显示和动态显示。静态显示就是每个二极管显示的内容是一样的,通过片选信号来决定是哪个二极管该显示。动态数码管,即利用人眼的视觉停留效果,快速扫描,快速显示每个数码管的内容,使得每个数码管看起来好像是一起显示的一样。 本实验编写了几个数码管显示的简单程序。在此不做赘述了。*/#include <reg52.h>#define uchar unsigned char//共阳极段码(a在高位,dp在低位
发表于 2018-07-21 13:06:23

关于单片机死机的一些问题

最近的一个项目中测试系统的高低温实验,结果意外的发现经过高低温实验后(80℃到-20摄氏度)单片机有些已经死机了,所以不得不着手研究一下这个问题,在网上查阅资料后,基本上可以归结于以下几个问题:1. 意外中断。是否打开了某个中断,但是没有响应和清除中端标志,导致程序一直进入中断,造成死机假象 2. 中断变量处理不妥。若定义某些会在中断中修改的全局变量,这时要注意两个问题:首先为了防止编译器优化中断变量,要在这些变量定义时前加volatile,其次在主循环中读取中断变量前应该首先关闭全局中断,防止读到一半被中断给修改了,读完之后再打开全局中断;否则出现造成数据乱套。  3. 地址溢出,常见错误为指针操作
发表于 2018-07-16 20:31:16

单片机外部中断的两种模式

51单片机的外部中断有两种模式:电平触发模式和跳变沿触发模式第一,选择电平触发时,单片机在每个机器周期检查中断源口线,检测到低电平,即置位中断请求标志,向CPU请求中断。第二,选择边沿触发方式时,单片机在上一个机器周期检测到中断源口线为高电平,下一个机器周期检测到低电平,即置位中断标志,请求中断。 区别:电平触发模式时,中断标志寄存器不锁存电平中断请求信号。单片机把每个周期的S5P2采样外部中断口的电平逻辑直接赋值到中断标志寄存器。标志寄存器对于请求信号来说是透明的。这样当中断请求被阻塞而没有得到及时响应时,将被丢失。换言之,就是要使电平触发的中断被CPU响应并执行,必须保证外部中断源口线的低电平维持到中断被执行
发表于 2018-07-16 20:29:36

基于80C51单片机——中断小结

最近看了一下80C51单片机的中断部分的实验,做一些笔记,方便以后学习查找。 首先说一下什么是中断吧,中断是指CPU在执行当前程序的过程中,由于某种随机出现的外设(外部设备)请求或CPU内部的异常事件,使CPU暂停正在执行的程序而转去执行相应的服务处理程序;当服务处理程序运行完毕之后,CPU再返回到暂停处继续执行原来的程序。那什么是中断嵌套呢?简单点说就是低优先级的中断可以被高优先级的中断源所中断,等高优先级中断服务程序结束后,再返回去执行被中断的的低优先级的中断服务程序。举个简单的栗子吧(之前写过但不知道怎么删了,,又让我重新编辑):比如我们就是一个CPU,我们当前在洗衣服(当前程序),突然电话铃声响了(中断来了
发表于 2018-07-16 20:26:35

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved