本程序还是在原有基础上小修改了一下,去掉了星期显示,把原来整点闹钟改成了可自由设定小时+分钟的闹钟,其他的功能还是不变。
功能:时间,时分闹钟设置,上下限温度设置,温度显示。
闹钟可设置到分钟,响铃时间还是10秒钟。
可扩展功能:音乐响铃,一个星期中的任何一天闹钟设定,需要添加或者修改一下程序即可,程序只是简单的整理了一下,很多地方很乱,需要程序的朋友最好有较好的编程能力,否者很难理解程序的写作思维。
仿真图

完整的源代码下载: http://www.51hei.com/ziliao/file/1602_naoz.rar
#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit BEEP=P3^7; //// 定义蜂鸣器口
unsigned char L,H,Z,Y; //// 定义高低温度变量
/////////////////////////////////////////////////////////////////////////////////////////////////
/**********报警声音**************/
bi(uint t)
{
int c,n;
for(c=0;c<t;c++)
{
for(n=0;n<50;n++);
BEEP=~BEEP; //按位取反BEEP
}
return(t);
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/**********18b20温度程序**********/
sbit DQ=P3^6; //定义温度数据口
int xs; //定义小数
unsigned int temp,temp1,temp2; //定义温度转换变量
//////////////////////////////////////////////////////////////////////////////////////////////
/*********18B20延时程序************/
void delay_18B20(unsigned int i)
{
while(i--);
}
//////////////////////////////////////////////////////////////////////////////////////////////
/*********ds18b20初始化函数*********/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位 ds18b20通信端口
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(4);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
///////////////////////////////////////////////////////////////////////////////////////////
/********ds18b20读一个字节**********/
unsigned char ReadOneChar(void)
{
unsigned char i=0,dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; //高电平拉成低电平时读周期开始
dat>>=1;
DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
//////////////////////////////////////////////////////////////////////////////////////////
/*************ds18b20写一个字节****************/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0; //从高电平拉至低电平时,写周期的开始
DQ = dat&0x01; //数据的最低位先写入
delay_18B20(5); //60us到120us延时
DQ = 1;
dat>>=1; //从最低位到最高位传入
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/**************读取ds18b20当前温度************/
void ReadTemperature(void)
{
unsigned char a=0,b=0,t=0;
Init_DS18B20 ( );
WriteOneChar ( 0xCC ); // 跳过读序号列号的操作
WriteOneChar ( 0x44 ); // 启动温度转换
delay_18B20 ( 100 ); // this message is wery important
Init_DS18B20 ( );
WriteOneChar ( 0xCC ); //跳过读序号列号的操作
WriteOneChar ( 0xBE ); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delay_18B20 ( 100 );
a=ReadOneChar( ); //读取温度值低位
b=ReadOneChar( ); //读取温度值高位
temp1 = b<<4; //高8位中后三位数的值
temp1+= ( a&0xf0 )>>4; //低8位中的高4位值加上高8位中后三位数的值 temp1室温整数值
temp2 = a&0x0f; //小数的值
temp = ( ( b*256+a ) >>4 ); //当前采集温度值除16得 实际温度值 zhenshu
xs=temp2*0.0625*10; //小数位,若为0.5则算为5来显示 xs小数 xiaoshu
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*********************1602液晶程序********************/
/******定义液晶控制口*******/
sbit lcdrs=P2^5; //定义液晶三个控制口
sbit lcdrw=P2^6;
sbit lcden=P2^7;
sbit K1=P3^0; //定义三个开关
sbit K2=P3^1;
sbit K3=P3^2;
/////////////////////////////////////////////////////////////////////////////////////////////////
/******定义变量*******/
uchar count,shi,fen,miao,xq,K1num; //定义时间程序里所需要的变量
/////////////////////////////////////////////////////////////////////////////////////////////////
/******定义数组*******/
// uchar code table [ ]= "H:38 L:25 00 Q:7"; //液晶界面显示的内容
// uchar code table1[ ]= "23:59:55 . C";
uchar code table [ ]= "01:00:55 01-01"; //液晶界面显示的内容
uchar code table1[ ]= "H:38 L:25 . C";
//////////////////////////////////////////////////////////////////////////////////////////////////
/******延时程序*******/
void delay(uint m) //液晶延时程序
{
uint i,j;
for(i=m;i>0;i--)
for(j=110;j>0;j--);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
/**********写指令*************/
void write_com(uchar com)
{
lcdrs=0;
lcdrw=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/////////////////////////////////////////////////////////////////////////////////////
/************写数据*************/
void write_data(uchar date)
{
lcdrs=1;
lcdrw=0;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
///////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
/***************液晶显示程序***************/
/*********时分秒数的分离**********/
void write_sfm(uchar add,uchar date)
{
uchar shi,ge; //分离数字,如35,分成3和5
shi=date/10;
ge=date%10;
write_com ( 0x80+add );
write_data ( 0x30+shi );
write_data ( 0x30+ge );
}
//////////////////////////////////////////////////////////////////
/**********星期***********/
void write_xq(uchar add1,uchar date1)
{
uchar ge; //星期只需要一个数字显示
ge=date1%10;
write_com ( 0x80+add1 );
write_data ( 0x30+ge );
}
////////////////////////////////////////////////////////////////
/************高温低温数的分离************/
void write_HL(uchar add2,uchar date2)
{
uchar shi,ge;
shi=date2/10;
ge=date2%10;
write_com(0x80+0x40+add2);
write_data( 0x30+shi );
write_data( 0x30+ge );
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/***************按键调时程序***************/
void keycan()
{
/**********功能选择**********/
if( K1==0 ) { K1num++; delay(1); if( K1==0 ) { while(!K1);bi(200);
if( K1num==1 ) { TR0=0; write_com ( 0x80+1 ); write_com(0x0f); } //时
if( K1num==2 ) { write_com ( 0x80+4 ); } //分
if( K1num==3 ) { write_com ( 0x80+7 ); } //秒
//if( K1num==4 ) { write_com ( 0x80+11 ); } //星期
if( K1num==4 ) { write_com ( 0x80+12 ); } //闹钟
if( K1num==5 ) { write_com ( 0x80+15 ); }
if( K1num==6 ) { write_com ( 0x80+0x40+3 ); } //上限
if( K1num==7 ) { write_com ( 0x80+0x40+8 ); } //下限
if( K1num==8 ) { K1num=0; write_com(0x0c); TR0=1; } //退出设置
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
/*********功能加*********/
if( K1num!=0 ) {
if( K2==0 ) { delay(1);
if( K2==0 ) { while(!K2);bi(200);
if( K1num==1 ) { shi++; if( shi==24 ) shi=0; write_sfm ( 0,shi ); write_com ( 0x80+1 ); }
if( K1num==2 ) { fen++; if( fen==60 ) fen=0; write_sfm ( 3,fen ); write_com ( 0x80+4 ); }
if( K1num==3 ) { miao++; if( miao==60 ) miao=0; write_sfm ( 6,miao); write_com ( 0x80+7 ); }
//if( K1num==4 ) { xq++; if( xq==8 ) xq=1; write_xq (11,xq ); write_com ( 0x80+11); }
if( K1num==4 ) { Z++; if( Z==24 ) Z=0; write_sfm (11,Z ); write_com ( 0x80+12); }
if( K1num==5 ) { Y++; if( Y==60 ) Y=0; write_sfm (14,Y ); write_com ( 0x80+15); }
if( K1num==6 ) { H++; if( H==100) H=0; write_HL ( 2,H ); write_com ( 0x80+0x40+3);}
if( K1num==7 ) { L++; if( L==100) L=0; write_HL ( 7,L ); write_com ( 0x80+0x40+8);}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**********功能减************/
if(K1num!=0) {
if(K3==0 ) { delay(1);
if(K3==0 ) { while(!K3); bi(200);
if( K1num==1 ) { shi--; if( shi==-1 ) shi=23; write_sfm ( 0,shi ); write_com ( 0x80+1 ); }
if( K1num==2 ) { fen--; if( fen==-1 ) fen=59; write_sfm ( 3,fen ); write_com ( 0x80+4 ); }
if( K1num==3 ) {miao--; if( miao==-1 ) miao=59; write_sfm ( 6,miao); write_com ( 0x80+7 ); }
// if( K1num==4 ) { xq--; if( xq==0 ) xq=7; write_xq (11,xq ); write_com ( 0x80+11); }
if( K1num==4 ) { Z--; if( Z==-1 ) Z=23; write_sfm (11,Z ); write_com ( 0x80+12); }
if( K1num==5 ) { Y--; if( Y==-1 ) Y=59; write_sfm (14,Y ); write_com ( 0x80+15); }
if( K1num==6 ) { H--; if( H==-1 ) H=99; write_HL ( 2,H ); write_com ( 0x80+0x40+3);}
if( K1num==7 ) { L--; if( L==-1 ) L=99; write_HL ( 7,L ); write_com ( 0x80+0x40+8);}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/*************初始化**************/
void init()
{
uchar num; //定义一个变量num,用于下面数组的初始化//
lcden=0;
write_com ( 0x38 );
write_com ( 0x0c ); //不显示光标
write_com ( 0x06 ); //光标向右边自动移位
write_com ( 0x01 ); //清屏
shi=1; fen=00; miao=55; //xq=7;
H=38; L=25; Z=1; Y=1;
write_com ( 0x80 );
for( num=0; num<16; num++ )
{ write_data( table[num] ); delay(5); }
write_com ( 0x80+0x40 );
for( num=0; num<16; num++ )
{ write_data( table1[num] ); delay(5); }
///////////////////////////////////////////////////////////////////////////////////////
/********定时器初始化*************/
TMOD=0x01; //定义定时器0,工作方式1
TH0=(65536-50000)/256; //高8位
TL0=(65536-50000)%256; //低8位
EA=1; //开全局中断
ET0=1;
TR0=1; //打开定时器
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/***********定时器中断函数************/
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if( count==20 ) { count=0; miao++;
if( miao==60 ) { miao=0; fen++; }
if( fen==60 ) { fen=0; shi++; }
if( shi==24 ) { shi=0; //xq++;
//if( xq==8 ) { xq=1; }
}
}
}
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
/*****************************************/
uchar code mytab[8]={0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00};
/* 设定显示位置
/**************************************/
void lcd_pos(uchar pos)
{
write_com(pos | 0x80) ; //数据指针=80+地址变量
}
/////////////////////////////////////////////////////////////////////////////
/*自定义字符写入CGRAM
/*********************************/
void writetab()
{
unsigned char i ;
write_com(0x40) ; //写CGRAM
for (i = 0 ; i< 8 ; i++)
write_data(mytab[ i ]) ;
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
void wendu() /////温度显示程序/////
{
writetab( ) ; //自定义字符写入CGRAM
delay ( 5 ) ;
lcd_pos ( 0x4e ) ; //显示圈圈
write_data( 0x00 ) ; //显示自定义字符
write_com ( 0x0c );
ReadTemperature();
write_com ( 0x80+0x40+10 );
write_data ( 0x30+temp/10 );
write_com ( 0x80+0x40+11 );
write_data ( 0x30+temp%10 );
write_com ( 0x80+0x40+13 );
write_data ( 0x30+xs%10 );
/////时间显示地址/////
write_sfm( 0,shi );
write_sfm( 3,fen );
write_sfm( 6,miao );
// write_xq (11,xq );
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////温度报警程序//////
void baojing()
{
if(H==temp)
{
bi(500);
}
if(L==temp)
{
bi(500);
}
if((Z==shi)&(Y==fen)&(miao<10)) //设定报警,响10秒钟结束。
{
{
bi(500);
}
}
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
/***************主函数***************/
void main()
{
init();
while(1)
{
keycan();
wendu();
baojing();
}
}
