电子说
1 设计任务
电子数字电子钟是单片机系统的一个应用,由硬件和软件相配合使用。硬件由主控器、时钟电路、显示电路、键盘接口4个模块组成。主控模块用STC89C52RC、时钟电路用时钟芯片DS1302、显示模块用 LCD1602、键盘接口电路用普通按键接上拉电阻完成;软件利用C语言编程实现单片机程序控制。单片机通过时钟芯片DS1302获取时间数据,通过1602液晶显示器进行显示阳历年、月、日、时、分、秒、星期。
数字电子钟的功能要求:数字电子钟能用1602液晶显示屏第一行显示年、月、日、星期,第二行显示秒、分、时。
数字电子钟的按键要求:四个独立按键的功能分别为:K1对秒、分、时的选择,K4对年、月、日的选择,K2加,K3减。
2 系统硬件设计
2.1 器件选择
本系统以 AT89S52 单片机为控制核心,时钟芯片DS1302,将得到的数据通过 1602液晶显示出来,同时通过相应的按键调整相应的值。51单片机的硬件资源分配:单片机最小系统模块:STC89C52RC单片机芯片;复位电路;晶振电路。本模块AT89C52RC系统控制核心,单片机系统复位由按键电平复位电路完成,并设计独立按键调节时间,本次设计显示为6位,采用两个四位一体数码管(共阳极)作为显示窗口,既可以节约成本又能简化电路。STC89C52RC单片机包含中央处理器、程序寄存器(ROM)、数据存储器(ROM)、并行接口、串行接口和举行键盘等几大单元及数据总线、地址总线、和控制总线等三大总线。STC89C52RC共有4组8位I/O口(P0、P1、P2、P3),用于对外部数据的传输。
2.2 硬件原理图
STC89C52RC芯片有40个引脚:
(1)电源及时钟引脚(4个)
Vcc:电源接入引脚。
GND:接地引脚。
XTAL1:晶体振荡器接入的一个引脚。
XTAL2:晶体振荡器接入的另一个引脚。
(2)控制线引脚(4个)
RST:复位信号输入引脚。
ALE/PROG:地址锁存允许信号输出/编程脉冲引脚。
EA:内外存储器选择引脚。
PSEN:外部程序存储器(ROM)选通信号输出引脚。
(3)并行I/O引脚(32个,分成4个8位端口)
P0.0- P0.7:一般I/O端口引脚或数据/低位地址总线复用引脚。
P1.0- P1.7:一般I/O端口引脚。
P2.0- P2.7:一般I/O端口引脚或高位地址总线引脚。
P3.0- P3.7:一般I/O端口引脚或第二功能引脚。
STC89C52RC芯片,如图2.1所示:
图2.1 STC89C52RC芯片
1602 液晶功耗较小可直接与单片机接口相接,电源直接与电源电路相接,使用单片机的P0口和P1口与1602进行通信。1602 相应功能特性介绍 n +5V 电压,对比度可调 n 内含复位电路n 提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能 n有80字节显示数据存储器 DDRAM n内建有160个 5X7 点阵的字型的字符发生器 CGROM n 8 个可由用户自定义的5X7的字符发生器CGRAM ,如图2.2所示:
图2.2 1602硬件原理图
DS1302时钟芯片包括实时时钟/日历和31字节的静态RAM。它经过一个简单的串行接口与微处理器通信。实时时钟/日历提供秒、分、时、日、周、月和年等信息。对于小于31天的月和月末的日期自动调整,还包括闰年校正的功能。时钟的运行可以采用24h或带AM(上午)/PM(下午)的12h格式。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302有主电源/后备电源双电源引脚:Vcc1在单电源与电池供电的系统中提供低电源,并提供低功率的电池备份;Vcc2在双电源系统中提供主电源,在这种运用方式中,Vcc1连接到备份电,以便在没有主电源的情况下能保存时间信息以及数据。DS1302由Vcc1或Vcc2中较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电;当Vcc2小于Vcc时, DS13026由Vcc1供电。如图2.3所示:
图2.3 DS1302时钟模块原理图
按键部分电路采用独立式按键,各按键相互独立,每个按键单独占用一根I/O口线,每根I/O口线的按键工作状态不会影响其他I/O口线上的工作状态。因此,通过检测输入线的电平状态可以很容易判断哪个按键被按下了。独立式按键接口电路配置灵活,软件结构简单。但每个按键需占用一根I/O口线,在按键数量较多时,I/O口浪费大。因此,独立式按键主要用于按键较少或操作速度较高的场合。本次设计需要按键数较少,故选用独立式按键。独立式按键接口电路如图2.4所示:
图2.4 独立式按键接口电路
3 系统软件设计
3.1总体方案组成框图
(1)主程序流程图如图3.1所示:
图3.1 主程序流程图
(2)子程序流程图如图3.2所示:
图3.2 时间调整程序流程图
3.2软件清单
void delay()此函数为延时函数
void write_com()此函数为写入命令函数
void write_date()此函数为写入数据函数
void init() 此函数为初始函数
void write_sfm()此函数是时间设置地址,将数据写入对应的地址的函数
void write_riqi()此函数是日期设置 将数据写入对应的地址的函数
void keyscan()此函数是时间按键函数
void riqi_xq() 此函数是显示星期的函数
void keys_riqi() 此函数是显示日期的函数
void main() 此函数为主函数
下图中为子函数
#include#define uchar unsigned char#define uint unsigned int
sbit dula=P2^6;sbit wela=P2^7;sbit lcdrs=P1^0;sbit lcdrw=P1^1;sbit lcden=P2^5;
sbit s1=P3^4;sbit s2=P3^5;sbit s3=P3^6;//sbit s4=P3^0;//sbit s8=P3^1;
//sbit s12=P3^2;sbit s4=P3^7;
uchar tt,s1num,s4num;char shi,fen,miao,shiji,nian,yue,ri,xq;
//string char code tabe2[7]={"MON","TUE","WED","THU","FRI","SAR","SUN"};
uchar code tabe[15]=" 2020_12-12_SAR";uchar code tabe1[14]=" 30:30:20 ";
void delay(uint n)
{
while(n--)
{
uchar i;for(i=113;i >0;i--);
}
}
void write_com(uchar com)
{
lcdrw=0;lcdrs=0;P0=com;
delay(5);lcden=1;delay(5);lcden=0;
}
void write_date(uchar date)
{
lcdrw=0;lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;
}
void init()
{
uchar num;dula=0;wela=0;lcden=0;shi=20;fen=30;miao=30;ri=12;yue=12;
nian=20;shiji=20;write_com(0x01);write_com(0x3c);write_com(0x0c);
write_com(0x06);write_com(0x80);for(num=0;num< 15;num++)
{
write_date(tabe[num]);delay(10);
}
write_com(0x80+0x40);for(num=0;num< 14;num++)
{
write_date(tabe1[num]);delay(10);
}
TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar sh,ge;sh=date%100/10;ge=date%10;write_com(0x80+0x40+add);
write_date(0x30+sh);write_date(0x30+ge);
}
void write_riqi(uchar add,uint date)
{
uchar sh,ge;sh=date%100/10;ge=date%10;write_com(0x80+add);
write_date(0x30+sh);write_date(0x30+ge);
}
void keyscan()
{
if(s1==0)
{
delay(5);if(s1==0)
{
while(!s1);s1num++;if(s1num==1)
{
TR0=0;write_com(0x80+0x40+3);write_com(0x0f);
}
if(s1num==2)
{
write_com(0x80+0x40+6);
}
if(s1num==3)
{
write_com(0x80+0x40+9);
}
if(s1num==4)
{
s1num=0;TR0=1;write_com(0x0c);
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);if(s2==0)
{
while(!s2);if(s1num==1)
{
miao++;if(miao==60)
miao=0;write_sfm(3,miao);write_com(0x080+0x40+3);
}
if(s1num==2)
{
fen++;if(fen==60)
fen=0;write_sfm(6,fen);write_com(0x080+0x40+6);
}
if(s1num==3)
{
shi++;if(shi==24)
shi=0;write_sfm(9,shi);write_com(0x080+0x40+9);
}
}
}if(s3==0)
{
delay(5);if(s3==0){
while(!s3);if(s1num==1
{
miao--;if(miao==-1)
miao=59;write_sfm(3,miao);write_com(0x80+0x40+3);
}
if(s1num==2)
{
fen--;if(fen==-1)
fen=59;write_sfm(6,fen);write_com(0x80+0x40+6);
}
if(s1num==3)
{
shi--;if(shi==-1)
shi=23;write_sfm(9,shi);write_com(0x80+0x40+9);
}
}
}
}
}
void riqi_xq()
{
switch(xq)
{
case 1:write_com(0x80+12);write_date(0x40+13);write_date(0x40+15);
write_date(0x40+14);write_com(0x80+12);break;
case 2:write_com(0x80+12);write_date(0x50+4);write_date(0x50+5);
write_date(0x40+5);write_com(0x80+12);break;
case 3:write_com(0x80+12);write_date(0x50+7);write_date(0x40+5);
write_date(0x40+4);write_com(0x80+12);break;
case 4:write_com(0x80+12);write_date(0x50+4);write_date(0x40+8);
write_date(0x50+5);write_com(0x80+12);break;
case 5:write_com(0x80+12);write_date(0x40+6);write_date(0x50+2);
write_date(0x40+9);write_com(0x80+12);break;
case 6:write_com(0x80+12);write_date(0x50+3);write_date(0x40+1);
write_date(0x50+2);write_com(0x80+12);break;
case 7:write_com(0x80+12);write_date(0x50+3);write_date(0x50+5);
write_date(0x40+14);write_com(0x80+12);break;
}
}
void keys_riqi()
{
if(s4==0)
{delay(10);if(s4==0)
{while(!s4);s4num++;if(s4num==1)
{TR0=0;write_com(0x80+0x0c);write_com(0x0f);
}
if(s4num==2)
{
write_com(0x80+9);
}
if(s4num==3)
{
write_com(0x80+6);
}
if(s4num==4)
{
write_com(0x80+3);
}
if(s4num==5)
{
write_com(0x80+1);
}
if(s4num==6)
{
s4num=0;TR0=1;write_com(0x0c);
}
}
}
if(s4num!=0)
{
if(s2==0)
{
delay(5);if(s2==0)
{
while(!s2);if(s4num==1)
{
xq++;if(xq==8)
xq=1;riqi_xq();
}
if(s4num==2)
{
ri++;if(ri==32)
ri=1;write_riqi(9,ri);write_com(0x80+9);
}
if(s4num==3)
{
yue++;if(yue==13)yue=1;write_riqi(6,yue);write_com(0x80+6);
}
if(s4num==4)
{
nian++;if(nian==100)
nian=0;write_riqi(3,nian);write_com(0x80+3);
}
if(s4num==5)
{
shiji++;if(shiji==100)
shiji=0;write_riqi(1,shiji);write_com(0x80+1);
}
}
}
if(s3==0)
{
delay(5);if(s3==0)
{
while(!s3);//s4num++;if(s4num==1)
{
xq--;if(xq==0)
xq=7;riqi_xq();
}
if(s4num==2)
{
ri--;if(ri==0)
ri=31;
write_riqi(9,ri);write_com(0x80+9);
}
if(s4num==3)
{
yue--;if(yue==0)
yue=12;write_riqi(6,yue);write_com(0x80+6);
}
if(s4num==4)
{
nian--;if(nian==0)
nian=99;write_riqi(3,nian);write_com(0x80+3);
}
if(s4num==5)
{shiji--;if(shiji==0)
shiji=99;write_riqi(1,shiji);write_com(0x80+1);
}
}
}
}
}
void main()
{
init();
while(1)
{
keys_riqi();keyscan();if(tt==20)
{
tt=0;miao++;if(miao==60)
{miao=0;fen++;if(fen==60)
{fen=0;shi++;if(shi==24)
{shi=0;ri++;xq++;if(ri==32)
{ri=1;yue++;if(yue==13)
{yue=1;nian++;if(nian==100)
{nian=0;shiji++;if(shiji==100)
{shiji=0;
}
write_riqi(1,shiji);
}
write_riqi(3,nian);
}
write_riqi(6,yue);
}
riqi_xq();write_riqi(9,ri);
}
write_sfm(9,shi);
}
write_sfm(6,fen);
}
write_sfm(3,miao);
}
}
}
void time0() interrupt 1
{
TH0=(65536-50000)/256;TL0=(65536-50000)%256;tt++;
}
全部0条评论
快来发表一下你的评论吧 !