历史上的今天
返回首页

历史上的今天

今天是:2026年01月11日(星期日)

2023年01月11日 | 基于51单片机的实时时钟设计

2023-01-11 来源:zhihu

功能:

通过8位数码管实现实时时钟,可以设置时间,切换显示模式,显示年月日,时分秒信息;可通过按键修改信息,增加、减少、确定、取消、上一个、下一个、切换模式、设置等功能。

时分秒


年月日:


部分程序:


#include

#include "MAX7221.h"

#include "DS1302.h"


void InitTimer0(void); //定时器T0初始化函数

void Disp(void); //时间显示函数

void SSetTime(unsigned char n,unsigned char m,unsigned char *readvalue,unsigned char *Cflag); //用户设置时间函数

void Delay(unsigned char time); //延时函数

void SDisp(unsigned char n); //设置时间,数码管闪烁函数


sbit Next=P1^0; //“下一个”按钮

sbit Pre=P1^1; //“上一个”按钮

sbit ADD=P1^2; //“增加”按钮

sbit SUB=P1^3; //“减少”按钮

sbit SET=P1^4; //“确定”按钮

sbit Cancel=P1^5; //“取消”按钮

sbit LED=P2^6; //设置指示灯

SYSTEMTIME CurrentTime; //时间日期类型

signed char DispBuf[16]; //存放时间日期的个位与十位

unsigned char DISPCODE[]={0,1,2,3,4,5,6,7,8,9,0x0A,0x0F}; //数码管显示数组,0x0A数码管显示“-”,0x0F数码管不显示

unsigned int count=1200; //用于设定时间/日期在数码管上的显示时间

unsigned char DisFlag=0; //显示标志,0位时间显示,1位日期显示

unsigned char SetFlag=0; //设置标志


void main(void)

{

InitTimer0(); //定时器初始化

Init_Max7221(0xFF,0x0A,0x07,0x01);//MAX7221初始化

Init_DS1302(); //DS1302初始化;注:1 Warning,由于在中断0中也调用了SetTime()函数,所以有一个警告,可忽略警告;如果你将其注释掉,会出现新的警告,因为你在DS1302中写了Init_DS1302()函数,而你没有调用;标准是一定要调用Init_DS1302()函数的

IT0=1; //设置中断INT0

EX0=1;

IT1=1; //设置中断INT1

EX1=1;

EA=1;

LED=0; //设置指示灯为灭的状态

while(1)

{

Disp(); //显示时间/日期

Delay(10);

}

return;

}


//时间/日期显示函数

void Disp(void)

{


GetTime(&CurrentTime); //获取时间/日期

if(DisFlag==0) //判断是不是显示时间

{

DispBuf[7]=(CurrentTime.Second)%10; //秒的个位

DispBuf[6]=(CurrentTime.Second)/10; //秒的十位

DispBuf[5]=10; //“-”

DispBuf[4]=(CurrentTime.Minute)%10; //分的个位

DispBuf[3]=(CurrentTime.Minute)/10; //分的十位

DispBuf[2]=10; //“-”

DispBuf[1]=(CurrentTime.Hour)%10; //时的个位

DispBuf[0]=(CurrentTime.Hour)/10; //时的十位

}

else if(DisFlag==1)

{

DispBuf[7]=(CurrentTime.Day)%10; //日的个位

DispBuf[6]=(CurrentTime.Day)/10; //日的十位

DispBuf[5]=10; //“-”

DispBuf[4]=(CurrentTime.Month)%10; //月的个位

DispBuf[3]=(CurrentTime.Month)/10; //月的十位

DispBuf[2]=10; //“-”

DispBuf[1]=(CurrentTime.Year)%10; //年的个位

DispBuf[0]=(CurrentTime.Year)/10; //年的十位

}


Wr_Max7221(0x08,DISPCODE[DispBuf[7]]); //显示秒的个位或日的个位

Wr_Max7221(0x07,DISPCODE[DispBuf[6]]); //显示秒的十位或日的十位

Wr_Max7221(0x06,DISPCODE[DispBuf[5]]); //显示“-”

Wr_Max7221(0x05,DISPCODE[DispBuf[4]]); //显示分的个位或月的个位

Wr_Max7221(0x04,DISPCODE[DispBuf[3]]); //显示分的十位或月的十位

Wr_Max7221(0x03,DISPCODE[DispBuf[2]]); //显示“-”

Wr_Max7221(0x02,DISPCODE[DispBuf[1]]); //显示时的个位或年的个位

Wr_Max7221(0x01,DISPCODE[DispBuf[0]]); //显示时的十位或年的十位

}


//T0定时器初始化子程序

void InitTimer0(void)

{

TMOD=0x01; //工作方式1

TH0=(65536-50000)/256; //定时时间为0.5ms

TL0=(65536-50000)%256;

EA=1; //开总中断

ET0=1; //允许定时器T0中断

TR0=1; //打开定时器T0

}


//T0定时器服务子程序

void Timer0(void) interrupt 1

{

TR0=0; //关定时器T0

TH0=(65536-50000)/256; //重载初值

TL0=(65536-50000)%256;

count--;

if(count==0) //count*0.5ms定时到

{

if(DisFlag==0) //如果上一个是显示时间

{

DisFlag=1; //改为显示日期

count=100; //显示5s

}

else if(DisFlag==1)

{

count=1200; //显示60s

DisFlag=0; //改为显示时间

}

}

TR0=1; //打开定时器T0

}



SetFlag=0; //清除设置标志

break; //退出设置模式

}

if(Next==0) n=n-1; //“下一个”按钮按下时,某数据设置位标志减1

if(n<=0) n=6; //若到达0时,回到6设置

if(Pre==0) n=n+1; //“上一个”按钮按下时,某数据设置位标志加1

if(n>=7) n=1; //若到达0时,回到6设置

if(ADD==0) m=1; //“增加”按钮按下时,设置增加标志

if(SUB==0) m=2; //“减少”按钮按下时,设置减少标志

if((Next==0)||(ADD==0)||(SUB==0)) //判断是否有“下一个”按钮或“增加”按钮或“减少”按钮按下

{

Delay(50); //延时(给一定的释放按钮时间)

SSetTime(n,m,readvalue,&Cflag); //进入相关的设置

}

SDisp(n); //显示

m=0; //清除“增加”或“减少”标志

}

LED=0; //设置完毕,关设置指示灯

count=1200; //设置完毕后,“时间”显示的60s

DisFlag=0; //显示“时间”

EA=1; //开总中断

}


//时间日期变化子函数

void SSetTime(unsigned char n,unsigned char m,signed char *readvalue,signed char* Cflag)

{

if(m==1) //设置值增加

{

if(n==6) //年增加

{

*Cflag|=0x01; //年值变化标志

readvalue[5]=readvalue[5]+1; //年值加1

if(readvalue[5]>=100) readvalue[5]=00; //判断是否大于99,若是,将其设置为0

DispBuf[0]=readvalue[5]/10; //保存年的十位

DispBuf[1]=readvalue[5]%10; //保存年的个位

}


推荐阅读

史海拾趣

Collins Electronics Corp公司的发展小趣事

在电子行业竞争日益激烈的情况下,Collins Electronics Corp面临着巨大的挑战。为了保持竞争优势,公司加大了研发投入,不断优化产品性能。同时,他们还加强了对市场趋势的研究,以便及时调整产品策略。在一次行业技术革新中,公司凭借敏锐的市场洞察力和强大的研发能力,成功推出了一款符合市场需求的新产品,赢得了市场份额。

Goldentech Discrete Semiconductor Inc公司的发展小趣事

在快速发展的同时,Goldentech始终关注环境保护和社会责任。公司积极推行绿色制造理念,采用环保材料和节能技术,减少生产过程中的碳排放和资源消耗。此外,Goldentech还投入大量资金研发可回收和可降解的半导体产品,旨在为全球电子行业的可持续发展贡献力量。这一环保理念不仅提升了公司的社会形象,还吸引了更多注重可持续发展的客户和合作伙伴。

泰科天润(GPT)公司的发展小趣事

随着物联网、可穿戴设备等新兴领域的兴起,Goldentech敏锐地捕捉到了市场的新机遇。公司迅速调整战略方向,加大在微型化、低功耗半导体器件的研发投入。通过引入先进的制造工艺和封装技术,Goldentech成功推出了一系列适用于物联网和可穿戴设备的高性能离散半导体产品。这些产品凭借出色的性能和稳定性,在市场中获得了广泛认可,为公司的持续发展注入了新的动力。

CITIZEN公司的发展小趣事

随着技术的不断进步和产品的不断创新,西铁城公司开始积极拓展全球市场。公司的产品以其高品质、精确度和创新技术而闻名,逐渐赢得了全球消费者的青睐。同时,公司也积极参与国际性的钟表展会和活动,通过展示最新产品和技术成果,进一步提升品牌知名度和影响力。这一系列的举措使得西铁城在全球市场上的地位日益稳固。

AdaptivEnergy公司的发展小趣事

在20世纪中叶,西铁城公司迎来了一次重要的技术突破。1956年,公司成功研制出防震手表,并通过了空中坠表实验,这一创新轰动了整个行业。防震手表的推出不仅提升了西铁城产品的品质,也进一步巩固了其在全球腕表市场中的地位。这一技术的成功应用,也显示了西铁城在精密加工和测量技术方面的实力。

ANOVA公司的发展小趣事

ANOVA深知,成功的关键在于与合作伙伴的紧密合作。因此,公司始终与客户保持紧密的合作关系,共同开发特定的解决方案,协助制定部署策略。ANOVA的服务团队以客户的需求为导向,以十几种语言提供个性化的服务,确保每一位客户都能得到满意的解决方案。此外,ANOVA还积极与商业伙伴合作,共同开拓市场,实现共赢。

问答坊 | AI 解惑

F题有做出来的么?(期待大牛的xyt)

本帖最后由 paulhyde 于 2014-9-15 09:33 编辑 RT,不包括功放也好 崩溃了有点。。。 [ 本帖最后由 plich 于 2009-9-5 10:53 编辑 ]  …

查看全部问答>

运放电压跟随器到底应怎样接?

看到一些书上介绍运放做成电压跟随器,将输出接到反相,还有的接到同相,有关原理介绍都是较少一带而过,请教诸位到底是哪一种接法呢?…

查看全部问答>

坛子里有没有朋友用过xilinx xupv2p开发板的??想请教一下!

如题,谢谢!希望我能从用过的朋友那里咨询一下关于这块开发板的问题。谢谢了!…

查看全部问答>

2440串口移植的问题

2440 5.0 串口移植到 6.0。 加载串口驱动后,启动出现INFO: CReg2440Uart::CReg2440Uart using processor frequency reported by the OAL (0). 然后系统就死了。 也就是这一段 CReg2440Uart::CReg2440Uart()中     if (!KernelIoC ...…

查看全部问答>

如何实现嵌入式系统的网上在线更新

最近要做一个基于Context-M3的无操作系统的项目,其中有一部分功能是要实现软件的在线更新。 我第一次做这方面的功能,没有什么经验,特来请教。 现在通信协议方面已经没有问题了,现在所面对的问题是: 如何将2进制文件写到Flash相应的地址上。 ...…

查看全部问答>

程序集“System.Web.Services"出错!

在做PDA应用程序时碰到: D:\\WebService2\\WebService2\\TestWebService\\Form1.cs(26,13): 错误 CS0012: 类型“System.Web.Services.WebService”在未被引用的程序集中定义。必须添加对程序集“System.Web.Services, Version=2.0.0.0, Culture=n ...…

查看全部问答>

请教麻宝华老师Snooper

我用麻宝华老师的Snooper 是否要用你们专用的读卡器呢?我有SIM卡读卡器 但软件连不上 我想查看 执行 STK菜单所发出去的短信内容 要怎么操作呢 谢谢 比如STK彩单 “移动梦网”下的“天气预报” 就会发送出去一条短信 我怎么能知道这条短信的 ...…

查看全部问答>

EVC 对话框 焦点问题

BOOL CScanDlg::OnInitDialog() {CDialog::OnInitDialog();         GetDlgItem(IDC_EDIT1)->SetFocus(); } 请问代码有问题吗? 为什么 edit1 就是在运行后得不到焦点呢? 请问有什么办法才能使他得到焦点。…

查看全部问答>

如何查看PIC烧进去的程序的大小啊?

请问如何查看少进去的程序的大小,和运行时RAM的使用情况…

查看全部问答>

百度HI 单片机&Arm群 招兵

百度HI 单片机&Arm群  招兵 HI  群号:1083326 要来的速度…

查看全部问答>