多语言展示
当前在线:835今日阅读:6今日分享:31

如何简单用单片机设计数字时钟

单片机技术随着时代的进步与科技的发展,应用日渐成熟。它作为计算机技术中的一个分支,在电子产品领域的应用广泛,丰富了电子产品的功能,也为智能化电子设备的开发和应用提供了新的出路,实现了智能化电子设备的创新与发展。       数字钟是一种用数字电路技术实现时、分、秒计时的装置,在现实生活中,各种数字钟已得到非常广泛的使用。数字钟的设计方法有许多种,例如可用中小规模集成电路组成数字钟,也可以利用好单片机来实现数字钟等。其中,用单片机实现的电子钟具有结构简单,并便于功能的扩展,但需要涉及到汇编以及C语言编写程序,对设计者有较高的要求。下面就简单介绍一下如何基于单片机实现数字电路的设计。
工具/原料
1

LenovoDESKTOP-L3NO47R

2

Windows20H2

3

Kelic5.0

4

Proteus 8.0

方法/步骤
1

撰写硬件设计方案,利用单片机AT89C51为核心设计的数字时钟是可以正常显示年、月、日、时、分、秒、星期并兼具有实现计时、校时等功能。它的构成模块主要由显示模块,输入模块,控制器模块三部分。其中控制模块的设计思路是采用STC89C52RC单片机STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。共有3个16位的定时/计数器,用户应用程序空间为8K字节,片上集成512字节RAM。       计时模块的设计思路是采用时钟芯片DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0V~5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。       显示模块的设计思路是采用LCD1602LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。不同厂家生产的LCD1602芯片可能有所不同,但使用方法都是一样的。为了降低成本,绝大多数制造商都直接将裸片做到板子上。

2

利用Proteus绘制硬件原理图。

3

利用Keilc编写软件程序主程序部分展示#include#include'lcd.h'#include'ds1302.h' sbit K1=P2^0;sbit K2=P2^1;sbit K3=P2^2;sbit K4=P2^3; void Int0Configuration();void LcdDisplay();unsigned char SetState,SetPlace; void Delay10ms(void);   //误差 0usvoid Timer0Init();void key_proy();void LcdDisplay();/******************************************************************************** 函数名         : main* 函数功能    : 主函数* 输入           : 无* 输出          : 无*******************************************************************************/ void main(){ LcdInit(); Ds1302Init(); Timer0Init();  //定时器0初始化 while(1) { if(SetState==0) { Ds1302ReadTime();             //读取DS1302寄存器中值 } else {   key_proy();                   //读取DS1302寄存器中值 } LcdDisplay();                  //显示LCD函数 } } void key_proy(){     unsigned char i; if(K1==0) //检测按键K1是否按下 { Delay10ms(); //消除抖动 if(K1==0) { SetPlace++;              // if(SetPlace>=7) SetPlace=0; }  while((i<50)&&(K1==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } if(K2==0) //检测按键K2是否按下 { Delay10ms(); //消除抖动 if(K2==0) { TIME[SetPlace]++; if((TIME[SetPlace]&0x0f)>9) //换成BCD码。 { TIME[SetPlace]=TIME[SetPlace]+6; } if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //分秒只能到59 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小时只能到23 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x7)&&(SetPlace==5)) //周只能到7 { TIME[SetPlace]=1; }   } while((i<50)&&(K2==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } if(K3==0) //检测按键K3是否按下 { Delay10ms(); //消除抖动 if(K3==0) { TIME[SetPlace]--; if((TIME[SetPlace]&0x0f)>9) //换成BCD码。 { TIME[SetPlace]=TIME[SetPlace]+6; } if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //分秒只能到59 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小时只能到23 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x7)&&(SetPlace==5)) //周只能到7 { TIME[SetPlace]=1; }   } while((i<50)&&(K3==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; }      if(K4==0) //检测按键K4是否按下 {       Delay10ms(); //消除抖动 if(K4==0) {   SetState=~SetState;   SetPlace=0;       Ds1302Init(); } while((i<50)&&(K4==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } }/******************************************************************************** 函 数 名         : Timer0Init* 函数功能    : 定时器0初始化* 输    入         : 无* 输    出         : 无*******************************************************************************/void Timer0Init(){ TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。  TH0=0XFC; //给定时器赋初值,定时1ms TL0=0X18; ET0=1;//打开定时器0中断允许 EA=1;//打开总中断 TR0=1;//打开定时器 }  /******************************************************************************** 函数名         : LcdDisplay()* 函数功能    : 显示函数* 输入           : 无* 输出          : 无*******************************************************************************/ void LcdDisplay(){ LcdWriteCom(0x80+0X40); LcdWriteData('0'+TIME[2]/16); //时 LcdWriteData('0'+(TIME[2]&0x0f));   LcdWriteData('-'); LcdWriteData('0'+TIME[1]/16); //分 LcdWriteData('0'+(TIME[1]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[0]/16); //秒 LcdWriteData('0'+(TIME[0]&0x0f));  LcdWriteCom(0x80); LcdWriteData('2'); LcdWriteData('0'); LcdWriteData('0'+TIME[6]/16); //年 LcdWriteData('0'+(TIME[6]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[4]/16); //月 LcdWriteData('0'+(TIME[4]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[3]/16); //日 LcdWriteData('0'+(TIME[3]&0x0f)); LcdWriteCom(0x8D); LcdWriteData('0'+(TIME[5]&0x07)); //星期  }   /******************************************************************************** 函数名         : Delay10ms* 函数功能    : 延时函数,延时10ms* 输入           : 无* 输出          : 无*******************************************************************************/void Delay10ms(void)   //误差 0us{    unsigned char a,b,c;    for(c=1;c>0;c--)        for(b=38;b>0;b--)            for(a=130;a>0;a--);} /******************************************************************************** 函 数 名         : void Timer0() interrupt 1* 函数功能    : 定时器0中断函数* 输    入         : 无* 输    出         : 无*******************************************************************************/void Timer0() interrupt 1{ static unsigned int count; TH0=0XFC; //给定时器赋初值,定时1ms TL0=0X18; count++; if(count==10) { count=0;   key_proy();  } }

注意事项

keilc文件一定要保留成Hex文件方可运行、

推荐信息