注:本程序并没有显示星期,如有需要,可自行添加。
/****************************************************** *实验名称:智能电子钟(LCD显示)
*实验效果:1602显示时钟,按K1进入时间设置,K2分别选择秒 * 分时日月星期年,按K3时间加一
/******************************************************/ #include
#define uint unsigned int #define uchar unsigned char
/******************************************************
**声明:本实验所有IO口只与“1302时钟按键设置”仿真图配套* *
/******************************************************/
sbit K1=P3^2; //接的是INT0 K1时钟设置 (按一下开始调节时间,再按一下退出调节时间)
sbit K2=P3^3; //接的是INT1 K2选择秒分时日月星期年 sbit K3=P3^4; //接的是TO K3加时间
void Cursor(); //设置时光标闪烁 void Delay10ms();
void Int0Configuration();//外部中断0设置 void LcdDisplay(); //显示函数
uchar SetState,SetPlace; //设置状态、光标位置
void main() //主函数 { uchar i; Int0Configuration(); //外部中断0设置 lcd1602Init(); //1602初始化 ds1302Init(); //1302初始化 while(1) { if(SetState==0) //如果没有键按下,就显示时间 { //SetState的高低由中断控制,按下K1则为1,再次按下则为0 ds1302readtime(); } else { if(K2==0) //消除抖动 { Delay10ms();
if(K2==0) //如果K2被按下,则光标移动 { SetPlace++; if(SetPlace>=7) //年月日星期时分秒 共7个时间 SetPlace=0; } while((i<50)&&(K2==0)) //松手检测 { Delay10ms(); i++; } i=0; }
if(K3==0) //如果K3被按下,则时间每次加1 { Delay10ms(); //消除抖动 if(K3==0) { TIME[SetPlace]++; if((TIME[SetPlace]&0x0f)>9) //换成BCD码 { TIME[SetPlace]=TIME[SetPlace]+6; } if((TIME[SetPlace]>0x60)&&(SetPlace<2)) //分秒只能到59 { TIME[SetPlace]=0; } if((TIME[SetPlace]>0x24)&&(SetPlace==2)) //小时只能到23 { TIME[SetPlace]=0; } if((TIME[SetPlace]>0x32)&&(SetPlace==3)) //日只能到31 { TIME[SetPlace]=0; } if((TIME[SetPlace]>0x13)&&(SetPlace==4)) //月只能到12 { TIME[SetPlace]=0; } if((TIME[SetPlace]>0x7)&&(SetPlace==5)) //周只能到7 { TIME[SetPlace]=0; } if((TIME[SetPlace]>0x99)&&(SetPlace==6)) //年只能到2099
{ TIME[SetPlace]=0; } } while((i<50)&&(K3==0)) //松手检测 { Delay10ms(); i++; } i=0; } } LcdDisplay(); //Lcd1602显示时间 } }
void LcdDisplay() //显示函数 { writecom(0x80+0x40); writedata('T'); writedata('I'); writedata('M'); writedata('E'); writedata(':'); writedata('0'+TIME[2]/16); //时 writedata('0'+(TIME[2]&0x0f)); writedata(':'); writedata('0'+TIME[1]/16); //分 writedata('0'+(TIME[1]&0x0f)); writedata(':'); writedata('0'+TIME[0]/16); //秒 writedata('0'+(TIME[0]&0x0f)); writecom(0x80); writedata('D'); writedata('A'); writedata('T'); writedata('E'); writedata(':'); writedata('2'); //年 writedata('0'); writedata('0'+TIME[6]/16); writedata('0'+(TIME[6]&0x0f));
writedata('-'); writedata('0'+TIME[4]/16); //月 writedata('0'+(TIME[4]&0x0f)); writedata('-'); writedata('0'+TIME[3]/16); //日 writedata('0'+(TIME[3]&0x0f)); }
void Delay10ms() //延时10ms {
uchar a,b,c; for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--); }
void Int0Configuration() //设置外部中断0 { IT0=1;//跳变沿触发 EX0=1;//打开外部0中断 EA=1; //打开总中断 }
void Int0() interrupt 0 //如果按下K1就进入中断 { Delay10ms(); if(K1==0) { // writecom(0x80+0x40+12); // writecom(0x0f); SetState=~SetState; SetPlace=0; ds1302Init();//调过时间后再按下K1,调好的时间就被写进DS1302 } }
------------------------------------------------------分割线------------------------------------------------------
#ifndef _LCD1602_H_ #define _LCD1602_H_
//---包含头文件---// #include
//---宏定义关键词---// #ifndef uint
#define uint unsigned int #endif
#ifndef uchar
#define uchar unsigned char #endif
//---定义1602的IO口---// sbit E=P2^2; sbit RW=P2^1; sbit RS=P2^0;
//---声明全局函数---// void delay1ms(uint z); void writecom(uchar com); void writedata(uchar dat); void lcd1602Init();
#endif
#include\
/*********函数功能:延时函数,延时1ms*********/ void delay1ms(uint c) { uchar a,b; for (; c>0; c--) for (b=199;b>0;b--) for(a=1;a>0;a--); }
/*********函数功能:向1602写入一个字节的指令*********/ void writecom(uchar com) { E=0; //使能端口 RW=0; //低电平选择写入 RS=0; //低电平选择写入指令 P0=com; //放入指令 delay1ms(1); //等待数据稳定