功能描述
1、采用51/52单片机作为主控芯片;
2、采用LGM12641显示年月日星期时分秒;
3、可通过按键修改时间值;
仿真设计
采用Proteus作为仿真设计工具。Proteus是一款著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。
单片机管脚说明:
P0端口(P0.0-P0.7):P0口为一个8位漏极开路双向I/O口,每个引脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1端口(P1.0-P1.7):P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高电平,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2端口(P2.0-P2.7):P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口,用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3端口(P3.0-P3.7):P3口管脚是一个带有内部上拉电阻的8位的双向I/O端口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入端时,由于外部下拉为低电平,P3口将输出电流(ILL)。P3口同时为闪烁编程和编程校验接收一些控制信号。
VCC(40):供电电压,其工作电压为5V。
GND(20):接地。
RST(9):复位输入。在振荡器运行时,有两个机器周期(24个振荡周期)以上的高电平出现在此引脚时,将使单片机复位,只要这个引脚保持高电平,51芯片便循环复位。复位后P3.0-P3.7口均置1,引脚表现为高电平,程序计数器和特殊功能寄存器SFR全部清零。当复位脚由高电平变为低电平时,芯片为ROM的00H处开始运行程序。复位操作不会对内部RAM有所影响。
ALE/PROG (30):当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地低位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如果想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,则置位无效。
PSEN(29):外部程序存储器的选通信号。在由外部程序存储器取指令期间,每个机器周期两次PSEN有效。但在访问外部数据存储器时,这两次有效的PSEN信号将不出现。
XTAL1(19):来自反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2(18):来自反向振荡器的输出。
EA/VPP(31):当EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,EA将内部锁定为RESET;当EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V的编程电源(VPP)。
主程序设计
void main(void)
{ char swh = 0;
char year= 20;
char week= 0x04;
char month= 0x20;
char day= 0x04;
char hour= 0x20;
char div= 0x04;
char second= 0x20;
char n_hour = 1;
char n_div = 30;
char n_falg=0;
unsigned char month_x= 0,day_x=0,hour_x = 0 ,div_x = 0,year_x = 0;
char djs_flag = 0;
char djs_stop_flag=1;
char djs = 60;
int time=0;
InitLCD(); //初始化LCD12864
//Ds1302Init();//Ds1302初始化,并且附上设定的默认时间
Ds1302ReadTime();
Ds1302WriteTime();
//set_DS1302_time(0x20,0x04,0x20, 0x04,0x20,0x04,0x20);
//InitTimer0();
while(1)
{
//ShowNumber(6,32,9);
// wendu();
//Ds1302ReadTime();
//digplay();
if ( KEY2 == 0 )
{
swh ++;
while(!KEY2);
}
if(swh >8 ) swh = 0;
if( swh == 0 )
{
ShowNumber(6,20,15);
ShowNumber(6,32,11); ShowNumber(6,40,11);
Ds1302ReadTime();
digplay();
//========判断 闹钟
if((TIME[2]>>4&0x03) == (n_hour/10) && (TIME[2]&0x0f) == n_hour%10 && (TIME[1]>>4&0x07) == n_div/10 && (TIME[1]&0x0f) == n_div%10)
{
{
n_falg ++;
if(n_falg%2==0 )
{
ShowNumber(6,75,n_hour/10); //时 十位
ShowNumber(6,83,n_hour%10);//时 个位
ShowNumber(6,91,10);
ShowNumber(6,99,n_div/10);//分 十位
ShowNumber(6,107,n_div%10);//分 个
}
if(n_falg%2==1 )
{
ShowNumber(6,73,n_hour/10); //时 十位
ShowNumber(6,81,n_hour%10);//时 个位
ShowNumber(6,89,10);
ShowNumber(6,97,n_div/10);//分 十位
ShowNumber(6,105,n_div%10);//分 个
}
}
}
}
if(swh == 1 )//设置年
{
ShowChina(6,32,9);
if(KEY3 == 0)
{
year ++;
while(!KEY3);
}
if(KEY4 == 0)
{
year --;
while(!KEY4);
}
year = year >80?80:year;
year = year <1?1:year;
year_x =((year/10)<<4)|(year%10) ;
// set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
digplay();
}
if(swh == 2 )//设置星期
{
ShowChina(6,32,10);
if(KEY3 == 0)
{
week ++;
while(!KEY3);
}
if(KEY4 == 0)
{
week --;
while(!KEY4);
}
week= week > 7 ?7:week;
week= week < 1 ?1:week;
// set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
digplay();
}
if(swh == 3 )//设置月
{
ShowChina(6,32,11);
if(KEY3 == 0)
{
month ++;
while(!KEY3);
}
if(KEY4 == 0)
{
month --;
while(!KEY4);
}
month = month >12?12:month;
month = month <1?1:month;
month_x=((month/10)<<4)|(month%10) ;
// set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
digplay();
}
if(swh == 4 )//设置日
{
ShowChina(6,32,12);
if(KEY3 == 0)
{
day ++;
while(!KEY3);
}
if(KEY4 == 0)
{
day --;
while(!KEY4);
}
day = day >31?31:day;
day = day <1?1:day;
day_x=((day/10)<<4)|(day%10) ;
// set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
digplay();
}
if(swh == 5 )//设置小时
{
ShowChina(6,32,13);
if(KEY3 == 0)
{
hour ++;
while(!KEY3);
}
if(KEY4 == 0)
{
hour --;
while(!KEY4);
}
hour = hour >24?24:hour;
hour = hour <1?1:hour;
hour_x=((hour/10)<<4)|(hour%10) ;
// set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
digplay();
}
if(swh == 6 )//设置分
{
ShowChina(6,32,14);
if(KEY3 == 0)
{
div ++ ;
while(!KEY3);
}
if(KEY4 == 0)
{
div --;
while(!KEY4);
}
div = div >60?60:div;
div = div <1?1:div;
div_x=((div/10)<<4)|(div%10) ;
// set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
digplay();
}
if(swh == 7 ) //设置 闹钟 时
{
ShowChina(6,32,13); ShowNumber(6,20,11);
if(KEY3 == 0)
{
n_hour ++;
while(!KEY3);
}
if(KEY4 == 0)
{
n_hour --;
while(!KEY4);
}
n_hour = n_hour >24?24:n_hour;
n_hour = n_hour <1?1:n_hour;
ShowNumber(6,75,n_hour/10); //时 十位
ShowNumber(6,83,n_hour%10);//时 个位
ShowNumber(6,91,10);
ShowNumber(6,99,n_div/10);//分 十位
ShowNumber(6,107,n_div%10);//分 个
}
if(swh == 8 ) //设置 闹钟 分
{
ShowChina(6,32,14); ShowNumber(6,20,11);
if(KEY3 == 0)
{
n_div ++;
while(!KEY3);
}
if(KEY4 == 0)
{
n_div --;
while(!KEY4);
}
n_div = n_div >60?60:n_div;
n_div = n_div <1?1:n_div;
ShowNumber(6,75,n_hour/10); //时 十位
ShowNumber(6,83,n_hour%10);//时 个位
ShowNumber(6,91,10);
ShowNumber(6,99,n_div/10);//分 十位
ShowNumber(6,107,n_div%10);//分 个
}
if(KEY6 == 0 )
{
set_DS1302_time(year_x,week,month_x, day_x,hour_x,div_x,0x00);
while(!KEY6);
}
}
}
源文件获取
关注公众号-电子开发圈,首页发送 “时钟” 获取;