} } }
//------------------减键key3,各句功能参照'加键'注释--------------- if(key3==0) {
delay(10);//调延时,消抖动 if(key3==0) {
buzzer=0;//蜂鸣器短响一次 delay(20); buzzer=1;
while(!key3); switch(key1n) {
case 1:miao--;
if(miao==-1)
miao=59;//秒数据减到-1时自动变成59
write_sfm(0x08,miao);//在LCD的正确位置显示改变后新的秒数
temp=(miao)/10*16+(miao);//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒 write_1302(0x8e,0x80); //打开写保护
write_1602com(er+0x09);//写回原来的位置 break; if(fen==-1) fen=59;
write_sfm(5,fen);
temp=(fen)/10*16+(fen);//十进制转换成DS1302要求的DCB码
数据BCD码
case 2:fen--;
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x82,temp);//向DS1302内写分寄存器写入调整后的分数据 write_1302(0x8e,0x80);//打开写保护
write_1602com(er+6);//写回原来的位置 break;
case 3:shi--;
27
if(shi==-1) shi=23;
write_sfm(2,shi);
temp=(shi)/10*16+(shi);//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x84,temp);//写小时寄存器写入调整后的小时数据 write_1302(0x8e,0x80);//打开写保护
write_1602com(er+3);//光标回位 break;
if(week==0)
week=7;
case 4:week--;
write_1602com(yh+0x0C);//指定'加'后的周数据显示位置
write_week(week);//指定周数据显示内容
temp=(week)/10*16+(week);//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8a,temp);//写周寄存器8aH写入调整后的周数据 write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+0x0e);//光标回位 break;
if(ri==0)
ri=31;
case 5:ri--;
write_nyr(9,ri);
temp=(ri)/10*16+(ri);//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x86,temp);//写日期寄存器86H写入调整后的日期数据 write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+10);//光标回位 break;
if(yue==0)
yue=12;
case 6:yue--;
write_nyr(6,yue);
temp=(yue)/10*16+(yue);//十进制转换成DS1302要求的DCB码
28
{ }
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x88,temp);//写月份寄存器88H写入调整后的月份数据 write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+7);//光标回位 break;
case 7:nian--; if(nian==-1)
nian=99;
write_nyr(3,nian);
temp=(nian)/10*16+(nian);//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8c,temp);//写年份寄存器8cH写入调整后的年份数据 write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+4);//光标回位 break;
} } } } }
void init() //定时器、计数器设置函数
TMOD=0x11; //指定定时/计数器的工作方式为3 TH0=0; //定时器T0的高四位=0 TL0=0; //定时器T0的低四位=0 EA=1; //系统允许有开放的中断 ET0=1; //允许T0中断
TR0=1; //开启中断,启动定时器
//*******************主函数************************** void main() {
lcd_init(); //调用液晶屏初始化子函数 ds1302_init(); //调用DS1302时钟的初始化子函数 init(); //调用定时计数器的设置子函数 led=0; //打开LCD的背光电源
buzzer=0;//蜂鸣器长响一次 delay(80); buzzer=1;
29
while(1) //无限循环下面的语句: {
keyscan(); //调用键盘扫描子函数 } }
void timer0() interrupt 1 //取得并显示日历和时间 {
flag=ReadTemperature();//将18b2头文件运行返回的函数结果送到变量FLAG中,用于显示
miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83)); shi = BCD_Decimal(read_1302(0x85)); ri = BCD_Decimal(read_1302(0x87)); yue = BCD_Decimal(read_1302(0x89)); nian=BCD_Decimal(read_1302(0x8d)); week=BCD_Decimal(read_1302(0x8b));
write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示
write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数) }
write_sfm(5,fen);//分,从第二行第5个字符后开始显示 write_sfm(2,shi);//小时,从第二行第2个字符后开始显示 //显示日、月、年数据:
write_nyr(9,ri);//日期,从第二行第9个字符后开始显示 write_nyr(3,nian);//年,从第二行第3个字符后开始显示 write_week(week);
write_nyr(6,yue);//月份,从第二行第6个字符后开始显示
附录三:温度转换子程序
sbit DQ = P3^3; // 定义DQ引脚为P3.3 void DS18_delay(int useconds) { int s;
for (s=0; s unsigned char ow_reset(void) { 30 unsigned char presence; DQ = 0; DQ = 1; // 将 DQ 线拉低 // 保持 480μs // 等待存在脉冲 // 等待时间隙结束 // DQ返回高电平 // 获得存在信号 // 返回存在信号,0 = 器件存在, 1 = 无器件 DS18_delay(29); DS18_delay(3); presence = DQ; DS18_delay(25); return(presence); } void write_bit(char bitval) { DQ = 0; // 将DQ 拉低开始写时间隙 // 如果写1,DQ 返回高电平 // 在时间隙内保持电平值, if(bitval==1) DQ =1; DS18_delay(5); } void ds18write_byte(char val) { unsigned char i; unsigned char temp; for (i=0; i<8; i++) { temp = val>>i; temp &= 0x01; } DS18_delay(5); } unsigned char read_bit(void) { unsigned char i; DQ = 0; DQ = 1; //将DQ 拉低开始读时间隙 // then return high // 延时15μs // 返回 DQ 线上的电平值 write_bit(temp); // 写入字节, 每次写入一位 DQ = 1; // DS18_delay函数每次循环延时16μs,因此DS18_delay(5) = 104μs for (i=0; i<3; i++); return(DQ); } unsigned char DSread_byte(void) { unsigned char i; unsigned char value = 0; 31 for (i=0;i<8;i++) { DS18_delay(6); } return(value); } unsigned // 读取字节,每次读取一个字节 if(read_bit()) value|=0x01< int ReadTemperature(void) { unsigned char get[10]; unsigned char temp_lsb,temp_msb; unsigned int t; unsigned char k; ow_reset(); ds18write_byte(0xCC); ds18write_byte(0x44); DS18_delay(5); ow_reset(); ds18write_byte(0xCC); ds18write_byte(0xBE); // 跳过 ROM // 读暂存器 // 跳过 ROM // 启动温度转换 for (k=0;k<2;k++){get[k]=DSread_byte();} temp_msb = get[1]; // Sign byte + lsbit temp_lsb = get[0]; // Temp data plus lsb t=temp_msb*256+temp_lsb; t=t&0x0ff0; if(t<0xff&&t>0xf0) t=(-1)*t; return t>>4; //temp_f = (((int)temp_c)* 9)/5 + 32; } 32