1602液晶显示DS1302实时时钟程序 下载本文

}

//外部中断INT0中断处理程序 void int0() interrupt 0 {

TR0=0; //禁止Timer0

IE=0; //禁止中断

lcd_wcmd(0x0e); //显示光标\整个光标不闪烁 alarm=1;

update_disbuf(0x50,\更新显示数据,0x50表示要显示\

pro_display(); //调用显示处理程序

lcd_pos(0x47); //使光标位于第一个调整项下

flag=0;

vkey=0x03;

while(flag^0x0a) {skey = scan_key(); //扫描按键状态

if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体

{ delay(10); //去按键抖动

skey = scan_key(); //转回扫描按键状态

if (skey^vkey) //若skey与vkey相同,跳出循环,相异执行循环体

{ vkey=skey; //将skey的值付给vkey

if (skey==0x01) //PRE键按下

{ flag++; //调整标志位加1

switch (flag) //将光标置于相应调整位置

{

case 1: lcd_pos(0x49);break; //光标置小时报警设置位置

case 2: lcd_pos(0x4c);break; //光标置分钟报警设置位置

case 3: lcd_pos(0x4f);break; //光标置秒时报警设置位置

e 4: update_disbuf(0x50,\

pro_display();

lcd_pos(0x05);break; //光标置年调整位

e 5: lcd_pos(0x08);break; //光标置月调整位置

e 6: lcd_pos(0x0b);break; //光标置日调整位置

e 7: lcd_pos(0x49);break; //光标置时调整位置

e 8: lcd_pos(0x4c);break; //光标置分调整位置

e 9: lcd_pos(0x4f);break; //光标置秒调整位置

ault:break;

} } if (skey==0x02) //SET键按下

{ pro_key(); //转设置按键处理程序

} }

}

cas cas cas cas cas cas def }

lcd_wcmd(0x0c); //设置LCD开显示及光标不闪烁,不显示\

lcd_wcmd(0x01); //清除LCD的显示内容

IE=0x8f; //CPU开中断,INT0,INT1,开中断

TR0=1; //Timer0启动 }

//主程序,初始化及初值设定 void main() {

lcd_init(); //初始化LCD

lcd_sef_chr(); //写入自定义字符号

hour=0;min=0;sec=0; //开机时的时,分,秒显示

armhour=0;armmin=0;armsec=0; //开机时的时,分,秒报警初值

year= 5; month=1;date=1; //开机时的年,月,日,星期显示

week_proc();

alarm=1; //初始开机,启用闹钟

IE = 0x8f; //CPU开中断,INT0,INT1,Timer0,Timer1开中断 IP = 0x04; //设置INT0为中断最高优先级

IT0=0;IT1=0; //外部

INT0,INT1设置为电平触发方式(注意,触发不要选边沿方式,易误动) TMOD = 0x11; //Timer0,Timer1工作于模式1, 16位定时方式

TH0 = 0xdc;TL0 = 0x00; //Timer0置10ms定时初值

TH1 = 0xff;TL1 = 0x00; //Timer1置初值

TR0 = 1; //Timer0启动

TR1 = 0;

while(1); }

//设置按键处理程序 void pro_key() {

switch (flag) {

case 0:alarm=!alarm; //启用或关闭闹钟(alarm=1:启用,alarm=0:关闭)

update_disbuf(0x50,\msec); //更新显示数据

pro_display(); //调用显示处理

lcd_pos(0x47);break; //光标回到原调整位置 case 1:armhour++;

if (armhour>23) armhour=0;

update_disbuf(0x50,\msec); //更新显示数据

pro_display(); //调用显示处理

lcd_pos(0x49);break; //光标回到原调整位置 case 2:armmin++;

if (armmin>59) armmin=0;

update_disbuf(0x50,\msec);

pro_display();

lcd_pos(0x4c);break; case 3:armsec++;

if (armsec>59) armsec=0;

update_disbuf(0x50,\msec);

pro_display();

lcd_pos(0x4f);break;

case 4:year++;

if (year> 99) year= 0;

week_proc(); //星期自动运算

update_disbuf(0x50,\\

pro_display();