您的当前位置:首页智能电子闹钟

智能电子闹钟

2021-10-29 来源:小侦探旅游网
 学校: 班级: 姓名:

2014年12月22---终结版

日目录

1. 功能简介 2. 硬件系统的设计 1.1 原件清单 1.2 原理图 3. 软件系统的设计 4. 作品欣赏 5. 附录1 源代码

1. 功能简介

本智能电子闹钟采用增强型51高速单片机STC12C5A60S2作为控制芯片,DS1302作为时钟源,1602字符液晶作为显示器,配合DS18B20温度传感器,蜂鸣器等可实现实时显示年、月、日、星期、时、分、秒,以及当前气温等,可以设置三组不同的闹钟,每组闹钟可单独关闭打开,且可以设置响一次还是每天响。加入了PWM,可实现背光亮度调节,加入了A/D转换,利用光敏电阻可实现背光亮度自动调节,在自动亮度模式下,光敏电阻每隔1秒钟会测一次环境光。还具有软件校时功能。具有掉电记忆功能,所有需要保存的数据断电前都会保存在单片机内部的EEPROM中,上电自动读取。由于加入了大电容作为备用电源,在掉电后时间还可以走两个多小时。开机有专门的欢迎界面。

作品还存在一些BUG和不足,比如说,自动亮度非线性变化,当环境光达到亮度变化的临界值时,屏幕会闪烁,时间经软件校时之后还会有些误差,等等。。。以后会慢慢修复

2. 硬件系统的设计

2.1 原件清单

1.STC12C5A60S2 2.DS1302 3.DS18B20 4.1602液晶显示器 5.40pin芯片座 6.8pin芯片座 7.16pin排母 8.光敏电阻 9.蜂鸣器 10.微动按钮4个 11.4pin弯排针 12.3pin排母 13.3.5mm电源座 14.10K电位器 15.10K排阻

16.1500uf电解电容 10uf点解电容 17.22pf瓷片电容2只,27pf瓷片电容2只 18.9013三极管2只

19.12MHZ晶振 32.579KHZ晶振

20.电阻若干 21.3MM LED 22. 。。。

2.2原理图

原理图还没画出来呀,只有仿真图,原理图以后补上,由

于LCD本身的原因,PWM部分没画出来。。。

3. 软件系统的设计

程序采用C51编写,2000行左右吧,各部件功能都进行了模块化,只是现在还没搞懂头文件的方式,所以所有程序都写在了一个文件中,详情见附录 1.以后等我搞懂了分文件的编译方式,我会把程序进行分文件模块化,方便以后其他项目的移植。敬请期待。。。

4. 作品欣赏

可用图钉订于墙上,看起来有木有高大上的感觉???

时间温度显示界面

菜单第一页

菜单第二页

菜单第三页

亮度设置界面

闹钟设置界面-第一页

闹钟设置界面-第二页

当有闹钟打开时,主界面右上角会有打开标志

焊工有待加强

开机欢迎界面

附录 1 源代码

/******************************************************** ********************************************************* ** ** ** ** ** 1602智能电子闹钟,采用DS1302时钟芯片,带测 ** ** 温功能,可以设置3组闹钟,闹钟可选择仅一次还是 ** ** 每天响闹钟开启时主界面会有闹钟标志,屏幕亮度 ** ** 可手动和自动调节 ** ** ** ** ** ** ** ********************************************************* ********************************************************/

#include #include

#define uint unsigned int #define uchar unsigned char

sbit key1=P1^4; sbit key2=P1^5; sbit key3=P1^6; sbit key4=P1^7;

sbit BZ=P2^4;

sbit pwm=P1^3;

sbit rs=P2^7; sbit rw=P2^6; sbit en=P2^5;

//定义按键

//定义蜂鸣器

//定义1602亮度pwm控制交房

//定义1602液晶引脚

sbit DQ=P2^0;

sbit rst=P2^3; sbit io=P2^2; sbit sck=P2^1;

uchar bdata rwdata; sbit lbit=rwdata^0; sbit hbit=rwdata^7;

//温度传感器数据线 //定义时钟芯片引脚

uchar TPH,TPL,key1num,okflag,auto_ge,auto_shi,num,auto_num,adc_num; uchar

alarmclose1,alarmclose2,alarmclose3,alarm_set_select,alarmtimes1,alarmtimes2,alarmtimes3; char nian,yue,ri,shi,fen,miao,xingqi,alarmshi,alarmfen,light_times,times;

uchar tempnum[]=\" 0.0 C\"; //用于存放温度值 uchar time[7]={0,0,8,1,1,0,14}; //存放时间日期星期 uchar alarm[3][3]={0,8,0,0,8,0,0,8,0}; //存放三个闹钟值

uchar code time_init[2][11]={\"2014-01-01\//时间初始化显示 uchar code week[22]=\"SunMonTueWedThuFriSur\"; //存放星期

uchar code menu[4][16]={\" ---Menu--- \ \ \Light \ //主菜单界面

uchar code alarm_menu_init[3][16]={\" --SetAlarm-- \ //闹钟选择界面 uchar code alarm_set[5][8]={\"Alarm-1 \闹钟设置界面 uchar code

light[17]={0x00,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0xf8,0xfc};//17级屏幕亮度

uchar code light_set[2][16]={\" Screen Light \ AUTO \亮度调节界面 uchar code welcome[2][16]={\"Welcome!\ //开机欢迎界面

uint welcome_flag=0;//用来判断是否显示欢迎界面

/********************************* 函数入口:微秒数 函数出口:无

函数功能:微秒延时,适用于1T单片机 *********************************/ void usdelay(uint n) { while(n--) { _nop_(); _nop_(); } }

/********************************* 函数入口:毫秒数 函数出口:无

函数功能:毫秒延时

*********************************/ void delay(uint x)

{ uint y; for(x;x>0;x--) for(y=255;y>0;y--); }

/********************************* 函数入口:1602指令 函数出口:无

函数功能:1602写指令

*********************************/ void write_com(uchar com) { rs=0; P0=com; delay(5); en=1; delay(5); en=0; }

/********************************* 函数入口:需要写入的数据 函数出口:无

函数功能:1602写数据

*********************************/ void write_date(uchar date) { rs=1; P0=date; delay(5); en=1; delay(5); en=0; }

/********************************* 函数入口:无 函数出口:无

函数功能:关闭IAP,禁止操作EEPROM *********************************/ void iap_close() { IAP_CONTR=0; IAP_CMD=0; IAP_TRIG=0; IAP_ADDRH=0x80;

IAP_ADDRL=0; }

/********************************* 函数入口:扇区号,字节号 函数出口:指定扇区中的数据

函数功能:读取EEPROM指定扇区指定字节数据 *********************************/ uchar iap_read(uchar n,uint x) { uchar dat; uint add; add=(n-1)*0x0200+x-1; IAP_CONTR=0x83; IAP_CMD=1; IAP_ADDRL=add; IAP_ADDRH=add>>8; IAP_TRIG=0x5a; IAP_TRIG=0xa5; _nop_(); dat=IAP_DATA; iap_close(); return dat; }

/*********************************

函数入口:扇区号,字节号,需要写入的数据 函数出口:无

函数功能:对EEPROM指定扇区指定字节写入指定数据 *********************************/ void iap_write(uchar n,uint x,uchar dat) { uchar add; add=(n-1)*0x0200+x-1; IAP_CONTR=0x83; IAP_CMD=2; IAP_ADDRL=add; IAP_ADDRH=add>>8; IAP_DATA=dat; IAP_TRIG=0x5a; IAP_TRIG=0xa5; _nop_(); iap_close(); }

/*********************************

函数入口:扇区号 函数出口:无

函数功能:擦除EEPROM指定扇区中数据 *********************************/ void iap_sector(uchar n) { uchar add; add=(n-1)*0x0200; IAP_CONTR=0x83; IAP_CMD=3; IAP_ADDRL=add; IAP_ADDRH=add>>8; IAP_TRIG=0x5a; IAP_TRIG=0xa5; _nop_(); iap_close(); }

/********************************* 函数入口:无 函数出口:无

函数功能:初始化ADC模块

*********************************/ void init_adc() { P1ASF=0x01; ADC_RES=0; AUXR1=0; ADC_CONTR=0x80; }

/*********************************

函数入口:无 函数出口:无

函数功能:初始化

*********************************/ void init() { uint i; TMOD=0x11; ET0=1; //开启定时器0中断 ET1=0; //关闭定时器1中断 TR1=1; TH0=(65535-50000)/256; TL0=(65535-50000)%256; TH1=(65536-50000)/256;

TL1=(65536-50000)%256; EA=1; EADC=1; init_adc(); CCON=0; CL=0; CH=0;

CMOD=0x02; CCAPM0=0x42; CCON=0x40; rw=0; en=0;

P2M0=0x16; P2M1=0x00; write_com(0x38); write_com(0x0c); write_com(0x06);

//开启ADC中断 //初始化ADC

//设置PWM寄存器

//设置显示模式

//开显示,关光标,关闪烁

write_com(0x01); //指针清零,显示清零 delay(2);

write_com(0x80+0x04); //开机显示欢迎界面 if(welcome_flag==0) { welcome_flag++; for(i=0;i<8;i++) { write_date(welcome[0][i]); delay(800); } delay(3000); write_com(0x80+0x40); for(i=0;i<16;i++) { write_date(welcome[1][i]); delay(800); } delay(10000); }

write_com(0x01); //清零 delay(2);

write_com(0x80); for(i=0;i<10;i++) //初始化显示日期 { write_date(time_init[0][i]); delay(5);

}

}

write_com(0x80+0x40+0x01); //初始化显示时间 for(i=0;i<8;i++) { write_date(time_init[1][i]); delay(5); }

write_com(0x80+0x0b); //初始化显示星期 for(i=0;i<3;i--) { write_date(week[i]); delay(5); }

write_com(0x80+0x40+0x09); //初始化显示温度 for(num=0;num<7;num++) { write_date(tempnum[num]); delay(5); }

write_com(0x80+0x40+0x0e); //显示摄氏度符号 write_date(0xdf);

light_times=iap_read(1,13); //从EEPROM中读取亮度状态 if(light_times>=0) //开启手动亮度模式 { CCAP0H=light[light_times]; } else //开启自动亮度模式 { ET1=1; }

alarmclose1=iap_read(1,1); //从EEPROM中读取闹钟状态 alarmclose2=iap_read(1,2); alarmclose3=iap_read(1,3); alarmtimes1=iap_read(1,4); alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12);

/********************************* 函数入口:无 函数出口:无

函数功能:设置主界面显示

*********************************/ void menu_display() { uchar i;

write_com(0x01); write_com(0x80); for(i=0;i<16;i++) write_date(menu[0][i]); write_com(0x80+0x40); switch(key1num) {

case 1: case 2:

//指针清零,显示清零 //显示主菜单第一行

//显示主菜单第二行

for(i=0;i<16;i++) //显示设置时间选项 write_date(menu[1][i]); break;

for(i=0;i<16;i++) //显示设置闹钟选项 write_date(menu[2][i]); break;

case 3: for(i=0;i<16;i++) //显示设置背光亮度选项

write_date(menu[3][i]); } }

/********************************* 函数入口:无 函数出口:无

函数功能:屏幕亮度调节界面显示

*********************************/ void screen_light() { uchar i; write_com(0x80);

for(i=0;i<16;i++) { write_date(light_set[0][i]); }

write_com(0x80+0x40); for(i=0;i<16;i++) { write_date('');

//显示第一行

//清零第二行显示

}

if(light_times>=0) //手动亮度显示 { write_com(0x80+0x40); for(i=0;i<16-light_times;i++) { write_date('<'); } CCAP0H=light[light_times]; } if(light_times<0) //自动亮度显示 { write_com(0x80+0x40); for(i=0;i<16;i++) write_date(light_set[1][i]); } }

/********************************* 函数入口:无 函数出口:无

函数功能:闹钟设置界面显示

*********************************/ void alarm_set_menu() { uchar i,shiwei,gewei,aa; switch(alarm_set_select) { case 1: write_com(0x80+0x04); for(i=0;i<7;i++) //显示Alarm-1 write_date(alarm_set[0][i]);

write_com(0x80+0x40+0x02); write_date(':');

//显示‘:’

write_com(0x80+0x40+0x08); //显示闹钟次数选择

for(i=0;i<8;i++) write_date(alarm_set[3+alarmtimes1][i]); write_com(0x80+0x40); aa=alarm[0][1]; shiwei=aa/10; gewei=aa%10;

write_date(0x30+shiwei);

//显示时

write_date(0x30+gewei);

write_com(0x80+0x40+0x03); aa=alarm[0][0]; shiwei=aa/10; gewei=aa%10; write_date(0x30+shiwei); write_date(0x30+gewei); write_com(0x80+0x40+0x04); break; case 2: write_com(0x80+0x04); for(i=0;i<7;i++) write_date(alarm_set[1][i]);

write_com(0x80+0x40+0x02); write_date(':');

//显示分

//显示Alarm-2

//显示‘:’

write_com(0x80+0x40+0x08); //显示闹钟次数选择

for(i=0;i<8;i++) write_date(alarm_set[3+alarmtimes2][i]); write_com(0x80+0x40); aa=alarm[1][1]; shiwei=aa/10; gewei=aa%10;

write_date(0x30+shiwei); write_date(0x30+gewei);

//显示时

write_com(0x80+0x40+0x03);

//显示分

aa=alarm[1][0]; shiwei=aa/10; gewei=aa%10; write_date(0x30+shiwei); write_date(0x30+gewei); write_com(0x80+0x40+0x04); break;

case 3: write_com(0x80+0x04); for(i=0;i<7;i++) write_date(alarm_set[2][i]);

write_com(0x80+0x40+0x02); write_date(':');

//显示Alarm-3

//显示‘:’

write_com(0x80+0x40+0x08); //显示闹钟次数选择 for(i=0;i<8;i++) write_date(alarm_set[3+alarmtimes3][i]);

write_com(0x80+0x40); aa=alarm[2][1]; shiwei=aa/10; gewei=aa%10;

write_date(0x30+shiwei); write_date(0x30+gewei);

write_com(0x80+0x40+0x03);

aa=alarm[2][0]; shiwei=aa/10; gewei=aa%10; write_date(0x30+shiwei); write_date(0x30+gewei); write_com(0x80+0x40+0x04); } }

/********************************* 函数入口:无 函数出口:无

函数功能:闹钟选择界面显示

*********************************/ void alarm_select_menu() { uchar i; write_com(0x80); for(i=0;i<16;i++) write_date(alarm_menu_init[0][i]); if(alarmclose1==1) { write_com(0x80+0x40+0x02); write_date(alarm_menu_init[1][0]); write_date(alarm_menu_init[1][1]); write_date(alarm_menu_init[1][2]); write_com(0x80+0x40+0x02); } else { write_com(0x80+0x40+0x02);

//显示时

//显示分

//闹钟设置界面第一行 //闹钟1显示ON

//闹钟1显示OFF

write_date(alarm_menu_init[2][0]); write_date(alarm_menu_init[2][1]); write_date(alarm_menu_init[2][2]); write_com(0x80+0x40+0x02);

}

if(alarmclose2==1) { write_com(0x80+0x40+0x07); write_date(alarm_menu_init[1][0]); write_date(alarm_menu_init[1][1]); write_date(alarm_menu_init[1][2]); write_com(0x80+0x40+0x07); }

else { write_com(0x80+0x40+0x07); write_date(alarm_menu_init[2][0]); write_date(alarm_menu_init[2][1]); write_date(alarm_menu_init[2][2]); write_com(0x80+0x40+0x07); }

if(alarmclose3==1) { write_com(0x80+0x40+0x0c); write_date(alarm_menu_init[1][0]); write_date(alarm_menu_init[1][1]); write_date(alarm_menu_init[1][2]); write_com(0x80+0x40+0x0c);

}

else { write_com(0x80+0x40+0x0c); write_date(alarm_menu_init[2][0]); write_date(alarm_menu_init[2][1]); write_date(alarm_menu_init[2][2]); write_com(0x80+0x40+0x0c); } }

/********************************* 函数入口:无 函数出口:无

函数功能:闹钟响铃

//闹钟2显示ON

//闹钟2显示OFF

//闹钟3显示ON

//闹钟3显示OFF

*********************************/ void alarm_start() { uint i=500;

if((alarm[0][0]==time[1])&&(alarm[0][1]==time[2])) { if(alarmtimes1==0) { if((key4==0)||(times>1185)) 钟,关闭闹钟 { TR0=0; alarmclose1=0; times=0;

//闹钟1响铃

//进入响一次部分 //键4按下或响铃一分

alarmclose3=iap_read(1,3); //从EEPROM中读取闹钟状态 alarmclose2=iap_read(1,2); alarmtimes1=iap_read(1,4); alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12); light_times=iap_read(1,13);

iap_sector(1); //擦除扇区1 iap_write(1,13,light_times); //往扇区1写入数据 iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]); iap_write(1,12,alarm[2][1]); }

if(alarmclose1==1) //响铃部分

}

{ }

TR0=1; while(i--) { BZ=!BZ; usdelay(200); }

if(alarmtimes1==1) { if(key4==0) 关闭闹钟 alarmclose1=0;

//进入每天响部分

//键4按下,

if(alarmclose1==1) { TR0=1; while(i--) { BZ=!BZ; usdelay(200); } } if(times>1195) 后一分钟,重新开启闹钟 { TR0=0; alarmclose1=1; times=0; } } } if((alarm[1][0]==time[1])&&(alarm[1][1]==time[2])) { if(alarmtimes2==0) { if((key4==0)||(times>1185)) 分钟之后,关闭闹钟 { TR0=0; alarmclose2=0; times=0; alarmclose3=iap_read(1,3);

//响铃部分

//从开始响铃之

//闹钟2响铃

//进入响一次部分 //键4按下,或响铃一

//从EEPROM中读取闹钟状态

alarmclose1=iap_read(1,1); alarmtimes1=iap_read(1,4); alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12); light_times=iap_read(1,13); iap_sector(1);

//擦除扇区1

iap_write(1,13,light_times); //往扇区1写入数据

iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]); iap_write(1,12,alarm[2][1]); } if(alarmclose2==1) //响铃部分 { TR0=1; while(i--) { BZ=!BZ; usdelay(200); } } } if(alarmtimes2==1) //进入每天响部分 { if(key4==0) //键4按下,关闭闹钟 alarmclose2=0; if(alarmclose2==1) //响铃部分

{ }

TR0=1; while(i--) { BZ=!BZ; usdelay(200); }

if(times>1195) //从开始响铃之后一分钟,重新开启闹钟 { TR0=0; alarmclose2=1; times=0; } } } if((alarm[2][0]==time[1])&&(alarm[2][1]==time[2])) //闹钟3响铃 {

if(alarmtimes3==0) {

//进入响一次部分

if((key4==0)||(times>1185)) //键4按下,或响铃一份中后,关闭闹钟 { TR0=0; alarmclose3=0; times=0; alarmclose1=iap_read(1,1); //从EEPROM中读取闹钟状态 alarmclose2=iap_read(1,2); alarmtimes1=iap_read(1,4); alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12); light_times=iap_read(1,13); iap_sector(1); //擦除扇区1 iap_write(1,13,light_times); //往扇区1写入数据

iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]); iap_write(1,12,alarm[2][1]);

}

if(alarmclose3==1)

{ TR0=1; while(i--) { BZ=!BZ; usdelay(200); } } }

if(alarmtimes3==1)

{

if(key4==0)

关闭闹钟 alarmclose3=0; if(alarmclose3==1) { TR0=1; while(i--) { BZ=!BZ; usdelay(200); } } if(times>1195) 后一分钟,重新开启闹钟 { TR0=0; alarmclose3=1; times=0; }

//响铃部分

//进入每天响部分

//键4按下,

//响铃部分

//从开始响铃之

} } }

/*********************************

函数入口:无 函数出口:无

函数功能:温度显示

*********************************/ void display_temp() { write_com(0x80+0x40+0x09); //显示温度符号 write_date(tempnum[0]); delay(10); write_com(0x80+0x40+0x0a); //显示温度十位 write_date(0x30+tempnum[1]); delay(10); write_com(0x80+0x40+0x0b); //显示温度个位 write_date(0x30+tempnum[2]); delay(10); write_com(0x80+0x40+0x0d); //显示温度小数位 write_date(0x30+tempnum[4]); delay(10); }

/********************************* 函数入口:无 函数出口:无

函数功能:时间显示

*********************************/ void display() { uchar ge,shi,aa; if((alarmclose1==1)||(alarmclose2==1)||(alarmclose3==1)) 打开标志 { write_com(0x80+0x0f); write_date('@'); } else 闹钟打开标志

//主界面显示闹钟

//主界面关闭

{ }

write_com(0x80+0x0f); write_date('');

display_temp(); //显示一次温度 aa=time[5]; //显示星期 write_com(0x80+0x0b); write_date(week[(aa-1)*3]); write_date(week[(aa-1)*3+1]); write_date(week[(aa-1)*3+2]); aa=time[6]; shi=aa/10; ge=aa%10;

write_com(0x80+0x02); write_date(0x30+shi); write_date(0x30+ge); aa=time[4]; //显示月 shi=aa/10; ge=aa%10;

write_com(0x80+0x05); write_date(0x30+shi); write_date(0x30+ge); aa=time[3]; //显示日 shi=aa/10; ge=aa%10;

write_com(0x80+0x08); write_date(0x30+shi); write_date(0x30+ge); aa=time[2]; //显示时 shi=aa/10; ge=aa%10;

write_com(0x80+0x40+0x01); write_date(0x30+shi); write_date(0x30+ge);

aa=time[1]; //显示分 shi=aa/10; ge=aa%10;

write_com(0x80+0x40+0x04); write_date(0x30+shi);

//显示年

write_date(0x30+ge); aa=time[0]; //显示秒 shi=aa/10; ge=aa%10; write_com(0x80+0x40+0x07); write_date(0x30+shi); write_date(0x30+ge); }

/*********************************

函数入口:无 函数出口:无

函数功能:复位DS18B20,并检测设备是否存在 *********************************/ void reset() {

CY = 1; while (CY) {

DQ = 0; //送出低电平复位信号 usdelay(480); //延时至少480us DQ = 1; //释放数据线 usdelay(60); //等待60us

CY = DQ; //检测存在脉冲 usdelay(420); //等待设备释放数据线 } }

/*********************************

函数入口:无

函数出口:读取的数据

函数功能:从DS18B20读1字节数据 *********************************/ uchar temp_read_byte() {

uchar i;

uchar date = 0;

for (i=0; i<8; i++) //循环8次,读取8位数据 {

date>>= 1;

DQ = 0; //开始时间片 usdelay(1); //延时等待

DQ = 1; //准备接收 usdelay(1); //接收延时 if (DQ) date |= 0x80; //如果有高电平,则赋1给date最高位 usdelay(60); //等待时间片结束 }

return date; }

/********************************* 函数入口:需写入的数据 函数出口:无

函数功能:向DS18B20写1字节数据 *********************************/ void temp_write_byte(uchar date) {

uchar i;

for (i=0; i<8; i++) //循环8次,写入8位数据 {

DQ = 0; //开始时间片 usdelay(1); //延时等待

date>>= 1; //数据最低位溢出到CY DQ = CY; //CY为位移溢出位 usdelay(60); //等待时间片结束 DQ = 1; //恢复数据线 usdelay(1); //恢复延时 } }

/********************************* 函数入口:无 函数出口:无

函数功能:从ds18b20读温度并计算 *********************************/ void read_temp() { uchar temp; reset(); //初始化18b20 temp_write_byte(0xcc); //直访ROM temp_write_byte(0x44); //启动温度转换 while (!DQ); //等待转换完成 reset(); //初始化18b20 temp_write_byte(0xcc); //直访ROM temp_write_byte(0xbe); //读SRAM

TPL=temp_read_byte(); //读温度低字节 TPH=temp_read_byte(); //读温度高字节

/******温度计算部分******/ if(TPH&0x08) //温度符号 tempnum[0]='-'; else tempnum[0]=''; temp=TPH&0x07; //整数部分 temp=temp<<4;

temp=temp|(TPL>>4);

tempnum[1]=temp/10; //整数部分十位 tempnum[2]=temp%10; //整数部分个位 temp=TPL&0x0f; //小数部分 tempnum[4]=(temp*5)>>3; /****启动下一次转换****/ reset(); //初始化18b20 temp_write_byte(0xcc); //直访ROM temp_write_byte(0x44); //启动温度转换 }

/********************************* 函数入口:无

函数出口:读取的数据

函数功能:单片机8位读取DS1302函数 *********************************/ uchar time_read_bit() { uchar i; for(i=8;i>0;i--) { rwdata=rwdata>>1; hbit=io; sck=1; usdelay(2); sck=0; usdelay(2); } return rwdata; }

/********************************* 函数入口:需写入的数据 函数出口:无

函数功能:单片机8位写DS1302函数 *********************************/ void time_write_bit(uchar inputdata) { uchar i; rwdata=inputdata; for(i=8;i>0;i--) { io=lbit; sck=1; usdelay(2); sck=0; usdelay(2); rwdata=rwdata>>1; } }

/*********************************

函数入口:地址

函数出口:读出的数据

函数功能:单片机字节读取1302函数 *********************************/ uchar time_read_byte(uchar add) { uchar rdata; rst=0; sck=0; rst=1; time_write_bit(add); rdata=time_read_bit(); sck=1; rst=0; return rdata; }

/********************************* 函数入口:地址

函数出口:需写入的数据

函数功能:单片机单字节写1302函数 *********************************/ void time_write_byte(uchar add,uchar date1) { rst=0;

sck=0; rst=1; time_write_bit(add); time_write_bit(date1); sck=1; rst=0; }

/********************************* 函数入口:无 函数出口:无

函数功能:设定时间函数

*********************************/ void set_time() { uchar i,tmp; uchar add=0x80;

for(i=0;i<7;i++) //十进制转化为BCD码 { tmp=time[i]/10; time[i]=time[i]%10; time[i]=time[i]+tmp*16; }

time_write_byte(0x8e,0x00); //关闭写保护 time_write_byte(0x90,0xaa); //开启电容涓流充电,电流2mA左右 for(i=0;i<7;i++) //将时间值写入1302 {

time_write_byte(add,time[i]); add+=2; }

for(i=0;i<7;i++) //将时间值转化为十进制 { tmp=time[i]/16; time[i]=time[i]%16; time[i]=tmp*10+time[i]; }

time_write_byte(0x8e,0x80); //开启写保护 }

/********************************* 函数入口:无 函数出口:无

函数功能:亮度调节界面键盘扫描函数 *********************************/ void screen_keyscan() {

if(key2==0) { delay(10); if(key2==0) { while(!key2); light_times--; if(light_times==-2) light_times=-1; screen_light(); } }

if(key3==0) { delay(10); if(key3==0) { while(!key3); light_times++; if(light_times==17) light_times=16; screen_light(); } }

if(light_times==-1) ET1=1; else

//键2按下,增加亮度

//键3按下,降低亮度

//开启亮度自动调节

ET1=0; if(key4==0) { delay(5); if(key4==0) { while(!key4); okflag=1;

//键4按下,保存亮度值

alarmclose1=iap_read(1,1); //从EEPROM扇区1中读取数据 alarmclose2=iap_read(1,2); alarmclose3=iap_read(1,3); alarmtimes1=iap_read(1,4); alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[1][0]=iap_read(1,9);

alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12);

iap_sector(1); //擦除扇区1 iap_write(1,13,light_times); //往扇区1写入数据 iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]); iap_write(1,12,alarm[2][2]); } } }

/********************************* 函数入口:无 函数出口:无

函数功能:闹钟设置界面键盘扫描

*********************************/ void alarm_keyscan() { write_com(0x0d); //开启闪烁 if(key1num==1) write_com(0x80+0x40+0x02); //1选项闪烁 if(key1==0) //键1按下后,记录次数 { delay(10);

if(key1==0) //消抖 { key1num++; while(!key1); switch (key1num) { case 1: write_com(0x80+0x40+0x02);break; 闪烁

case 2: write_com(0x80+0x40+0x07);break;

//1选项

//2选项闪烁

case 3: write_com(0x80+0x40+0x0c);break; case 4: key1num=1; 确定标志置1,用来跳出外部大循环 } } } if(key2==0) 键2按下,切换闹钟开关状态 { delay(10); if(key2==0) { while(!key2); switch(key1num) { case 1: alarmclose1=!alarmclose1; 闹钟1开关状态 alarm_select_menu(); write_com(0x80+0x40+0x02); break; case 2: alarmclose2=!alarmclose2;

钟2开关状态

alarm_select_menu();

write_com(0x80+0x40+0x07);

break;

case 3: alarmclose3=!alarmclose3;

钟3开关状态 alarm_select_menu();

write_com(0x80+0x40+0x0c); } }

}

if(key4==0)

按下,确定并退出 { if(key4==0) { while(!key4); alarmtimes1=iap_read(1,4); EEPROM扇区1中读取数据 alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8);

//3选项闪烁 //

//

//切换

//切换闹

//切换闹

//键4

//从

alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12); light_times=iap_read(1,13);

扇区1 iap_sector(1);

iap_write(1,13,light_times);

数据 iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]); iap_write(1,12,alarm[2][1]); okflag=1; } } if(key3==0) 下键3按下 {

设置界面 delay(10); if(key3==0) { while(!key3); write_com(0x01);

write_com(0x0d); switch(key1num) 个闹钟设置 { case 1: while(1) { alarmshi=alarm[0][1];

//擦除

//往扇区1写入

//闹钟选择界面 //进入闹钟时间

//消抖

//清屏 //闪烁

// 判定进入哪

alarmfen=alarm[0][0]; alarmclose1=1;

alarm_set_select=1; 时间设置 按下,切换 按下,确定并退出闹钟设置界面 EEPROM扇区1中读取数据

扇区1 区1写入数据

alarm_set_menu(); //进入闹钟1if(key1==0)

//键1

{ delay(15); if(key1==0) { while(!key1); key1num++; } }

if(key4==0) //键4

{ delay(10); if(key4==0) { while(!key4); alarmclose2=iap_read(1,2); //从 alarmclose3=iap_read(1,3); alarmtimes2=iap_read(1,5); alarmtimes3=iap_read(1,6); alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12); light_times=iap_read(1,13);

iap_sector(1); //擦除

iap_write(1,13,light_times); //往扇 iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2);

iap_write(1,6,alarmtimes3);

//时闪烁

//分闪烁 //响铃次数选择闪烁 加 时加 加

iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]); iap_write(1,12,alarm[2][1]); okflag=1; break; } }

switch(key1num) { case 1: write_com(0x80+0x40+0x01);break; case 2: write_com(0x80+0x40+0x04);break;

case 3: write_com(0x80+0x40+0x08);break;

case 4: key1num=1;

}

if(key2==0) //键2按下,

{ delay(10); if(key2==0) { while(!key2); if(key1num==1) { alarmshi++; //

if(alarmshi==24) alarmshi=0; alarm[0][1]=alarmshi; }

if(key1num==2) { alarmfen++; //分 if(alarmfen==60) alarmfen=0;

alarm[0][0]=alarmfen;

}

铃次数选择

按下,减 时减 分减

响铃次数选择

if(key1num==3) //响

{ alarmtimes1++; if(alarmtimes1==2) alarmtimes1=0;

alarm[0][2]=alarmtimes1;

}

}

}

if(key3==0) //键3

{ delay(10); if(key3==0) { while(!key3); if(key1num==1) { alarmshi--; //

if(alarmshi==-1) alarmshi=23; alarm[0][1]=alarmshi; }

if(key1num==2) { alarmfen--; //

if(alarmfen==-1) alarmfen=59; alarm[0][0]=alarmfen; }

if(key1num==3) //

{ alarmtimes1--;

if(alarmtimes1==-1) alarmtimes1=1;

alarm[0][2]=alarmtimes1;

}

}

}

case 2:

}break; while(1) { alarmshi=alarm[1][1]; alarmfen=alarm[1][0]; alarmclose2=1; 入闹钟2时间设置

切换 确定并退出闹钟设置界面 EEPROM扇区1中读取数据 扇区1

alarm_set_select=2;

//进

alarm_set_menu();

if(key1==0)

//键1按下,

{

delay(15); if(key1==0) { while(!key1); key1num++; } }

if(key4==0) //键4按下,

{ delay(10); if(key4==0) { while(!key4); okflag=1; alarmclose1=iap_read(1,1); //从 alarmclose3=iap_read(1,3); alarmtimes1=iap_read(1,4); alarmtimes3=iap_read(1,6); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[2][0]=iap_read(1,11); alarm[2][1]=iap_read(1,12); light_times=iap_read(1,13);

iap_sector(1); //擦除

区1写入数据

//时闪烁 //分闪烁

//响铃次数选择闪烁 按下,加 //时加

iap_write(1,13,light_times); //往扇 iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]);

iap_write(1,12,alarm[2][1]);

break; } }

switch(key1num) { case 2: write_com(0x80+0x40+0x01);break; case 3: write_com(0x80+0x40+0x04);break; case 4: write_com(0x80+0x40+0x08);break; case 5: key1num=2; } if(key2==0)

//键2

{ delay(10);

if(key2==0) { while(!key2); if(key1num==2) { alarmshi++;

if(alarmshi==24) alarmshi=0; alarm[1][1]=alarmshi; }

if(key1num==3)

分加

响铃次数选择 按下,减 时减 分减 铃次数选择

{

alarmfen++; //

if(alarmfen==60) alarmfen=0; alarm[1][0]=alarmfen; }

if(key1num==4) //

{ alarmtimes2++;

if(alarmtimes2==2) alarmtimes2=0;

alarm[1][2]=alarmtimes2;

}

}

}

if(key3==0) //键3

{ delay(10); if(key3==0) { while(!key3); if(key1num==2) { alarmshi--; //

if(alarmshi==-1) alarmshi=23; alarm[1][1]=alarmshi; }

if(key1num==3) { alarmfen--;

//

if(alarmfen==-1) alarmfen=59; alarm[1][0]=alarmfen; }

if(key1num==4) //响

{

case 3: alarmtimes2--; if(alarmtimes2==-1) alarmtimes2=1; alarm[1][2]=alarmtimes2; } } } }break; while(1) 进入闹钟3时间设置

闹钟设置界面

EEPROM中读取闹钟状态

{ alarmshi=alarm[2][1]; alarmfen=alarm[2][0]; alarmclose3=1; alarm_set_select=3; //

alarm_set_menu();

if(key1==0) //键1按下,切换 { delay(15); if(key1==0) { while(!key1); key1num++; } }

if(key4==0)

//键4按下,确定并退出

{ delay(10);

if(key4==0) { while(!key4); alarmclose1=iap_read(1,1); //从 alarmclose2=iap_read(1,2); alarmtimes1=iap_read(1,4); alarmtimes2=iap_read(1,5); alarm[0][0]=iap_read(1,7); alarm[0][1]=iap_read(1,8); alarm[1][0]=iap_read(1,9); alarm[1][1]=iap_read(1,10); light_times=iap_read(1,13);

扇区1 区1写入数据

//时闪烁

//分闪烁 //响铃次数选择闪烁

时加

iap_sector(1); //擦除

iap_write(1,13,light_times); //往扇 iap_write(1,1,alarmclose1); iap_write(1,2,alarmclose2); iap_write(1,3,alarmclose3); iap_write(1,4,alarmtimes1); iap_write(1,5,alarmtimes2); iap_write(1,6,alarmtimes3); iap_write(1,7,alarm[0][0]); iap_write(1,8,alarm[0][1]); iap_write(1,9,alarm[1][0]); iap_write(1,10,alarm[1][1]); iap_write(1,11,alarm[2][0]);

iap_write(1,12,alarm[2][1]);

okflag=1; break; } }

switch(key1num) { case 3: write_com(0x80+0x40+0x01);break; case 4: write_com(0x80+0x40+0x04);break; case 5: write_com(0x80+0x40+0x08);break; case 6: key1num=3;

} if(key2==0) //键2按下,加 { delay(10); if(key2==0) { while(!key2); if(key1num==3) { alarmshi++; // if(alarmshi==24)

alarmshi=0;

铃次数选择 按下,减 时减 分减

alarm[2][1]=alarmshi; write_com(0x80+0x40+0x01); }

if(key1num==4) { alarmfen++;

//分

if(alarmfen==60) alarmfen=0;

alarm[2][0]=alarmfen;

write_com(0x80+0x40+0x04);

}

if(key1num==5)

//响

{

alarmtimes3++; if(alarmtimes3==2) alarmtimes3=0;

alarm[2][2]=alarmtimes3;

}

}

}

if(key3==0) //键3

{ delay(10); if(key3==0) { while(!key3); if(key1num==3) { alarmshi--; //

if(alarmshi==-1) alarmshi=23; alarm[2][1]=alarmshi; write_com(0x80+0x40+0x01); }

if(key1num==4) { alarmfen--; //

if(alarmfen==-1)

}

}

}

alarmfen=59; alarm[2][0]=alarmfen;

write_com(0x80+0x40+0x04);

//响

铃次数选择 } } } } }

/*********************************

if(key1num==5) { }

alarmtimes3--;

if(alarmtimes3==-1) alarmtimes3=1;

alarm[2][2]=alarmtimes3;

函数入口:无 函数出口:无

函数功能:时间设置界面键盘扫描

*********************************/ void time_keyscan() { write_com(0x0d); //开启闪烁 if(key1num==1) write_com(0x80+0x40+0x08); //秒闪烁 if(key1==0) //键1按下后,记录次数 { delay(28);

if(key1==0) //消抖 { key1num++; while(!key1); switch (key1num) { case 1: write_com(0x80+0x40+0x08);break; case 2: write_com(0x80+0x40+0x05);break; case 3: write_com(0x80+0x40+0x02);break; case 4: write_com(0x80+0x0c);break; case 5: write_com(0x80+0x09);break; case 6: write_com(0x80+0x06);break;

//秒闪烁

//分闪烁 //时闪烁 //星期闪烁 //日闪烁 //月闪烁

case 7: write_com(0x80+0x03);break; case 8: key1num=1; } } }

if(key1num!=0) { if(key2==0) //键2按下 { delay(5); if(key2==0) { while(!key2); switch(key1num) { case 1: miao++; //秒加 if(miao==60) miao=0; time[0]=miao; display(); write_com(0x80+0x40+0x08); break; case 2: fen++; //分加 if(fen==60) fen=0; time[1]=fen; display(); write_com(0x80+0x40+0x05); break; case 3: shi++; //时加 if(shi==24) shi=0; time[2]=shi; display(); write_com(0x80+0x40+0x02); break; case 4: xingqi++; //星期加 if(xingqi==8) xingqi=1; time[5]=xingqi; display();

//年闪烁

write_com(0x80+0x0c); break;

ri++; //日加

if((nian%4==0)&&(yue==2)&&((ri==30)||(ri==31))) { ri=1; }

if((nian%4)&&(yue==2)&&((ri==29)||(ri==30)||(ri==31))) { ri=1; }

if(((yue==4)||(yue==6)||(yue==9)||(yue==11))&&(ri==31)) { ri=1; }

if(ri==32) ri=1;

time[3]=ri; display();

write_com(0x80+0x09); break;

yue++; //月加

if((nian%4==0)&&(yue==2)&&((ri==30)||(ri==31))) { ri=1; }

if((nian%4)&&(yue==2)&&((ri==29)||(ri==30)||(ri==31))) { ri=1; }

if(((yue==4)||(yue==6)||(yue==9)||(yue==11))&&(ri==31)) { ri=1;; }

if(yue==13) yue=1; time[3]=ri; time[4]=yue; display();

write_com(0x80+0x06); break;

case 5:

case 6:

case 7: nian++; //年加 if((nian%4==0)&&(yue==2)&&((ri==30)||(ri==31))) { ri=1; } if((nian%4)&&(yue==2)&&((ri==29)||(ri==30)||(ri==31))) { ri=1; } if(nian==100) nian=0; time[3]=ri; time[6]=nian; display(); write_com(0x80+0x03); } } } if(key3==0) //键3按下 { delay(5); if(key3==0) { while(!key3); switch(key1num) { case 1: miao--; //秒减 if(miao==-1) miao=59; time[0]=miao; display(); write_com(0x80+0x40+0x08); break; case 2: fen--; //分减 if(fen==-1) fen=59; time[1]=fen; display(); write_com(0x80+0x40+0x05); break;

case 3: shi--; if(shi==-1)

//时减

shi=23;

time[2]=shi; display();

write_com(0x80+0x40+0x02); break;

xingqi--; //星期减 if(xingqi==0) xingqi=7; time[5]=xingqi; display(); write_com(0x80+0x0c); break;

ri--; //日减

if((nian%4==0)&&(yue==2)&&(ri==0)) { ri=29; }

if((nian%4)&&(yue==2)&&(ri==0)) { ri=28; }

if(((yue==4)||(yue==6)||(yue==9)||(yue==11))&&(ri==0)) { ri=30; }

if(ri==0) ri=31;

time[3]=ri; display();

write_com(0x80+0x09); break;

yue--; //月减

if((nian%4==0)&&(yue==2)&&((ri==31)||(ri==30))) { ri=1; }

if((nian%4)&&(yue==2)&&((ri==31)||(ri==30)||(yue==29))) { ri=1; }

if(((yue==4)||(yue==6)||(yue==9)||(yue==11))&&(ri==31))

case 4: case 5: case 6:

{ ri=1; }

if(yue==0) yue=12;

time[4]=yue; display();

write_com(0x80+0x06); break;

case 7: nian--; //年减 if(nian==-1) nian=99; time[6]=nian; display(); write_com(0x80+0x03); } } } } }

/*********************************

函数入口:无 函数出口:无

函数功能:读取时钟值函数并转化

*********************************/ void read_time() { uchar i,tmp; uchar add=0x81; okflag=0; for(i=0;i<7;i++) //读取时间值 { time[i]=time_read_byte(add); add+=2; usdelay(5); } for(i=0;i<7;i++) //将读取的时间值转化为十进制 { tmp=time[i]/16; time[i]=time[i]%16; time[i]=tmp*10+time[i];

} if((time[2]==12||time[2]==0)&&(time[1]==0)&&(time[0]==30)) { tmp=time[0]; time[0]=--tmp; set_time(); delay(5500); } }

/********************************* 函数入口:无 函数出口:无

函数功能:检测按键是否按下

*********************************/ void detect_key() {

if(key1==0) { while(1) {

//如果按键一按下,显示菜单,记录键1按下次数

//按键扫描大循环

if(key1==0) { while(!key1); key1num++; }

if(key1num==4) { key1num=0;

init();

//键1按下四次,返回时钟界面

menu_display();

//根据key1num不同的值显示不同菜

单 示

//由菜单界面返回时间显示界面需要初始化显

break; }

if(key4==0) //键4按下 { delay(8); if(key4==0) //消抖 { while(!key4); switch(key1num) { case 1:{ miao=time[0]; //进入设置时间界面 fen=time[1];

置界面需要初始化显示

时间设置按键函数 完时间,跳出循环 置1,用来跳出外部大循环 好的时间写入DS1302 小循环 选择界面 键盘扫描循环 间,跳出循环

shi=time[2]; ri=time[3]; yue=time[4]; xingqi=time[5]; nian=time[6];

write_com(0x01); //清屏 init(); //由菜单转到时间设 read_temp(); //显示一次当前温度 display(); //显示一次当前时间 while(1) //进入键盘扫描循环

{ time_keyscan(); //扫描 if(key4==0)

//设置

{

key1num=0;

write_com(0x0c); //关闪烁 okflag=1; //确定标志 set_time(); //将调

break;

//跳出

} } break; }

case 2:{ write_com(0x01); //清屏 alarm_select_menu(); //显示闹钟

key1num=1; while(1) //进入闹钟

{ alarm_keyscan();

//扫描按键 if(okflag==1) //设置完时

{ key1num=0;

write_com(0x0c); //关闪烁 break; //跳出

}

}

}

break;

write_com(0x01); screen_light(); while(1)

//清屏 //显示亮度

调节界面 case 3: {

{ 界面键盘扫描 }

}

}

}

}

if(okflag==1)

{

init(); break; } } } }

/********************************* 函数功能:主函数

*********************************/ void main() { init(); //初始化 while(1) { read_time(); //读取时间 display(); //显示时间 detect_key(); //检测按键是否按下 read_temp(); //读取温度并转换 display_temp(); //显示温度值 alarm_start(); //闹钟响铃函数 } }

screen_keyscan();

//亮度调节

if(okflag==1) {

break; }

//利用确定标志跳出循环 //初始化显示时间界面

//跳出大循环

/********************************* 函数功能:定时器0中断服务函数 *********************************/ void timer0() interrupt 1 { times++; TH0=(65535-50000)/256; TL0=(65535-50000)%256; }

/********************************* 函数功能:定时器1中断服务函数 *********************************/ void timer1() interrupt 3 { TH1=(65536-50000)/256; TL1=(65536-50000)%256; adc_num++;

if(adc_num==20) { adc_num=0;

//1秒钟AD转换一次

ADC_CONTR=0x88; //开启AD转换 } }

/********************************* 函数功能:ADC模块中断服务函数 *********************************/ void adc() interrupt 5 { auto_num=ADC_RES; auto_num=auto_num*5*100/256; auto_ge=auto_num%10; auto_shi=auto_num%100/10; }

ADC_CONTR=0x80; //关闭AD转换 auto_num=auto_shi*10+auto_ge; if(auto_num<0) //LCD亮度自动调节 CCAP0H=light[16]; else if(auto_num>=85) CCAP0H=light[0]; else CCAP0H=light[16-auto_num/5];

因篇幅问题不能全部显示,请点此查看更多更全内容