找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2096|回复: 2
收起左侧

具有校正功能的时钟1302

[复制链接]
ID:111634 发表于 2016-5-4 22:16 | 显示全部楼层 |阅读模式

实例91 具有校正功能的时钟1302LCD1602显示)

上例时钟电路是开机显示PC机时间,无时钟校正功能,本例具有时钟校正功能。

电路设计

在上例时钟电路的基础上,加入3个时钟修正按键:K0(修正)、K1(移位)和K2(加1),分别与80C51P2.7P2.5P2.3连接,如图7-6所示


  
    



图7-6.jpg



程序设计

7-6电路,要求开机显示201211134758秒,星期日(7),且要求K0K1K2具有时钟校正功能,其控制过程为:按下K0(带锁),进入时钟修正;首先年数据(12)快速闪烁,表示可被修正;按一次K1(不带锁),被修正位(快速闪烁)按年、周、月、日、时、分、秒次序循环往复;按一次K2(不带锁),被修正位加1(最大值不超过时钟规定值,超过复0);时钟修正期间,计时继续运行;释放K0,退出时钟修正。

#include <reg51.h>                      //包含访问sfr库函数reg51.h

sbit  RST=P1^0;                        //定义RSTP1.01302复位/片选端)

sbit  SCLK=P1^1;                     //定义SCLKP1.11302时钟端)

sbit IO=P1^2;                         //定义IOP1.21302数据端)

sbit E=P1^3;                          //定义EP1.31602使能片选端)

sbit  RW=P1^4;                        //定义RWP1.41602/写控制端)

sbit RS=P1^5;                        //定义RSP1.51602寄存器选择端)

sbit K0=P2^7;                         //定义K0P2.7(时钟修正标志键)

sbit K1=P2^5;                         //定义K1P2.5(时钟修正移位键)

sbit K2=P2^3;                         //定义K2P2.3(时钟修正加1键)

sbit  ACC7=ACC^7;                     //定义ACC7为累加器A7ACC.7

bit  f=0;                               //定义0.15s标志f

unsigned char  m=0;                     //定义50ms计数器m,并赋初值0

unsigned char  n=6;                     //定义修正位序号nn赋初值6(年序号)

unsigned char  b[8];          //定义时钟数据数组b,内存秒分时日月周年即时读出值(BCD码)

unsigned char  y[]="2000-00-00-Week0";        //定义1602第一行年月日数组y20××-××-××-Week×

unsigned char  h[]="00:00:00--------";            //定义1602第二行时分秒数组h××:××:××--------

void  Wr8b (unsigned char  d);           //13028位数据子函数(写入数据d)。略,见实例90

unsigned char  Rd8b ();                  //13028位数据子函数。略,见实例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

时钟修正键.jpg


主函数.jpg


T0中断函数.jpg

Keil调试

本题Keil调试同上例。因涉及外围元件DS1302LCD1602,在Keil软件调试中无法得到外围元件的有效信号。因此,仅在Keil中,按实例1所述步骤,编译链接,语法纠错,自动生成Hex文件,并在变量观察窗口Watch页中设置(设置方法参阅8-30)全局变量b(时钟数据数组)、y(第一行年月日数组)和h(第二行时分秒数组),获得数组b[]y[]h[]的首地址(分别为0x210x3c0x29,用于在Proteus仿真中观测)。

需要注意的是,引用前述实例中的9个子函数必须插入,否则Keil调试将显示出错。


Proteus仿真

实例23所述Proteus仿真步骤,打开Proteus ISIS软件,按7-4选择和放置元器件,并连接线路,画出Proteus仿真电路如7-7所示。

表7-4.jpg



图7-7.jpg


鼠标左键双击Proteus ISIS仿真电路中AT89C51,装入Keil调试后自动生成的Hex文件。

全速运行后,1602显示实时时钟,初始值为程序中设置的201211134758秒,周7(日),并随后不断更新实时数值

按下K0(锁定),进入时钟修正。

需要说明的是,本例选用的BUTTON按键有两种运行功能:有锁运行和无锁运行。作有锁运行时,鼠标左键单击按键图形中小红圆点,单击第一次闭锁,第二次开锁。作无锁运行时,鼠标左键单击按键图形中键盖帽“   ”,单击一次,键闭合后弹开一次,不闭锁。

首先年数据快速闪烁,表示年数据允许修正。此时每按一次K2(鼠标左键单击键图形中键盖帽“    ”,单击一次,键闭合后弹开一次,不闭锁),年数据显示数加1,但不超过年最大值2099,超过时复位2000

若再按一次K1(不闭锁,方法同K2),被修正位(快速闪烁,表示该位允许修正)移至周数据,每按一次K2,周数据显示数加1,但不超过周最大值7,超过时复位1

再按一次K1,被修正位(快速闪烁)移至月数据,每按一次K2,月数据显示数加1,但不超过月最大值12,超过时复位1

再按一次K1,被修正位(快速闪烁)移至日数据,每按一次K2,日数据显示数加1,但不超过规定的最大值(闰年2月,日数≤29;非闰年2月,日数≤2846911月,日数≤30;其余月份,日数≤31),超过时复位1

再按一次K1,被修正位(快速闪烁)移至时数据,每按一次K2,时数据显示数加1,但不超过最大值23,超过时复位0

再按一次K1,被修正位(快速闪烁)移至分数据,每按一次K2,分数据显示数加1,但不超过最大值59,超过时复位0

再按一次K1,被修正位(快速闪烁)移至秒数据,每按一次K2,秒数据显示数加1,但不超过最大值59,超过时复位0

再按一次K1,被修正位(快速闪烁)重新移至年数据。这样,按年周月日时分秒次序循环往复;按一次K2(不带锁),被修正位加1(最大值不超过时钟规定值);释放K0,退出时钟修正。

再按一次K0K0释放,退出时钟修正。

按暂停按钮,打开80C51片内RAM(主菜单Debug80C51 CPUInternalIDATAMemory -U1),可看到21H28H29H38H3CH4BH中,已经依次存放了时钟数据数组b[]、第二行时分秒数组h[]和第一行年月日数组y[]的即时数据。

终止程序运行,可按停止按钮。

思考与练习

秒、分、时、日、月、周、年数据上限值各不相同,加一超限时如何判别修正?

实例91 带校正时钟1302(LCD1602显示).rar (52.74 KB, 下载次数: 19)
回复

使用道具 举报

ID:73030 发表于 2016-5-4 22:40 来自手机 | 显示全部楼层
这个不错,谢谢楼主分享。
回复

使用道具 举报

ID:194936 发表于 2017-5-2 20:00 | 显示全部楼层
谢谢楼主分享!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表