实例91 具有校正功能的时钟1302(LCD1602显示)
上例时钟电路是开机显示PC机时间,无时钟校正功能,本例具有时钟校正功能。
⒈ 电路设计
在上例时钟电路的基础上,加入3个时钟修正按键:K0(修正)、K1(移位)和K2(加1),分别与80C51P2.7、P2.5和P2.3连接,如图7-6所示。
⒉ 程序设计
按图7-6电路,要求开机显示2012年1月1日13时47分58秒,星期日(7),且要求K0、K1和K2具有时钟校正功能,其控制过程为:按下K0(带锁),进入时钟修正;首先年数据(12)快速闪烁,表示可被修正;按一次K1(不带锁),被修正位(快速闪烁)按年、周、月、日、时、分、秒次序循环往复;按一次K2(不带锁),被修正位加1(最大值不超过时钟规定值,超过复0);时钟修正期间,计时继续运行;释放K0,退出时钟修正。
#include <reg51.h> //包含访问sfr库函数reg51.h
sbit RST=P1^0; //定义RST为P1.0(1302复位/片选端)
sbit SCLK=P1^1; //定义SCLK为P1.1(1302时钟端)
sbit IO=P1^2; //定义IO为P1.2(1302数据端)
sbit E=P1^3; //定义E为P1.3(1602使能片选端)
sbit RW=P1^4; //定义RW为P1.4(1602读/写控制端)
sbit RS=P1^5; //定义RS为P1.5(1602寄存器选择端)
sbit K0=P2^7; //定义K0为P2.7(时钟修正标志键)
sbit K1=P2^5; //定义K1为P2.5(时钟修正移位键)
sbit K2=P2^3; //定义K2为P2.3(时钟修正加1键)
sbit ACC7=ACC^7; //定义ACC7为累加器A第7位ACC.7
bit f=0; //定义0.15s标志f
unsigned char m=0; //定义50ms计数器m,并赋初值0
unsigned char n=6; //定义修正位序号n,n赋初值6(年序号)
unsigned char b[8]; //定义时钟数据数组b,内存秒分时日月周年即时读出值(BCD码)
unsigned char y[]="2000-00-00-Week0"; //定义1602第一行年月日数组y:20××-××-××-Week×
unsigned char h[]="00:00:00--------"; //定义1602第二行时分秒数组h:××:××:××--------
void Wr8b (unsigned char d); //1302写8位数据子函数(写入数据d)。略,见实例90
unsigned char Rd8b (); //1302读8位数据子函数。略,见实例90
void Cmd_Wr(unsigned char c,d); //1302命令写一字节子函数。略,见实例90
void Bst_Rd (unsigned char t[]); //1302突发读时钟子函数。形参t[]。略,见实例90
void Bst_Wr(unsigned char t[]); //1302突发写时钟子函数。略,见实例90
void out (unsigned char x); //1602并行数据输出子函数。略,见实例61
void init1602 ( ); //1602初始化设置子函数。略,见实例61
void wr1602(unsigned char d[],a); //写1602子函数。略,见实例61
void chag (unsigned char y[],unsigned char h[],unsigned char b[]); //时钟数据转换显示数子函数
//形参:1602第一行显示数组y[]、第二行显示数组h[]、时钟数据数组b[]。略,见实例90
⒊ Keil调试
本题Keil调试同上例。因涉及外围元件DS1302和LCD1602,在Keil软件调试中无法得到外围元件的有效信号。因此,仅在Keil中,按实例1所述步骤,编译链接,语法纠错,自动生成Hex文件,并在变量观察窗口Watch页中设置(设置方法参阅图8-30)全局变量b(时钟数据数组)、y(第一行年月日数组)和h(第二行时分秒数组),获得数组b[]、y[]和h[]的首地址(分别为0x21、0x3c、0x29,用于在Proteus仿真中观测)。
需要注意的是,引用前述实例中的9个子函数必须插入,否则Keil调试将显示出错。
⒋ Proteus仿真
⑴ 按实例23所述Proteus仿真步骤,打开Proteus ISIS软件,按表7-4选择和放置元器件,并连接线路,画出Proteus仿真电路如图7-7所示。
⑵ 鼠标左键双击Proteus ISIS仿真电路中AT89C51,装入Keil调试后自动生成的Hex文件。
⑶ 全速运行后,1602显示实时时钟,初始值为程序中设置的2012年1月1日13时47分58秒,周7(日),并随后不断更新实时数值。
⑷ 按下K0(锁定),进入时钟修正。
需要说明的是,本例选用的BUTTON按键有两种运行功能:有锁运行和无锁运行。作有锁运行时,鼠标左键单击按键图形中小红圆点,单击第一次闭锁,第二次开锁。作无锁运行时,鼠标左键单击按键图形中键盖帽“ ”,单击一次,键闭合后弹开一次,不闭锁。
① 首先年数据快速闪烁,表示年数据允许修正。此时每按一次K2(鼠标左键单击键图形中键盖帽“ ”,单击一次,键闭合后弹开一次,不闭锁),年数据显示数加1,但不超过年最大值2099,超过时复位2000。
② 若再按一次K1(不闭锁,方法同K2),被修正位(快速闪烁,表示该位允许修正)移至周数据,每按一次K2,周数据显示数加1,但不超过周最大值7,超过时复位1。
③ 再按一次K1,被修正位(快速闪烁)移至月数据,每按一次K2,月数据显示数加1,但不超过月最大值12,超过时复位1。
④ 再按一次K1,被修正位(快速闪烁)移至日数据,每按一次K2,日数据显示数加1,但不超过规定的最大值(闰年2月,日数≤29;非闰年2月,日数≤28;4、6、9、11月,日数≤30;其余月份,日数≤31),超过时复位1。
⑤ 再按一次K1,被修正位(快速闪烁)移至时数据,每按一次K2,时数据显示数加1,但不超过最大值23,超过时复位0。
⑥ 再按一次K1,被修正位(快速闪烁)移至分数据,每按一次K2,分数据显示数加1,但不超过最大值59,超过时复位0。
⑦ 再按一次K1,被修正位(快速闪烁)移至秒数据,每按一次K2,秒数据显示数加1,但不超过最大值59,超过时复位0。
⑧ 再按一次K1,被修正位(快速闪烁)重新移至年数据。这样,按年周月日时分秒次序循环往复;按一次K2(不带锁),被修正位加1(最大值不超过时钟规定值);释放K0,退出时钟修正。
⑸ 再按一次K0,K0释放,退出时钟修正。
⑹ 按暂停按钮,打开80C51片内RAM(主菜单Debug→80C51 CPU→Internal(IDATA)Memory -U1),可看到21H~28H、29H~38H和3CH~4BH中,已经依次存放了时钟数据数组b[]、第二行时分秒数组h[]和第一行年月日数组y[]的即时数据。
⑺ 终止程序运行,可按停止按钮。
⒌ 思考与练习
秒、分、时、日、月、周、年数据上限值各不相同,加一超限时如何判别修正?
|