可以按键调节温度的上下限
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P3^3; //定义DS18B20端口DQ
sbit BEEP=P3^6 ; //蜂鸣器驱动线
bit presence,flag;
bit compare_th,compare_tl,al
ARM_on_off=0,temp_th,temp_tl;
sbit K1 = P1^4;
sbit K2 = P1^5;
sbit K3 = P1^6;
sbit K4 = P1^7;
unsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字
uchar code cdis1[ ] = {" READ_ROMCORD "};
uchar code cdis3[ ] = {" DS18B20 ERROR "};
uchar code cdis4[ ] = {" PLEASE CHECK "};
uchar code cdis6[ ] = {"TH: TL: "};
unsigned char data temp_data[2] = {0x00,0x00};
unsigned char data temp_alarm[2] = {0x00,0x00};
unsigned char data display[5] = {0x00,0x00,0x00,0x00,0x00}; //温度值显示
unsigned char data display1[3] = {0x00,0x00,0x00}; //温度报警值显示
unsigned char data RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
unsigned char Temp,temp_comp,
timecount,count;
unsigned char crc;
void Disp_Temp_alarm(uchar addr,uchar num);
void spk(uchar addr);
void set_temp_alarm();
void temp_compare();
void beep();
/*******************************************************************/
void delay1(int ms)
{
unsigned char y;
while(ms--)
{
for(y = 0; y<250; y++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/***********************************************************************
以下是DS1302
芯片的操作程序
************************************************************************/
sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.1引脚
sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P1.1引脚
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
;
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(unsigned char dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{
dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
/****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void Init_DS1302(void)
{
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((16/10)<<4|(16%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((8/10)<<4|(8%10))); //根据写小时寄存器命令字,写入小时的初始值
}
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚
sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚
sbit EN=P2^2; //使能信号位,将E位定义为P2.2引脚
sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/******************************************************************/
bit lcd_busy()
{
bit result;
RS = 0;
RW = 1;
EN = 1;
delayNOP();
result = (bit)(P0&0x80);
EN = 0;
return(result);
}
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{
while(lcd_busy()); //如果忙就等待
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
EN=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空操作两个机器周期,给硬件反应时间
P0=dictate; //将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
EN=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
EN=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
while(lcd_busy());
RS=1; //RS为高电平,RW为低电平时,可以写入数据
RW=0;
EN=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=y; //将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
EN=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
EN=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInitiate(void)
{
delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x38); //连续三次,确保初始化成功
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x06); //显示模式设置:光标右移,字符不移
delaynms(5); //延时5ms ,给硬件一点反应时间
WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除
delaynms(5); //延时5ms ,给硬件一点反应时间
}
/*****************************************************
/*****************************************************
函数功能:显示秒
入口参数:x
***************************************************/
void DisplaySecond(unsigned char x)
{
unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x46); //写显示地址,将在第2行第7列开始显示
WriteData(digit[i]); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示分钟
入口参数:x
***************************************************/
void DisplayMinute(unsigned char x)
{
unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x43); //写显示地址,将在第2行第7列开始显示
WriteData(digit[i]); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示小时
入口参数:x
***************************************************/
void DisplayHour(unsigned char x)
{
unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x40); //写显示地址,将在第2行第7列开始显示
WriteData(digit[i]); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示日
入口参数:x
***************************************************/
void DisplayDay(unsigned char x)
{
unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x0A); //写显示地址,将在第2行第7列开始显示
WriteData(digit[i]); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示月
入口参数:x
***************************************************/
void DisplayMonth(unsigned char x)
{
unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x07); //写显示地址,将在第2行第7列开始显示
WriteData(digit[i]); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:显示年
入口参数:x
***************************************************/
void DisplayYear(unsigned char x)
{
unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位
i=x/10;//取十位
j=x%10;//取个位
WriteAddress(0x04); //写显示地址,将在第2行第7列开始显示
WriteData(digit[i]); //将百位数字的字符常量写入LCD
WriteData(digit[j]); //将十位数字的字符常量写入LCD
delaynms(50); //延时1ms给硬件一点反应时间
}
/*******************************************************************/
/* */
/*us级延时函数 */
/* */
/*******************************************************************/
void Delay(unsigned int num)
{
while( --num );
}
/*******************************************************************/
/* */
/*初始化ds1820 */
/* */
/*******************************************************************/
Init_DS18B20(void)
{
DQ = 1; //DQ复位
Delay(8); //稍做延时
DQ = 0; //
单片机将DQ拉低
Delay(90); //精确延时 大于 480us
DQ = 1; //拉高总线
Delay(8);
presence = DQ; //如果=0则初始化成功 =1则初始化失败
Delay(100);
DQ = 1;
return(presence); //返回信号,0=presence,1= no presence
}
/*******************************************************************/
/* */
/* 读一个字节 */
/* */
/*******************************************************************/
ReadOneChar(void)
{
unsigned char i = 0;
unsigned char dat = 0;
for (i = 8; i > 0; i--)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if(DQ)
dat |= 0x80;
Delay(4);
}
return (dat);
}
/*******************************************************************/
/* */
/* 写一个字节 */
/* */
/*******************************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i = 0;
for (i = 8; i > 0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay(5);
DQ = 1;
dat>>=1;
}
}
/*******************************************************************/
/* */
/* 温度报警值写入DS18B20 */
/* */
/*******************************************************************/
Write_Temperature_alarm(void)
{
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x4e); //将设定的温度报警值写入 DS18B20
WriteOneChar(temp_alarm[0]); //写TH
WriteOneChar(temp_alarm[1]); //写TL
WriteOneChar(0x7f); //12位精确度
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x48); //把暂存器里的温度报警值拷贝到EEROM
}
/*******************************************************************/
/* */
/* 读取64位序列码 */
/* */
/*******************************************************************/
Read_RomCord(void)
{
unsigned char j;
Init_DS18B20();
WriteOneChar(0x33); // 读序列码的操作
for (j = 0; j < 8; j++)
{
RomCode[j] = ReadOneChar() ;
}
}
/*******************************************************************/
/* */
/*DS18B20的CRC8校验程序 */
/* */
/*******************************************************************/
uchar CRC8()
{
uchar i,x; uchar crcbuff;
crc=0;
for(x = 0; x <8; x++)
{
crcbuff=RomCode[x];
for(i = 0; i < 8; i++)
{
if(((crc ^ crcbuff)&0x01)==0)
crc >>= 1;
else {
crc ^= 0x18; //CRC=X8+X5+X4+1
crc >>= 1;
crc |= 0x80;
}
crcbuff >>= 1;
}
}
return crc;
}
/*******************************************************************/
/* */
/* 数据转换与显示 */
/* */
/*******************************************************************/
Disp_RomCode(uchar H_num)
{
uchar j;
if(H_num==1)
WriteAddress(0x00);
if(H_num==2)
WriteAddress(0x40);
for(j=0;j<8;j++)
{
Temp = RomCode[j];
display[0]=((Temp&0xf0)>>4);
if(display[0]>9)
{ display[0]=display[0]+0x37;}
else{display[0]=display[0]+0x30;}
WriteData(display[0]); //高位数显示
display[1]=(Temp&0x0f);
if(display[1]>9)
{display[1]=display[1]+0x37;}
else {display[1]=display[1]+0x30;}
WriteData(display[1]); //低位数显示
}
}
/*******************************************************************/
/* */
/* 读取温度 */
/* */
/*******************************************************************/
Read_Temperature(void)
{
uchar i;
TR0=0; //关中断,防止读数错误
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0x55); //匹配ROM命令
for(i=0;i<8;i++)
WriteOneChar(RomCode[i]);
WriteOneChar(0xBE); //读取温度寄存器
temp_data[0] = ReadOneChar(); //温度低8位
temp_data[1] = ReadOneChar(); //温度高8位
temp_alarm[0] = ReadOneChar(); //温度报警TH
temp_alarm[1] = ReadOneChar(); //温度报警TL
temp_comp=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
//取温度整数值
TR0=1; //开中断
}
/*******************************************************************/
/* */
/* 数据转换与温度显示 */
/* */
/*******************************************************************/
Disp_Temperature()
{
uchar s=0;
if(temp_data[1]>127) //温度为负值
{
temp_data[0]=(~temp_data[0])+1; //取反加一,将补码变成原码
if((~temp_data[0])>=0xff)
temp_data[1]=(~temp_data[1])+1;
else temp_data[1]=~temp_data[1];
s=1;
}
display[4]=temp_data[0]&0x0f;
display[0]=(display[4]*10/16)+0x30;
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
display[3]=display[4]/100+0x30;
display[1]=display[4]%100;
display[2]=display[1]/10+0x30;
display[1]=display[1]%10+0x30;
if(display[3]==0x30) //高位为0,不显示
{
display[3]=0x20;
if(display[2]==0x30) //次高位为0,不显示
display[2]=0x20;
}
if(s)
display[3]=0x2d; //显示负号
WriteAddress(0x49);
WriteData(display[3]); //百位数显示
WriteData(display[2]); //十位数显示
WriteData(display[1]); //个位数显示
WriteData('.');
WriteData(display[0]); //小数位数显示
WriteData(0xdf); //显示自定义字符
WriteData('C'); //显示C
/* lcd_pos(0x09); //写年月分隔符的显示地址, 显示在第1行第9列
lcd_wdat('-'); //将字符常量写入LCD
lcd_pos(0x06); //写月日分隔符的显示地址, 显示在第1行第12列
lcd_wdat('-'); //将字符常量写入LCD
lcd_pos(0x43); //写小时与分钟分隔符的显示地址, 显示在第2行第6列
lcd_wdat(':'); //将字符常量写入LCD
lcd_pos(0x46); //写分钟与秒分隔符的显示地址, 显示在第2行第9列
lcd_wdat(':'); //将字符常量写入LCD
*/
}
/*******************************************************************/
/* */
/* 蜂鸣器响一声 */
/* */
/*******************************************************************/
void beep()
{
unsigned char y;
for (y=0;y<100;y++)
{
Delay(70);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
Delay(25000);
}
/**********************************************************/
void delay0(uchar x)
{
uchar i;
while(x--)
{
for (i = 0; i<13; i++) {;}
}
}
/**********************************************************
蜂鸣器驱动子函数
**********************************************************/
void beep1()
{
uchar i;
for (i=0;i<180;i++)
{
delay0(5);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
delay0(250); //延时
}
/**********************************************************
蜂鸣器驱动子函数
**********************************************************/
void beep2()
{
uchar i;
for (i=0;i<180;i++)
{
delay0(20);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
delay0(500); //延时
}
/*******************************************************************/
/* */
/* ROMCORD 显示菜单 */
/* */
/*******************************************************************/
void RomCode_Menu ()
{
uchar m;
lcd_init(); //初始化LCD
Read_RomCord(); //读取64位序列码
CRC8(); //CRC效验
if(crc==0) //CRC效验正确
{
Disp_RomCode(2); //显示64位序列码
}
}
/*******************************************************************/
/* */
/* DS18B20 ERROR 显示菜单 */
/* */
/*******************************************************************/
void Error_Menu ()
{
uchar m;
lcd_init(); //初始化LCD
WriteAddress(0); //设置显示位置为第一行的第1个字符
for(m=0;m<16;m++)
WriteData(cdis3[m]); //显示字符
WriteAddress(0x40); //设置显示位置为第二行第1个字符
for(m=0;m<16;m++)
WriteData(cdis4[m]); //显示字符
}
/*******************************************************************/
/* */
/* DS18B20 正常显示菜单 */
/* */
/*******************************************************************/
void Natural_Menu ()
{
uchar m;
lcd_init(); //初始化LCD
Read_Temperature();
Disp_Temp_alarm(0x0d,0); //显示TH值
Disp_Temp_alarm(0x00,1); //显示TL值
Disp_Temperature(); //显示实时温度值
}
/*******************************************************************/
/* */
/* 主函数 */
/* */
/*******************************************************************/
void main()
{
uchar m;
unsigned char second,minute,hour,day,month,year; //分别储存苗、分、小时,日,月,年
unsigned char ReadValue; //储存从1302读取的数据
LcdInitiate(); //将液晶初始化
TMOD=0x01; TH0=0x4c; TL0=0x00; //50ms定时
EA=1; ET0=1; TR0=1;
WriteAddress(0x09); //写年月分隔符的显示地址, 显示在第1行第9列
WriteData('-'); //将字符常量写入LCD
WriteAddress(0x06); //写月日分隔符的显示地址, 显示在第1行第12列
WriteData('-'); //将字符常量写入LCD
WriteAddress(0x42); //写小时与分钟分隔符的显示地址, 显示在第2行第6列
WriteData(':'); //将字符常量写入LCD
WriteAddress(0x45); //写分钟与秒分隔符的显示地址, 显示在第2行第9列
WriteData(':'); //将字符常量写入LCD
Init_DS1302(); //将1302初始化
while(1)
{
ReadValue = ReadSet1302(0x81); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
DisplaySecond(second); //显示秒
ReadValue = ReadSet1302(0x83); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
DisplayMinute(minute); //显示分
ReadValue = ReadSet1302(0x85); //从分寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
DisplayHour(hour); //显示小时
ReadValue = ReadSet1302(0x87); //从分寄存器读
day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
DisplayDay(day); //显示日
ReadValue = ReadSet1302(0x89); //从分寄存器读
month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
DisplayMonth(month); //显示月
ReadValue = ReadSet1302(0x8d); //从分寄存器读
year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
DisplayYear(year); //显示年
Init_DS18B20();
if(presence)
{
Error_Menu ();
do
{
Init_DS18B20();
beep();
}
while(presence);
}
RomCode_Menu (); //显示RomCode
for(m=0;m<10;m++)
Delay(500);
Natural_Menu ();
do
{
Read_Temperature();
Disp_Temperature();
temp_compare();
set_temp_alarm();
if(!K4)
{
beep();
while(!K4); //等待键释放
alarm_on_off=~alarm_on_off;
}
if(!K1)
{
//beep();
while(!K1); //等待键释放
RomCode_Menu (); //显示RomCode
while(K2); //等待K2键按下
beep();
Natural_Menu ();
}
}
while(!presence);
}//end of while(1)
} //end of main()
/*********************************************************/
// 显示报警温度
/*********************************************************/
void Disp_Temp_alarm(uchar addr,uchar num)
{ //0=TH,1=TL
display1[2]=temp_alarm[num]/100+0x30;
display1[0]=temp_alarm[num]%100;
display1[1]=display1[0]/10+0x30;
display1[0]=display1[0]%10+0x30;
if(display1[2]==0x30) //高位为0,不显示
{
display1[2]=0x20;
if(display1[1]==0x30) //次高位为0,不显示
display1[1]=0x20;
}
WriteAddress(addr);
WriteData(display1[2]); //百位数显示
WriteData(display1[1]); //十位数显示
WriteData(display1[0]); //个位数显示
}
/**********************************************************/
// Time0中断函数
/**********************************************************/
void Time0(void) interrupt 1 using 0
{
TH0=0x4c; //50ms定时
TL0=0x00;
timecount++;
if(timecount>9)
{
timecount=0;
flag=~flag;
}
}
/*********************************************************/
// 温度比较函数
/*********************************************************/
void temp_compare()
{
if(temp_comp >= temp_alarm[0]) //比较 TH 值
{
compare_th=1;
}
else compare_th=0;
if(temp_comp < temp_alarm[1]) //比较 TL 值
{
compare_tl=1;
}
else compare_tl=0;
if(compare_th)
{
if(!alarm_on_off) //静音选择
beep2();
}
else
{
WriteAddress(0x50);
WriteData(0x20);
}
if(compare_tl)
{
if(!alarm_on_off) //静音选择
beep1();
}
else
{
//lcd_pos(0x4e);
WriteData(0x20);
}
}
/*********************************************************/
// 温度报警值闪动
/*********************************************************/
void Set_tempalarm_Flash(uchar addr,uchar num)
{
if(flag)
{
temp_alarm[num]=count;
Disp_Temp_alarm(addr,num); //显示温度报警值
}
else
{
WriteAddress(addr);
WriteData(0x20);
WriteData(0x20);
WriteData(0x20);
}
}
/*********************************************************/
// 设定报警值键函数
/*********************************************************/
void key_set(uchar num)
{
if(!K2) //加键
{
beep();
if(count!=num)
count++;
else
count=0;
}
if(!K1) //减键
{
beep();
if(count!=0)
count--;
else count=num;
}
}
/**********************************************************
温度报警值设定
***********************************************************/
void set_temp_alarm()
{
if(!K3)
{
beep();
temp_th=1;
count=temp_alarm[0]; //取实时TH报警值
}
while(temp_th)
{
key_set(120);
Set_tempalarm_Flash(0x0d,0);
if(!K3)
{
beep();
temp_th=0;
temp_tl=1;
flag=1;
Set_tempalarm_Flash(0x0d,0); //显示温度报警TH值
count=temp_alarm[1]; //取实时TL报警值
}
}
while(temp_tl)
{
key_set(120);
Set_tempalarm_Flash(0x00,1);
if(!K3)
{
beep();
temp_tl=0;
flag=1;
Set_tempalarm_Flash(0x00,1); //显示温度报警TL值
Write_Temperature_alarm(); //报警值写入DS18B20
count=0;
}
}
}
实在不行的话把程序分块吧,分成三块一个一个做,最后联调
一周热门 更多>