基于单片机的温度报警系统proteus仿真.docx

上传人:b****7 文档编号:11498563 上传时间:2023-03-02 格式:DOCX 页数:17 大小:29.98KB
下载 相关 举报
基于单片机的温度报警系统proteus仿真.docx_第1页
第1页 / 共17页
基于单片机的温度报警系统proteus仿真.docx_第2页
第2页 / 共17页
基于单片机的温度报警系统proteus仿真.docx_第3页
第3页 / 共17页
基于单片机的温度报警系统proteus仿真.docx_第4页
第4页 / 共17页
基于单片机的温度报警系统proteus仿真.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

基于单片机的温度报警系统proteus仿真.docx

《基于单片机的温度报警系统proteus仿真.docx》由会员分享,可在线阅读,更多相关《基于单片机的温度报警系统proteus仿真.docx(17页珍藏版)》请在冰豆网上搜索。

基于单片机的温度报警系统proteus仿真.docx

基于单片机的温度报警系统proteus仿真

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

#definedelayNOP(){_nop_();_nop_();_nop_();_nop_();}

sbitHI_LED=P2^3;//高温,低温白净闪烁LED

sbitLO_LED=P2^6;

sbitDQ=P3^3;//DS18B20数据线

sbitBEEP=P3^7;//报警

sbitRS=P2^0;

sbitRW=P2^1;

sbitEN=P2^2;

sbitK1=P1^7;//正常显示温度,越界时报警

sbitK2=P1^4;//显示报警温度

sbitK3=P1^1;//查看ROMCODE

ucharcodeRomCodeStr[]={"--ROMCODE--"};

ucharRomCode[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//64位ROMCODE

ucharcodeTemp_Disp_Title[]={"CurrentTemp:

"};

ucharCurrent_Temp_Display_Buffer[]={"TEMPE:

"};

ucharcodeTemperature_Char[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};//温度示字符

ucharcodeAlarm_Temp[]={"ALARMTEMPHiLo"};

ucharAlarm_HI_LO_STR[]={"Hi:

Lo:

"};

uchartemp_data[2]={0x00,0x00};

uchartemp_alarm[2]={0x00,0x00};

uchardisplay[5]={0x00,0x00,0x00,0x00,0x00,};//温度值

uchardisplay1[3]={0x00,0x00,0x00};//温度报警值

ucharcodedf_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//温度小数位对照表

//.......................................................

//报警温度上下限(取值范围:

-128~+127)(DS18B20温度范围为:

-55~+125)

//数组中前一位为高温值,后一位为低温值

//此处类型注意设为char,否则不能进行有符号数的比较

charAlarm_Temp_HL[2]={70,-20};

//............................................................

ucharCurrentT=0;//当前读取温度整数部分

ucharTemp_Value[]={0x00,0x00};//从DS18B20读取的温度值

ucharDisplay_Digit[]={0,0,0,0};//待显示的各温度数位

bitHI_Alarm=0,LO_Alarm=0;//高低温报警标志

bitDS18B20_IS_OK=1;//传感器正常标志

uintTime0_Count=0;//定时器延时累加

//...........................

//延时

//...........................

voidDelayXus(intx)

{

uchari;

while(x--)for(i=0;i<200;i++);

}

//.......................................

//忙检测

bitLCD_Busy_Check()

{

bitLCD_Status;

RS=0;//寄存器选择

RW=1;//读状态寄存器EN=1;//开始读

DelayXus

(1);

LCD_Status=(bit)(P0&0x80);

EN=0;

returnLCD_Status;

}

 

//写LCD指令

voidWrite_LCD_Command(ucharcmd)

{

while((LCD_Busy_Check()&0x80)==0x80);//忙等待

RS=0;//写选择命令寄存器

RW=0;//写

EN=0;

P0=cmd;EN=1;DelayXus

(1);EN=0;

}

//向LCD写数据

voidWrite_LCD_Data(uchardat)

{

while((LCD_Busy_Check()&0x80)==0x80);//忙等待

RS=1;RW=0;EN=0;P0=dat;EN=1;DelayXus

(1);EN=0;

}

//设置液晶显示位置

voidSet_LCD_POS(ucharpos)

{

Write_LCD_Command(pos|0x80);

}

//LCD初始化

voidLCD_Initialise()

{

Write_LCD_Command(0x38);

DelayXus

(1);

Write_LCD_Command(0x01);//清屏

DelayXus

(1);

Write_LCD_Command(0x06);//字符进入模式:

屏幕不动,字符后移

DelayXus

(1);

Write_LCD_Command(0x0C);//显示开,关光标

DelayXus

(1);

}

//...............................................

//..........................................

//自定义字符写CGRAM

//..................................

voidWrite_NEW_LCD_Char()

{

uchari;

Write_LCD_Command(0x40);//写CGRAM

for(i=0;i<8;i++)

Write_LCD_Data(Temperature_Char[i]);//写入温度符号

}

//............................................

//延时

//........................................................

voidDelay(uintnum)

{

while(--num);

}

//...............................................

//初始化DS18B20

//...............................................

ucharInit_DS18B20()

{

ucharstatus;

DQ=1;Delay(8);

DQ=0;Delay(90);

DQ=1;Delay(8);

status=DQ;

Delay(100);

DQ=1;

returnstatus;//初始化成功时返回0

}

//...............................................

//读一节

//...............................................

ucharReadOneByte()

{

uchari,dat=0;

DQ=1;_nop_();

for(i=0;i<8;i++)

{

DQ=0;dat>>=1;DQ=1;_nop_();_nop_();

if(DQ)dat|=0x80;Delay(30);DQ=1;

}

returndat;

}

//...............................................

//写一字节

//...............................................

voidWriteOneByte(uchardat)

{

uchari;

for(i=0;i<8;i++)

{

DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;

}

}

//...............................................

//读取温度值

//...............................................

voidRead_Temperature()

{

if(Init_DS18B20()==1)//DS18B20故障

DS18B20_IS_OK=0;

else

{

WriteOneByte(0xCC);//跳过序列号

WriteOneByte(0x44);//启动温度转换

Init_DS18B20();

WriteOneByte(0xCC);//跳过序列号

WriteOneByte(0xBE);//读取温度寄存器

Temp_Value[0]=ReadOneByte();//温度低8位

Temp_Value[1]=ReadOneByte();//温度高8位

Alarm_Temp_HL[0]=ReadOneByte();//报警温度TH

Alarm_Temp_HL[1]=ReadOneByte();//报警温度TL

DS18B20_IS_OK=1;

}

}

//...............................................

//设置DS18B20温度报警值

//...............................................

voidSet_Alarm_Temp_Value()

{

Init_DS18B20();

WriteOneByte(0xCC);//跳过序列号

WriteOneByte(0x4E);//将设定的温度报警值写入DS18B20

WriteOneByte(Alarm_Temp_HL[0]);//写TH

WriteOneByte(Alarm_Temp_HL[1]);//写TL

WriteOneByte(0x7F);//12位精度

Init_DS18B20();

WriteOneByte(0xCC);//跳过序列号

WriteOneByte(0x48);//温度报警值存入DS18B20

}

//......................................................

//在LCD上显示当前温度

//.....................................................

voidDisplay_Temperature()

{

uchari;

uchart=150;//延时值

ucharng=0;//负数标识

charSigned_Current_Temp;

//如果为负数则取反加1,并设置负数标识

if((Temp_Value[1]&0xF8)==0xF8)

{

Temp_Value[1]=~Temp_Value[1];

Temp_Value[0]=~Temp_Value[0]+1;

if(Temp_Value[0]==0x00)Temp_Value[1]++;

ng=1;//设负数标识

}

//查表得到温度小数部分

Display_Digit[0]=df_Table[Temp_Value[0]&0x0F];

//获取温度整数部分(无符号)

CurrentT=((Temp_Value[0]&0xF0)>>4)|((Temp_Value[1]&0x07)<<4);

//有符号的当前温度值,注意此处定义为char,其值可为-128~+127

Signed_Current_Temp=ng?

-CurrentT:

CurrentT;

//高低温报警标志设置(与定义为char类型的Alarm_Temp_HL比较,这样可区分正负比较)

HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?

1:

0;

LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?

1:

0;

//将整数部分分解为三位待显示数字

Display_Digit[3]=CurrentT/100;

Display_Digit[2]=CurrentT%100/10;

Display_Digit[1]=CurrentT%10;

//刷新LCD显示缓冲

Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';

Current_Temp_Display_Buffer[10]='.';

Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';

Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';

Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0';

//高位为0时不显示

if(Display_Digit[3]==0)Current_Temp_Display_Buffer[7]='';

//高位为0且次高位为0时,次高位不显示

if(Display_Digit[2]==0&&Display_Digit[3]==0)

Current_Temp_Display_Buffer[8]='';

//负数符号显示恰当位置

if(ng)

{

if(Current_Temp_Display_Buffer[8]=='')

Current_Temp_Display_Buffer[8]='_';

else

if(Current_Temp_Display_Buffer[7]=='')

Current_Temp_Display_Buffer[7]='_';

else

Current_Temp_Display_Buffer[6]='_';

}

//在第一行显示标题

Set_LCD_POS(0X00);

for(i=0;i<16;i++)Write_LCD_Data(Temp_Disp_Title[i]);

//在第二行显示当前温度

Set_LCD_POS(0X40);

for(i=0;i<16;i++)Write_LCD_Data(Current_Temp_Display_Buffer[i]);

//显示温度符号

Set_LCD_POS(0X4D);Write_LCD_Data(0x00);

Set_LCD_POS(0X4E);Write_LCD_Data('C');

}

//.....................................

//定时器中断,控制报警声音

//.................................

voidT0_INT()interrupt1

{

TH0=-1000/256;

TL0=-1000%256;

BEEP=!

BEEP;

if(++Time0_Count==400)

{

Time0_Count=0;

if(HI_Alarm)HI_LED=~HI_LED;elseHI_LED=0;

if(LO_Alarm)LO_LED=~LO_LED;elseLO_LED=0;

TR0=0;

}

}

//...............................................

//ROMCODE转换与显示

//.....................................................

voidDisplay_Rom_Code()

{

uchari,t;

Set_LCD_POS(0x40);

for(i=0;i<8;i++)

{

t=((RomCode[i]&0xF0)>>4);

if(t>9)t+=0x37;elset+='0';

Write_LCD_Data(t);//高位数显示

t=RomCode[i]&0x0F;

if(t>9)t+=0x37;elset+='0';

Write_LCD_Data(t);//低位数显示

}

}

//..................................

//读64位序列码

//...............................

voidRead_Rom_Code()

{

uchari;

Init_DS18B20();

WriteOneByte(0x33);//读序列码

for(i=0;i<8;i++)RomCode[i]=ReadOneByte();

}

//.........................................

//显示ROMCODE

//...............................

voidDisplay_RomCode()

{

uchari;

Set_LCD_POS(0x00);

for(i=0;i<16;i++)//显示标题

Write_LCD_Data(RomCodeStr[i]);

Read_Rom_Code();//读64位序列码

Display_Rom_Code();//显示64位ROMCODE

}

//.......................................

//显示报警温度

//...............................................

voidDisp_Alarm_Temperature()

{

uchari,ng;

//显示Alarm_Temp_HL数组中的报警温度值

//由于Alarm_Temp_HL类型为char,故可以直接进行正负比较

//高温报警值.........................

ng=0;

if(Alarm_Temp_HL[0]<0)//如果为负数则取反加1

{

Alarm_Temp_HL[0]=~Alarm_Temp_HL[0]+1;

ng=1;

}

//分解高温各数位到待显示串中

Alarm_HI_LO_STR[4]=Alarm_Temp_HL[0]/100+'0';

Alarm_HI_LO_STR[5]=Alarm_Temp_HL[0]/10%10+'0';

Alarm_HI_LO_STR[6]=Alarm_Temp_HL[0]%10+'0';

//屏蔽高位不显示的0

if(Alarm_HI_LO_STR[4]=='0')Alarm_HI_LO_STR[4]='';

if(Alarm_HI_LO_STR[4]==''&&Alarm_HI_LO_STR[5]=='0')

Alarm_HI_LO_STR[5]='';

//"-"符号显示

if(ng)

{

if(Alarm_HI_LO_STR[5]=='')Alarm_HI_LO_STR[5]='-';

else

if(Alarm_HI_LO_STR[4]=='')Alarm_HI_LO_STR[4]='-';

else

Alarm_HI_LO_STR[3]='-';

}

//低温报警值

ng=0;

if(Alarm_Temp_HL[1]<0)//如果为负数则取反加1

{

Alarm_Temp_HL[1]=~Alarm_Temp_HL[1]+1;

ng=1;

}

//分解低温各数位到待显示串中

Alarm_HI_LO_STR[12]=Alarm_Temp_HL[1]/100+'0';

Alarm_HI_LO_STR[13]=Alarm_Temp_HL[0]/10%10+'0';

Alarm_HI_LO_STR[14]=Alarm_Temp_HL[0]%10+'0';

//屏蔽高位不显示的0

if(Alarm_HI_LO_STR[12]=='0')Alarm_HI_LO_STR[12]='';

if(Alarm_HI_LO_STR[12]==''&&Alarm_HI_LO_STR[13]=='0')

Alarm_HI_LO_STR[13]='';

//"-"符号显示

if(ng)

{

if(Alarm_HI_LO_STR[13]=='')Alarm_HI_LO_STR[13]='-';

else

if(Alarm_HI_LO_STR[12]=='')Alarm_HI_LO_STR[12]='-';

else

Alarm_HI_LO_STR[11]='-';

}

//显示高低温报警温度值

Set_LCD_POS(0x00);//显示标题

for(i=0;i<16;i++)Write_LCD_Data(Alarm_Temp[i]);

Set_LCD_POS(0x40);//显示高低温

for(i=0;i<16;i++)Write_LCD_Data(Alarm_HI_LO_STR[i]);

}

//................................

//主函数

//..................................

voidmain()

{

ucharCurrent_Operation=1;//默认当前操作为显示温度

LCD_Initialise();

IE=0x82;

TMOD=0x01;

TH0=-1000/256;

TL0=-1000%256;

TR0=0;

HI_LED=0;

LO_LED=0;

Set_Alarm_Temp_Value();

Read_Temperature();

Delay(50000);

Delay(50000);

while

(1)

{

if(K1==0)Current_Operation=1;

if(K2==0)Current_Operation=2;

if(K3==0)Current_Operation=3;

switch(Current_Operation)

{

case1:

//正常显示当前温度,越界时报警

Read_Temperature();

if(DS18B20_IS_OK)

{

if(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1