📄 温度传感器程序.txt
字号:
/*=============================================
温度控制器
广州工程职业技术学院
传感器课程设计
指导老师: 冯伟
作者: GIT-3408-YOUJJYY (方畅,曹文荣,梁锐权)
时间: 2007-4-25
温度传感器用单总线DS18B20
CPU为AT89S52,三个按键(UP,DOWN,SET)
温度调节上限为125度,下限为-55度(本程序只能用于单只18B20)
================================================*/
#include <at89x52.h>
#include <intrins.h>
#include <main_led_display.h>
/*--------用于按键可位寻址的状态寄存器-----------*/
static unsigned char bdata StateREG;
sbit DS1820ON=StateREG^0; //DS18B20是否存在
sbit SetTF=StateREG^1; //是否是在温度设置状态
sbit KeySETDown=StateREG^2; //"1"为已按过SET键,"0"为没按过SET按
sbit PowTF=StateREG^3; //电源标识("0"为开电源,"1"为关电源)
sbit KeyTF=StateREG^4; //"0"为按键允许,"1"为不允许
sbit KeySETDowning=StateREG^5; //SET是否正在按下
sbit LEDTF=StateREG^6; //开机LOG标志位
static unsigned char bdata TLV _at_ 0x0029; //温度变量高低位
static unsigned char bdata THV _at_ 0x0028;
static signed char TMV; //转换后的温度值
static unsigned char KeyV,TempKeyV; //键值
static signed char TMRomV _at_ 0x0027; //高温度限制
static signed char TMSetV _at_ 0x0026; //温度设定值
static unsigned char KSDNum; //SET键连按时的采集次数
static unsigned char IntNum,IntNum2,IntNum3;//中断发生次数(IntNum用于SET长按检测,IntNum2用于设定状态时LED闪烁,IntNum用于连按其他键)
static unsigned int IntNum4,IntNum5;
static signed char Sign; //负号标识
static unsigned char LED_One,LED_Two,LED_Three;
/*------------------------------------------
数值转换
-------------------------------------------*/
void V2ToV(void)
{
TLV>>=4;
THV<<=4; //读出的高低位数值移位
TMV=TLV|THV; //合并高低位放入TM为实际温度值
Sign=0;
if(SetTF||!Key_SET)Sign=TMSetV>>7; //取符号
else Sign=TMV>>7;
if(Sign)
{
if(SetTF||!Key_SET)
{
LED_One=(~(TMSetV-1))/100; //SET状态下显示设定值
LED_Two=((~(TMSetV-1))-LED_One*100)/10;
LED_Three=(~(TMSetV-1))-LED_One*100-LED_Two*10;
}
else
{
LED_One=(~(TMV-1))/100; //转换百位数值
LED_Two=((~(TMV-1))-LED_One*100)/10;
LED_Three=(~(TMV-1))-LED_One*100-LED_Two*10;
}
}
else
{
if(SetTF||!Key_SET)
{
LED_One=TMSetV/100; //SET状态下显示设定值
LED_Two=(TMSetV-LED_One*100)/10;
LED_Three=TMSetV-LED_One*100-LED_Two*10;
}
else
{
LED_One=TMV/100; //转换百位数值
LED_Two=(TMV-LED_One*100)/10;
LED_Three=TMV-LED_One*100-LED_Two*10;
}
}
//=================转换LED字段==================
if(LED_One)LED_Two=BCD_ASCII[LED_Two+1]; //超过百时十位的处理
else
{
if(LED_Two==0)LED_Two=BCD_ASCII[0];
else LED_Two=BCD_ASCII[LED_Two+1];
}
if(Sign)LED_One=0xf7;
else
{
if(LED_One==0)LED_One=BCD_ASCII[0];
else LED_One=BCD_ASCII[LED_One+1];
}
LED_Three=BCD_ASCII[LED_Three+1];
}
/*-------------------------------------------
初始化DS1820
--------------------------------------------*/
void InitDS1820(void)
{
TMPort=1;
_nop_();
TMPort=0;
Delay_6n5_8us(77); //延时 DS1820复位时间要500US的抵电平
TMPort=1;
Delay_6n5_8us(16); //延时112US 等待DS1820的回应
if(!TMPort){DS1820ON=1;ON_DS1820=1;} //检测是否有DS1820
else {DS1820ON=0;ON_DS1820=0;}
Delay_6n5_8us(55);
TMPort=1;
}
/*------------------写数据-------------------*/
void Write_Data(uchar T_DATA)
{
uchar i,DATA_T;
DATA_T=T_DATA;
for(i=0;i<=7;i++)
{
TMPort=0;
Delay_6n5_8us(1); //延时14微秒
if(DATA_T&0x01)TMPort=1;
else TMPort=0;
DATA_T>>=1;
Delay_6n5_8us(7); //延时54微秒
TMPort=1;
_nop_();
}
TMPort=1;
}
/*--------------------------------------------
写入温度限制值
发出4EH写ROM指令后连发两个字节
---------------------------------------------*/
void WriteDS1820(void)
{
uchar TM_H,TM_L;
TM_H>>=4;
TM_L<<=4;
Write_Data(TM_H);
Write_Data(TM_L);
}
/*-----------------读数据-------------------*/
uchar ReadTM(void)
{
uchar i,TM_DATA;
for(i=0;i<=7;i++)
{
TM_DATA>>=1;
TMPort=1;
_nop_();_nop_();
TMPort=0;
_nop_();_nop_();_nop_();
TMPort=1;
Delay_6n5_8us(1);
if(TMPort)TM_DATA|=0x80;
Delay_6n5_8us(6);
}
return (TM_DATA);
}
/*-------------------------------------------
读出温度值
将温度高位和低位,高温度限制位从DS1820中读出
低位存入29H(TEMPER_L),
高位存入28H(TEMPER_H),
高温度限制位存入27H(TMRomV)
---------------------------------------------*/
void ReadDS1820(void)
{
TLV=ReadTM();
THV=ReadTM();
TMRomV=ReadTM();
}
/*====================主程序===================*/
void main(void)
{
StateREG=0; //初始化变量
SetTF=1; //在设置温度状态
PowTF=1; //关电源
THV=0; //温度数据存储(高地址:0x0028,低地址:0x0029) TLV=0;
TMV=0; //转换后的温度值
KeyV=0;
KSDNum=0; //SET键连按时的采集次数
IntNum=0; //用于SET长按检测
IntNum2=0; //用于设定状态时LED闪烁
IntNum3=0;
LED_One=0;
LED_Two=0;
Beep=1;
LEDTF=0;
InitDS1820();//初始化
Write_Data(0xcc);//跳过ROM
Write_Data(0xb8);//E2RAM中的温度上限值调入RAM
InitDS1820();
Write_Data(0xcc);//跳过ROM
Write_Data(0xbe);//读出温度指令
ReadDS1820();//读出温度值和上限值
TMSetV=TMRomV;//拷贝保存在DS1820ROM里的上限值到TMSet
EA=1; //允许CPU中断
ET0=1; //定时器0中断开
TMOD=0x01; //设定时器0为模式1,16位模式
TH0=0XB1;
TL0=0XDF; //设定时值为20MS
TR0=1; //开定时
while(1);
}
/*----------------------------------
定时器0中断处理中键扫描和显示
------------------------------------*/
void KeyAndDis_Time0(void) interrupt 1 using 2
{
TH0=0XB1;
TL0=0XDF; //设定时值为20MS
LEDPort=0xff; //关闭LED
/*--------------对按下的键值附值-------------*/
if(!Key_UP)KeyV=1; //检测Key_UP是否按下
if(!Key_DOWN)KeyV=2; //检测Key_DOWN是否按下
if(!Key_SET)KeyV=3; //检测Key_SET是否按下
KeySETDowning=0; //清除
/*--------------检测是否有键按下----------------*/
if(KeyV!=0) //KeyV不等于零表示有键按下
{
Delay_1ms(10); //延时防抖 按下10MS再测
if(!Key_UP)TempKeyV=1;
if(!Key_DOWN)TempKeyV=2;
if(!Key_SET)TempKeyV=3;
if(KeyV==TempKeyV) //两次值相等为确定接下了键
{
/*---判断是否是Key_SET按下---*/
if(KeyV==3) //按下SET键,如在SET状态就退出,否则进入
{
KeySETDowning=1; //表明SET正在按下
PowTF=0; //电源标识开
if(!KeyTF) //KeyTF为1不允许执行下程序
if(SetTF)
{
SetTF=0; //是否是在温度设置状态标识位标识退出设定
InitDS1820();
Write_Data(0xcc); //跳过ROM
Write_Data(0x4e); //写温度上限指令
WriteDS1820(); //写温度上限到DS1820ROM
InitDS1820();
Write_Data(0xcc); //跳过ROM匹配
Write_Data(0x48); //温度上限值COPY回E2PRAM
}
else SetTF=1; //为下一次没按SET时,按其他键作准备
if(!KeySETDown){KeySETDown=1;OPen=1;} //是否已按过SET键标识
else KSDNum+=1; //前一秒内有按SET则开始计数
}
/*--------Key_UP和Key_DOWN的检测---------*/
if(SetTF) //在SET状态下
{
if((KeyV==1)&&(!KeyTF))TMSetV+=1,OPen=0; //上调温度
if((KeyV==2)&&(!KeyTF))TMSetV-=1,OPen=0; //下调温度
if(TMSetV<=-55)TMSetV=-55;
if(TMSetV>=125)TMSetV=125;
}
if((!KeyTF)&&(IntNum3==0))KeyTF=1; //判断键盘是否处于可用时
}
/*---------按键长按的处理----------*/
if(KeySETDown)IntNum+=1; //在2秒内按下了SET则计中断发生次数用于长按SET时计时用
if(IntNum>60)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -