嵌入式课程设计数字钟程序代码
- 格式:pdf
- 大小:190.40 KB
- 文档页数:18
数电实验数字钟的设计代码数字钟是一种常见的电子设备,用于显示当前时间。
它是基于数字电路技术设计的,可以实时地显示时、分、秒的数字。
在这篇文章中,我将为大家介绍数字钟的设计代码,以及它的原理和实现过程。
在开始设计数字钟之前,我们需要准备一些基础材料和器件。
首先,我们需要一块数字时钟显示屏,它可以显示四位数的时、分、秒。
其次,我们需要几个集成电路芯片,包括时钟发生器、计数器、解码器等。
另外,还需要一些细小的电子元件,如电阻、电容、晶体管等。
准备好这些材料后,我们就可以开始设计数字钟的电路了。
首先,我们先来了解一下数字钟的原理。
数字钟的核心部分就是计数器。
计数器可以根据时钟发生器提供的脉冲信号进行计数,当计数到一定值时,就会触发一次计数事件。
我们可以将计数事件与显示屏相连,通过解码器将计数的结果转化成数字信号,进而在显示屏上以数码形式显示出来。
通过不断循环计数,我们就可以实现数字钟的功能了。
接下来,我们将详细介绍数字钟的设计代码。
首先,我们需要定义一些常量和变量。
常量包括时钟频率、计数器的初始值等,而变量则用来保存时、分、秒的数值。
接着,我们需要编写时钟发生器的代码,它可以产生一个固定频率的脉冲信号。
然后,我们需要编写计数器的代码,它会根据时钟发生器的脉冲信号进行计数,并触发计数事件。
最后,我们需要编写解码器的代码,它可以将计数的结果转化成数字信号,供显示屏显示。
在编写完代码后,我们需要将它们烧录到集成电路芯片中。
然后,将电路连接起来,将显示屏与解码器相连。
确保所有电子元件的接触良好,然后通电测试。
如果一切正常,数字钟就会开始工作,并在显示屏上显示出当前的时、分、秒。
在这个实验中,我们学习到了数字电路设计的基本原理和实现过程。
数字钟作为一个常见的例子,展示了数字电路的实际应用。
通过这个实验,我们不仅提高了自己的动手实践能力,还加深了对数字电路的理解。
相信通过这次实验,我们对数字钟的设计代码有了更深入的了解,也能够在今后的实践中运用这些知识。
嵌入式课程设计报告题目:基于DS1302数字钟姓名:学号:班级:电子101专业:电子信息工程指导老师:提交时间: 2013-12-13组员:目录摘要................................................. - 1 -1.引言............................................... - 3 -2.硬件电路设计:..................................... - 4 - 2.1 DS1302 ........................................ - 4 - 2. 2 AT89C52 ...................................... - 6 - 2. 3 LCD1602 ...................................... - 7 -2. 4 设计方案 ..................................... - 8 -3.软件程序设计....................................... - 9 - 3.1主程序.......................................... - 9 - 3.2 LCD1602程序:................................. - 10 -3.3 DS1302应用程序:.............................. - 13 -4.课设的心得体会.................................... - 17 - 参考文献............................................ - 20 -摘要本设计选取串行接口时钟芯片 DS1302 与单片机同步通信构成数字时钟电路并用LCD1602显示。
电子时钟工具的程序设计及代码示例为满足现代生活的需求,电子时钟成为人们生活中的常见工具。
除了具备实时显示时间的功能外,电子时钟还可以根据用户需求进行各种定制,如显示日期、倒计时、闹钟等功能。
本文将探讨电子时钟的程序设计方法,并提供一个简单的代码示例。
一、程序设计方法在进行电子时钟的程序设计前,我们需要确定以下几个关键因素:1. 使用的编程语言:根据实际情况选择合适的编程语言,如C++、Java、Python等。
2. GUI框架:确定使用什么图形界面框架,如Qt、Tkinter等。
3. 实时更新:确定时间的实时更新方式,可以利用计时器、循环等方式进行时间更新。
4. 用户交互:考虑用户是否需要与电子时钟进行交互,如设置闹钟、选择日期等。
二、代码示例以下是一个基于Python和Tkinter的电子时钟代码示例,代码注释中详细说明了每个函数的功能和实现方法:```pythonimport tkinter as tkfrom datetime import datetimedef update_time():# 获取当前时间current_time = datetime.now().strftime("%H:%M:%S")# 更新时间标签time_label.config(text=current_time)# 每隔1秒更新一次时间time_label.after(1000, update_time)# 创建窗口window = ()window.title("电子时钟")# 创建时间标签time_label = bel(window, font=("Arial", 100), bg="white") time_label.pack(pady=50)# 更新时间update_time()# 运行窗口主循环window.mainloop()```以上代码创建了一个简单的窗口,使用标签实时显示当前时间。
/*电子时钟源代码*/#include<graphics.h>#include<stdio.h>#include<math.h>#include<dos.h>#define PI 3.1415926 /*定义常量*/#define UP 0x4800 /*上移↑键:修改时间*/#define DOWN 0x5000 /*下移↓键:修改时间*/#define ESC 0x11b /*ESC键:退出系统*/#define TAB 0xf09 /*TAB键:移动光标*//*函数声明*/int keyhandle(int,int); /*键盘按键判断,并调用相关函数处理*/int timeupchange(int); /*处理上移按键*/int timedownchange(int); /*处理下移按键*/int digithour(double); /*将double型的小时数转换成int型*/int digitmin(double); /*将double型的分钟数转换成int型*/int digitsec(double); /*将double型的秒钟数转换成int型*/void digitclock(int,int,int ); /*在指定位置显示时钟或分钟或秒钟数*/void drawcursor(int); /*绘制一个光标*/ void clearcursor(int);/*消除前一个光标*/void clockhandle(); /*时钟处理*/ double h,m,s; /*全局变量:小时,分,秒*/double x,x1,x2,y,y1,y2; /*全局变量:坐标值*/struct time t[1];/*定义一个time结构类型的数组*/main(){int driver, mode=0,i,j;driver=DETECT; /*自动检测显示设备*/initgraph(&driver, &mode, "");/*初始化图形系统*/setlinestyle(0,0,3); /*设置当前画线宽度和类型:设置三点宽实线*/ setbkcolor(0);/*用调色板设置当前背景颜色*/setcolor(9); /*设置当前画线颜色*/ line(82,430,558,430);line(70,62,70,418);line(82,50,558,50);line(570,62,570,418);line(70,62,570,62);line(76,56,297,56);line(340,56,564,56); /*画主体框架的边直线*//*arc(int x, int y, int stangle, int endangle, int radius)*/arc(82,62,90,180,12);arc(558,62,0,90,12);setlinestyle(0,0,3);arc(82,418,180,279,12);setlinestyle(0,0,3);arc(558,418,270,360,12); /*画主体框架的边角弧线*/setcolor(15);outtextxy(300,53,"CLOCK"); /*显示标题*/setcolor(7);rectangle(342,72,560,360); /*画一个矩形,作为时钟的框架*/setwritemode(0); /*规定画线的方式。
数字时钟程序/**************************************************程序名称:数字时钟程序全局变量:tt,shi,fen,miao等参数说明:无返回说明:无版本:1.0功能说明:通过数码实现时钟的显示,通过键盘实现时间的调整其中k1是开始调整,k2是增加,k3是减小,k5是实现定时屏幕的切换,k4是定时设置的开始。
带闹铃功能。
作者邮箱:****************(欢迎交流)**************************************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit beep=P2^3;sbit dula=P2^6;sbit wela=P2^7;sbit k1=P3^0;sbit k2=P3^1;sbit k3=P3^2;sbit k4=P3^3;sbit k5=P3^4;sbit rd=P3^7;uchartt,shi_s,shi_g,shi1_s,shi1_g,fen1_s,fen1_g,miao1_s,miao1_g,fen_s,fen_g,miao_s,miao_g,k1num,k 4num,flag;char shi,fen,miao=20,shi1,fen1,miao1;/*********************************函数名称:延时程序设计全局变量:无参数说明:z传递给内部,是实现75*z条空指令延迟返回说明:无版本:1.0功能说明:约Z*75us延时程序设计作者邮箱:****************(欢迎交流)*********************************/void delay(uint z){uchar x;uint y;for(x=z;x>0;x--)for(y=75;y>0;y--);}/********八段数码管编码**********/uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};/*********************************函数名称:初始化函数全局变量:无参数说明:无返回说明:无版本:1.0功能说明:定时器装初值,开总中断,定时中断,并写定时中断函数作者邮箱:****************(欢迎交流)*********************************/void init(){TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;tt++;if(tt==20){tt=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}}}}}/*********************************函数名称:6个数码管显示函数全局变量:shi fen miao 的个十位分离参数说明:将个十位的分离分别传递到各个数码管中并显示返回说明:无版本:1.0功能说明:实现时钟的数码管显示,动态扫描。
数字时钟代码1. 介绍数字时钟是一种常见的显示时间的装置,它通过数字显示屏显示当前的小时和分钟。
本文档将介绍如何编写一个简单的数字时钟代码。
2. 代码实现以下是一个基本的数字时钟代码实现示例:import timewhile True:current_time = time.localtime()hour = str(current_time.tm_hour).zfill(2)minute = str(current_time.tm_min).zfill(2)second = str(current_time.tm_sec).zfill(2)clock_display = f"{hour}:{minute}:{second}"print(clock_display, end="\r")time.sleep(1)代码说明:- `time.localtime()` 函数返回当前时间的结构化对象,包括小时、分钟和秒等信息。
- `str(current_time.tm_hour).zfill(2)` 将小时转换为字符串,并使用 `zfill()` 方法填充到两位数。
- `str(current_time.tm_min).zfill(2)` 和`str(current_time.tm_sec).zfill(2)` 同理处理分钟和秒。
- 使用 f-string 格式化字符串 `clock_display`,将小时、分钟和秒显示为 `` 的形式。
- `print(clock_display, end="\r")` 使用 `\r` 实现覆盖打印,使得时钟在同一行连续显示。
- `time.sleep(1)` 让程序每隔一秒更新一次时间。
请注意,上述代码需要在支持 Python 的环境中运行。
3. 结束语通过以上的代码实现,我们可以编写一个简单的数字时钟。
}#include<reg52。
h 〉 // #include<intrins 。
h 〉uchar num ,count,shi,fen,miao ,s1num ,s2num,year,month,day ,week,flag,flag1,year1,month1, day1,week1,shi1,fen1,miao1,year2,month2,day2,week2,shi2,fen2,miao2,year5,month5, day5,week5,shi5,fen5,miao5,wk ,ashi,afen; // 参数定义 uchar code table []="20 — — "; // uchar code table1[]=" : : 00:00”; /*uchar time_dat[7]={12,1,6,6,12,59,59}; // uchar write_add [7]={0x8c ,0x8a,0x88,0x86,0x84,0x82,0x80}; uchar read_add [7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};*/ void write_com (uchar com); // void write_data(uchar date ); //void write_ds1302(uchar add,uchar dat ); //ds1302void set_rtc (); //ds1302 void time_pros(); //ds1302 void read_rtc (); //ds1302 void alarm (); // void delay(uint z)//{uint x,y ;for (x=z;x>0;x-—) for(y=110;y 〉0;y--);#define uchar unsigned char// #define uint unsigned int // 位定义 sbit rs=P2^5; sbit lcden=P2^7; sbit s1=P2^0; sbit s2=P2^1; sbit s3=P2^3; sbit s4=P2^4; sbit rst=P1^5; sbit io=P1^6; sbit sclk=P1^7; sbit beep=P3^0; // // // // // //ds1302 //宏定义液晶位定义 时间功能切换按键 按键加 按键减 闹钟功能切换键 引脚定义 蜂鸣器 头文件 液晶固定显示年周月日时分秒 液晶写指令函数 液晶写数据函数芯片写指令函数 时间设置函数 进制转换函数 读时间函数 闹钟函数 延时函数}void write_com(uchar com)//1602 液晶写指令 {rs=0; P0=com; delay(5); lcden=1; delay(5); lcden=0;}void write_data(uchar date)//1602 液晶写写数据 {rs=1; P0=date; delay (5); lcden=1; delay(5); lcden=0;//void init() {lcden=0; flag=0; flag1=0;write_com(0x38); write_com (0x0c ); write_com(0x06); write_com (0x01); write_com (0x80); // for(num=0;num<14;num++) {write_data(table[num ]); delay(5); }write_com (0x80+0x40); // for(num=0;num 〈20;num++) {write_data(table1[num]); delay (5);}初始化液晶固定显示,第一行液晶显示第二行void write_sfm(uchar add,uchar date)// 时分秒{uchar shi3,ge; shi3=date/10; ge=date%10;write_com(0x80+0x40+add); write_data(0x30+shi3);write_data(0x30+ge);}void write_nyr(uchar ad,uchar date)// 年月日{uchar shi4,ge2;shi4=date/10;ge2=date%10; write_com(0x80+ad); write_data(0x30+shi4); write_data(0x30+ge2);}void write_week(uchar wk) // 星期按西方星期设置{星期天为第一天write_com(0x80+11);switch(wk){case 1:write_data('S’); delay(5);write_data('U’); delay(5);write_data(’N’); break;case 2: write_data('M’); delay(5);write_data('O’); delay(5);write_data('N’); break;case 3: write_data('T');delay(5); write_data('U'); delay(5); write_data('E'); break;case 4:write_data('W’); delay(5);write_data(’E’); delay(5);write_da ta('D’); break;case 5: write_data('T'); delay(5);write_data(’H’); delay(5);write_data('U’); break;case 6: write_data('F’); delay(5);write_data('R’); delay(5);write_data('T’); break;case 7: write_data('S'); delay(5);write_data(’A'); delay(5);write_data(’T'); break;}}// 按键函数void keyscan(){if(s1==0){delay(5);if(s1==0)write_com(0x0f); s1num++; //flag=1;flag1=1;while(!s1);记录按键次数switch(s1num)// 光标闪烁点定位{case 1:write_com(0x80+0x40+6); // 秒break;case 2:write_com(0x80+0x40+3); // 分break;case 3:write_com(0x80+0x40+0); // 时break;case 4:write_com(0x80+11); // break;case 5:write_com(0x80+8); // break;星期日case 6:write_com(0x80+5);// break;case 7:write_com(0x80+2); //break;case 8:s1num=0;write_com(0x0c);// 间设置set_rtc();flag=0;break;}设置开显示光标不显示关闭时if(s1num!=0) // {按键加减if/加按键函数delay(10); if(s2==0) {while(!s2); switch(s1num) //根据功能键相应次数做出调节{case 1: miao++; // 秒加 if (miao==60) miao=0;write_sfm(6,miao); write_com(0x80+0x40+6); break;case 2: fen++; // 分加 if(fen==60)fen=0; write_sfm (3,fen); write_com (0x80+0x40+3); break ;case 3: shi++; // 时加 if (shi==24)shi=0; write_sfm (0,shi); write_com (0x80+0x40+0); break ;case 4: week++; // if(week==8) week=1; write_week(week ); write_com(0x80+11); break; case 5: day++; // if(day==32) day=1; write_nyr(8,day ); write_com(0x80+8); break;if (month==13)month=1; write_nyr (5,month); write_com (0x80+5);break;case 7: year++; //年加if (year==100) year=0;write_nyr(2,year );write_com(0x80+2);break;}}}if (s3==0) // 减按键函数同上 {星期加日加 case 6: month++;//月加delay(10);if(s3==0){while(!s3);switch(s1num) // 根据功能键相应次数做出调节{case 1: miao—-;if(miao==—1)miao=59;write_sfm(6,miao); write_com(0x80+0x40+6);break;case 2: fen——;if(fen==-1)fen=59;write_sfm(3,fen); write_com(0x80+0x40+3); break;case 3: shi—-;if(shi==—1)shi=23;write_sfm(0,shi); write_com(0x80+0x40+0); break;case 4: week--;if(week==—1) week=7;write_week(week); write_com(0x80+11); break;case 5: day--; if(day==-1) day=31; write_nyr(8,day);write_com(0x80+8); break;case 6: month—-;if(month==—1)month=12;write_nyr(5,month); write_com(0x80+5); break;case 7: year-—;if(year==—1) year=99;write_nyr(2,year); write_com(0x80+2); break;}}}}if(s4==0) // {闹钟按键delay(5);if(s4==0){write_com(0x0f); // s2num++;// flag=1;while(!s4);switch(s2num)//光标闪烁记录按键次数光标闪烁点定位{case 1:write_com(0x80+0x40+13);// break;case 2:write_com(0x80+0x40+10); // 时break;case 3:write_com(0x0c);flag=0; s2num=0;break;}}}//关闭闹钟设置if(s2num!=0) //{if(s2==0) //{delay(10); if(s2==0){ while(!s2);switch(s2num)//闹钟设置闹钟加根据功能键相应次数做出调节{case 1: afen++;if(afen==60)afen=0;write_sfm(13,afen);write_com(0x80+0x40+13);break;case 2: ashi++;if(ashi==24)ashi=0;write_sfm(10,ashi); write_com(0x80+0x40+10); break;}}}if(s3==0) // 闹钟减{delay(10);if(s3==0){while(!s3);switch(s2num) // 根据功能键相应次数做出调节{case 1: afen--;if(afen==—1)afen=59;write_sfm(13,afen);write_com(0x80+0x40+13);break;case 2: ashi--;if(ashi==-1)ashi=23;write_sfm(10,ashi);write_com(0x80+0x40+10); break;}}}}}void wirte_ds1302_byte(uchar dat) //ds1302 字节写{ uchar i;for(i=0;i〈8;i++){sclk=0;io=dat&0x01;dat=dat>>1; sclk=1; }}void write_ds1302(uchar add ,uchar dat) //ds1302 {rst=0;_nop_();// 空操作 sclk=0; _nop_(); rst=1;_nop_(); wirte_ds1302_byte (add ); wirte_ds1302_byte (dat ); rst=0; io=1; sclk=1;}uchar read_ds1302(uchar add) //ds1302{uchar i,value; rst=0;_nop_();// 空操作 sclk=0; _nop_(); rst=1;_nop_(); wirte_ds1302_byte(add ); for (i=0;i<8;i++) { value=value 〉>1; sclk=0; if (io) { value=value |0x80; } sclk=1; } rst=0;_nop_();// 空操作 sclk=0; _nop_();写函数读函数sclk=1;io=1;return value; }void set_rtc(){write_ds1302(0x8e,0x00);year1=year/10; //year=year%10;year=year+year1*16;write_ds1302(0x8c,year);//ds1302// 关写保护转换为十六进制week1=week/10;week=week%10;week=week+week1*16; write_ds1302(0x8a,week);month1=month/10;month=month%10;month=month+month1*16; write_ds1302(0x88,month);day1=day/10;day=day%10;day=day+day1*16; write_ds1302(0x86,day);shi1=shi/10;shi=shi%10;shi=shi+shi1*16; write_ds1302(0x84,shi);fen1=fen/10;fen=fen%10;fen=fen+fen1*16; write_ds1302(0x82,fen);miao1=miao/10;miao=miao%10;miao=miao+miao1*16;write_ds1302(0x80,miao);时间设置write_ds1302(0x8e,0x80); // 开写保护flag1=0;void read_rtc () //{year2=read_ds1302(0x8d); week2=read_ds1302(0x8b );month2=read_ds1302(0x89); day2=read_ds1302(0x87);shi2=read_ds1302(0x85);fen2=read_ds1302(0x83);miao2=read_ds1302(0x81);}void time_pros() // 进制{从 ds1302 中读出的时间转换为十year5=year2/16; year2=year2%16;year2=year2+year5*10; month5=month2/16; month2=month2%16;month2=month2+month5*10; day5=day2/16; day2=day2%16; day2=day2+day5*10; shi5=shi2/16; shi2=shi2%16; shi2=shi2+shi5*10; fen5=fen2/16; fen2=fen2%16; fen2=fen2+fen5*10; miao5=miao2/16;miao2=miao2%16; miao2=miao2+miao5*10;void display(){从 ds1302 中读时间// 显示函数write_sfm(6,miao2); write_com(0x80+0x40+6);write_sfm(3,fen2); write_com(0x80+0x40+3);write_sfm(0,shi2); write_com(0x80+0x40+0);write_week(week2);write_com(0x80+11);write_nyr(8,day2);write_com(0x80+8);write_nyr(5,month2);write_com(0x80+5);write_nyr(2,year2);write_com(0x80+2);if((ashi==shi2)&&(afen==fen2)) {alarm();}}void alarm() // 闹钟{beep=0; delay(1000);beep=1;void mai n()//{in it();//while(1){keysca n();//if(flag==O){keysca n(); read_rtc(); time_PrOS(); display();}■■■・』』u ■〈n “ Ia ・.■,□ ∣22912-07-64 I-C12: 18=03 C0=0^■ W■'h Ui■t∣?K。
单片机技术课程设计数字电子钟学院:班级:姓名:学号:教师:摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。
所以设计一个简易数字电子钟很有必要。
本电子钟采用AT89C52单片机为核心,使用12MHz 晶振与单片机AT89C52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。
该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEY5键,进行相应的操作就可实现校时、定时、复位功能。
具有时间显示、整点报时、校正等功能。
走时准确、显示直观、运行稳定等优点。
具有极高的推广应用价值。
关键词:电子钟 AT89C52 硬件设计软件设计目录NO TABLE OF CONTENTS ENTRIES FOUND.一、数字电子钟设计任务、功能要求说明及方案介绍1.1 设计课题设计任务设计一个具有特定功能的电子钟。
具有时间显示,并有时间设定,时间调整功能。
1.2 设计课题的功能要求说明设计一个具有特定功能的电子钟。
该电子钟上电或按键复位后能自动显示系统提示符“d.1004-22”,进入时钟准备状态;第一次按电子钟启动/调整键,电子钟从12时59分0秒开始运行,进入时钟运行状态;按电子钟S5键,则电子钟进入时钟调整状态,此时可利用各调整键调整时间,调整结束后可按S5键再次进入时钟运行状态。
1.3 设计课的设计总体方案介绍及工作原理说明本电子钟主要由单片机、键盘、显示接口电路和复位电路构成,设计课题的总体方案如图1所示:图1-1总体设计方案图本电子钟的所有的软件、参数均存放在AT89C52的Flash ROM和内部RAM 中,减少了芯片的使用数量简化了整体电路也降低了整机的工作电流。
键盘采用动态扫描方式。
利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据,同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。
嵌入式包括时分秒的数字时钟课程设计答案:嵌入式包括时分秒的数字时钟的课程设计可以通过使用微控制器和相关的编程语言来实现。
以下是一个基本的课程设计方案,用于设计一个嵌入式数字时钟。
1. 硬件设计:- 使用一个微控制器,如Arduino或Raspberry Pi,作为主控制器。
- 连接一个实时时钟(RTC)模块,以获取准确的时间信息。
- 连接一个数码管显示器,用于显示时、分、秒的数字。
- 连接适当的按钮或开关,用于设置时间和控制其他功能。
2. 软件设计:- 使用适当的编程语言,如C或Python,编写嵌入式软件。
- 初始化RTC模块,并设置初始时间。
- 通过读取RTC模块的时间信息,更新时、分、秒的变量。
- 将时、分、秒的变量转换为适当的格式,并在数码管显示器上显示。
- 实现按钮或开关的功能,例如设置时间、切换显示模式等。
- 使用循环结构,不断更新时间和响应用户输入。
扩展和深入分析:在设计嵌入式数字时钟时,可以进一步扩展和改进功能,以满足特定需求和提供更好的用户体验。
以下是一些可能的扩展和深入分析方向:1. 闹钟功能:- 添加闹钟功能,允许用户设置特定时间的闹钟。
- 当闹钟时间到达时,触发声音或震动提示。
2. 温度和湿度显示:- 连接温度和湿度传感器,显示当前环境的温度和湿度信息。
3. 亮度控制:- 添加光敏电阻或其他传感器,根据环境光线调整数码管显示器的亮度。
4. 日期和星期显示:- 使用RTC模块提供的日期信息,显示当前日期和星期。
5. 时钟同步:- 使用无线通信模块,如Wi-Fi或蓝牙,与互联网时间服务器同步时钟。
6. 电池备份:- 添加电池备份电路,以保持时钟运行,即使主电源中断。
通过以上扩展和改进,嵌入式数字时钟可以成为一个更加功能强大和实用的设备。
这些功能可以根据具体需求进行选择和实现,以满足不同用户的需求。
总结:嵌入式包括时分秒的数字时钟的课程设计可以通过硬件和软件的结合来实现。
硬件设计包括选择适当的微控制器、实时时钟模块、数码管显示器和按钮开关。
#pragma sfr //定义使用特殊功能寄存器#pragma access //定义使用存储器读写功能#pragma EI //定义使用开中断和关中断功能#pragma DI#pragma interrupt INTP5 inter RB1 //定义使用外部可屏蔽中断功能,命名中断为inter RB1#pragma interrupt INTKR inter_key RB1 //定义使用按键中断inter,命名中断为inter_key RB1#pragma interrupt INTRTC sec_INTERRUPT //定义使用INTREC中断功能,命名中断为sec_INTERRUPT//---------------------------------------------------------函数声明void Begin(); //1、端口初始化函数void delay(int k); //2、延时函数void welcome(); //3、欢迎页面函数void d_c_inter(); //4、时钟标志位切换函数void d_n_inter(); //5、闹钟标志位切换函数unsigned int countdays(); //6、计算当前月中天数的函数void time(); //7、时间函数void buffer(); //8、显示缓冲区刷新函数void ymdhms(); //9、显示年月日时分秒函数void chtime_inter(); //10、调整时间函数void noiled(); //11、闹钟响铃闪烁函数void nhm(); //12、闹钟时分显示函数void nhm_inter(); //13、闹钟调时分函数void inter(); //14、外部中断处理函数void inter_key(); //15、按键中断处理函数void sec_INTERRUPT(); //16、实时计数器1s中断处理函数//---------------------------------------------------------全局变量声明unsigned int m=0; //定义INTKR中断标志变量munsigned char n=0; //定义INTRTC中断标志变量nunsigned int wel[21]={0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002, 0x0607,0x010f,0x000d,0x000d,0x070d,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002}; //"-HELLO"的显示码unsigned int data[10]={0x070d,0x0600,0x030e,0x070a,0x0603,0x050b,0x050f,0x0700,0x070f,0x070b};//数字"0"~"9"的显示码unsigned char p=0; //显示转换标志,i=0显示年,i=1显示月,i=2显示日,i=3显示时,i=4显示分,i=5显秒unsigned char q=0; //显示闹钟转换标志,i=0显示时,i=1显示分unsigned char KEY=0; //定义全局变量KEYunsigned int year=2000; //初始化使年单元=2000unsigned int month=1; //初始化使月单元=1unsigned int day=1; //初始化使日单元=1unsigned int hour=0; //初始化使小时单元=0unsigned int minute=0; //初始化使分单元=0unsigned int second=0; //初始化使秒单元=0unsigned int nhour=0; //初始化使闹钟小时单元=0 unsigned int nminute=0; //初始化使闹钟分单元=0unsigned int bymd[8]; //年月日的位数码显示缓存区unsigned int bhms[8]; //时分秒的位数码显示缓存区unsigned int bnhm[8]; //闹钟的时分的位数码显示缓存区unsigned int tdays=0; //当前月份天数的临时变量//---------------------------------------------------------1、端口初始化函数void Begin(){PCC =0x00; // CPU的时钟选择(.0MHz)PFALL=0x0F; //所有接LCD引脚指定为LCD引脚LCDC0=0x33; //确定LCD的显示频率LCDMD=0x10; // LCD电源设置为1/5电源电压LCDM=0xC0; //LCD显示开DI(); //关中断PM3.0=1; //接按键的引脚P30设为输入模式PU3.0=1; //接按键的引脚P30使用内部上拉电阻PM4=0x3F; //端口的位~位为输入端口PU4=0x3F; //端口的位~位使用内部上拉电阻EGP.5=1; //外部中断INTP5的上升沿有效PMK5=0; //INTP5中断允许KRM=0x3f; //按键KEY中断允许KRMK=0; //中断屏蔽标志清零P1.4=0; //端口P1.4输出,使LED1处于熄灭状态P1.7=0; //端口P1.7输出,使LED1处于熄灭状态PM1.4=0; //端口P1.4设置为输出模式PM1.7=0; //端口P1.7设置为输出模式P3.3=0; //端口P3.3输出PM3.3=0; //端口P3.3设置为输出模式BZOE=0; //关闭蜂鸣器信号输出P3.4=0; //端口P3.4引脚上的灯处于熄灭状态PM3.4=0; //端口P3.4设置为输出模式P13=0xF0; //端口P13、P14、P15输出,使所有的灯处于熄灭状态P14=0xF0;P15=0xF0;PM13=0xF0; //端口P13的低四位设置为输出模式PM14=0xF0; //端口P14的低四位设置为输出模式PM15=0xF0; //端口P15的低四位设置为输出模式RTCMK=0; //允许实时时钟中断OSCSELS = 1; //启动副系统时钟RTCCL = 0; //实时计数器的输入时钟为副系统时钟RTCC0 = 0x09; //停止计数器操作,禁止RTC1HZ 引脚输出,//RTCCL 引脚输出,选择24小时系统,选择//1秒一次固定周期中断RTCE = 1; //启动计数器工作}//---------------------------------------------------------2、延时函数void delay(int k){unsigned char i,j;for(i=0;i<k;i++){for(j=0;j<k;j++){}}}//---------------------------------------------------------3、欢迎页面函数void welcome(){ unsigned int a,b; // a,b为计数标志unsigned int LCD_addr; //定义LCD地址for(a=0;a<14;a++) //将显示循环14次{LCD_addr=0xFA40; //初始化LCD地址为xFA40for(b=0;b<8;b++) //按显示位数循环次{pokew (LCD_addr,wel[a+b]); //将变量wel[a+b]中的内容写入地址为LCD_addr的字节存储单元中LCD_addr=LCD_addr+2; //LCD_addr内存地址指针加}delay(100); //延时函数pokew(LCD_addr,0x0000); //关闭显示}delay(100); //延时函数}//---------------------------------------------------------4、时钟标志位切换函数void d_c_inter(){DI(); //关中断if(p<5){p++;} //显示切换标志p小于,p加else{p=0;} //显示切换标志pEI(); //开中断}//---------------------------------------------------------5、闹钟标志位切换函数void d_n_inter(){DI(); //关中断if(q<2) //显示切换标志q{q++;}else{q=0;} //显示切换标志qEI(); //开中断}//---------------------------------------------------------6、计算当前月中天数的函数unsigned int countdays(unsigned int tmonth){unsigned int days;if ( (tmonth==4)||(tmonth==6)||(tmonth==9)||(tmonth==11))days=30; //4,6,9,11月为天else if (tmonth==2){if ((year%4==0 && year %100!=0)||(year%400==0))days=29; //闰年月为天elsedays=28; //平年月为天}elsedays=31; //1,3,5,7,8,10,12月为天return (days);}//---------------------------------------------------------7、时间函数void time(){if (n !=0) //判断到了秒吗?{n=0;second++;if (second>=60) //秒大于时,分加{second=0;minute++;if (minute>=60) //分大于时,时加{minute=0;hour++;if (hour>=24) //时大于时,天加{hour=0;day++;tdays=countdays(month); //判断该月是多少天if (day>=tdays) //该月最后一天到时,月加{day=1;month++;if (month>=13) //月大于后年加{month=1;year++;}}}}}}}//---------------------------------------------------------8、显示缓冲区刷新函数void buffer(){bymd[0]=data[(year/100)/10]; //年的显示码放入数码显示缓存区bymd[1]=data[(year/100)%10]; //年的显示码放入数码显示缓存区bymd[2]=data[(year%100)/10]; //年的显示码放入数码显示缓存区bymd[3]=data[(year%100)%10]; //年的显示码放入数码显示缓存区bymd[3]|= 0x0800; //在年的个位后显示一个点“.”bymd[4]=data[month/10]; //月的显示码放入数码显示缓存区bymd[5]=data[month%10]; //月的显示码放入数码显示缓存区bymd[5]|= 0x0800; //在月的个位后显示一个点“.”bymd[6]=data[day/10]; //日的显示码放入数码显示缓存区bymd[7]=data[day%10]; //日的显示码放入数码显示缓存区bhms[0]=wel[0]; //显示“-”bhms[1]=data[hour/10]; //时的显示码放入数码显示缓存区bhms[2]=data[hour%10]; //时的显示码放入数码显示缓存区bhms[2] |= 0x0800; //在时的个位后显示一个点“.”bhms[3]=data[minute/10]; //分的显示码放入数码显示缓存区bhms[4]=data[minute%10]; //分的显示码放入数码显示缓存区bhms[4] |= 0x0800; //在分的个位后显示一个点“.”bhms[5]=data[second/10]; //秒的显示码放入数码显示缓存区bhms[6]=data[second%10]; //秒的显示码放入数码显示缓存区bhms[7]=wel[0]; //显示“-”bnhm[0]=wel[0]; //显示“-”bnhm[1]=wel[0]; //显示“-”bnhm[2]=data[nhour/10]; //闹钟时的显示码放入时和分的数码显示缓存bnhm[3]=data[nhour%10]; //闹钟时的显示码放入时和分的数码显示缓存bnhm[3] |= 0x0800; //在时的个位后显示一个点“.”bnhm[4]=data[nminute/10]; //闹钟分的显示码放入时和分的数码显示缓存bnhm[5]=data[nminute%10]; //闹钟分的显示码放入时和分的数码显示缓存bnhm[6]=wel[0]; //显示“-”bnhm[7]=wel[0]; //显示“-”}//---------------------------------------------------------9、显示年月日时分秒函数void ymdhms(){unsigned int a; //8位显示位数计数unsigned int b[8]; //显示输出缓存区unsigned int LCD_addr; //定义LCD地址LCD_addr=0xFA40; //初始化LCD地址为xFA40switch(p) //判断标志位的值{case 0: //若显示转换标志为,显示时分秒{b[0]=bhms[0];b[1]=bhms[1];b[2]=bhms[2];b[3]=bhms[3];b[4]=bhms[4];b[6]=bhms[6];b[7]=bhms[7];break;}case 1: //若显示转换标志为,显示年{b[0]=wel[0];b[1]=wel[0];b[2]=bymd[0];b[3]=bymd[1];b[4]=bymd[2];b[5]=bymd[3];b[6]=wel[0];b[7]=wel[0];break;}case 2: //若显示转换标志为,显示月日{b[0]=wel[0];b[1]=wel[0];b[2]=bymd[4];b[3]=bymd[5];b[4]=bymd[6];b[5]=bymd[7];b[6]=wel[0];b[7]=wel[0];break;}case 3: //若显示转换标志为,显示年月日{b[0]=bymd[0];b[1]=bymd[1];b[2]=bymd[2];b[3]=bymd[3];b[4]=bymd[4];b[5]=bymd[5];b[6]=bymd[6];b[7]=bymd[7];break;}case 4: //若显示转换标志为,显示时分{b[0]=wel[0];b[2]=bhms[1];b[3]=bhms[2];b[4]=bhms[3];b[5]=bhms[4];b[6]=wel[0];b[7]=wel[0];break;}case 5: //若显示转换标志为,显示分秒{b[0]=wel[0];b[1]=wel[0];b[2]=bhms[3];b[3]=bhms[4];b[4]=bhms[5];b[5]=bhms[6];b[6]=wel[0];b[7]=wel[0];break;}}for(a=0;a<8;a++) //按显示位数循环8次{pokew (LCD_addr,b[a]); //将变量b[a]中的内容写入地址为LCD_addr的2字节存储单元中delay(100); //延时函数LCD_addr=LCD_addr+2; //LCD_addr内存地址指针加2 }}//---------------------------------------------------------10、调整时间函数void chtime_inter(){DI(); //关中断switch(p){case 0:{if(second<59) second++; //秒计数值小于,秒值加else second=0; //秒计数值等于,秒值清“”break;}case 1:{year++;break;}case 2:{if(month<12) month++; //月计数值小于,月值加else month=1; break; //月计数值等于,月值清“”}case 3:{tdays=countdays(month); //判断该月是多少天if(day>=tdays) day=1; //日计数值是该月最后一天时,day=1 else day++; //日计数值不是该月最后一天时,daybreak;}case 4:{if(hour<23) hour++; //时计数值小于,时值加else hour=0; //时计数值等于,时值清“”break;}case 5:{if(minute<59) minute++; //分计数值小于,分值加else minute=0; //分计数值等于,分值清“”break;}}EI(); //开中断}//---------------------------------------------------------11、闹钟响铃闪烁函数void noiled(){if(nhour==hour&&nminute==minute&&P1.4==1&&P1.7==1)//当时钟时间与闹钟所设定的时间相同时,蜂鸣器发出声响,LED小灯旋转发光{P13=0x09; //红灯亮P14=0x04;P15=0x02;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xC0; //打开蜂鸣器信号输出,输出频率为1.95KHzdelay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x02; //红灯灭P14=0x09;P15=0x04;P3.4=1; //端口P3.4引脚上的灯亮CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHzdelay(30);BZOE=0; //关闭蜂鸣器信号输出P13=0x04; //绿灯亮P14=0x02;P15=0x09;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xC0; //打开蜂鸣器信号输出,输出频率为1.95KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x09; //绿灯灭P14=0x04;P15=0x02;P3.4=1; //端口P3.4引脚上的灯亮CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHzdelay(40);BZOE=0; //关闭蜂鸣器信号输出P13=0x02; //黄灯亮P14=0x09;P15=0x04;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xC0; //打开蜂鸣器信号输出,输出频率为1.95KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x04; //黄灯灭P14=0x02;P15=0x09;P3.4=1; //端口P3.4引脚上的灯亮CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHzdelay(30);BZOE=0; //关闭蜂鸣器信号输出P13=0x01; //第一、三个红灯亮P14=0x04;P15=0x00;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xC0; //打开蜂鸣器信号输出,输出频率为1.95KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x00; //第一、三个红灯灭P14=0x00;P15=0x00;P3.4=1; //端口P3.4引脚上的灯亮CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHzdelay(40);BZOE=0; //关闭蜂鸣器信号输出P13=0x08; //第二、四个红灯亮P14=0x00;P15=0x02;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xC0; //打开蜂鸣器信号输出,输出频率为1.95KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x00; //第二、四个红灯灭P14=0x00;P15=0x00;P3.4=1; //端口P3.4引脚上的灯亮CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHzdelay(30);BZOE=0; //关闭蜂鸣器信号输出P13=0x02; //第一、二个黄灯亮P14=0x01;P15=0x00;P3.4=0; //端口P3.4引脚上的灯灭CKS=0x80; //打开蜂鸣器信号输出,输出频率为7.81KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x00; //第二、三个黄灯亮P14=0x09;P15=0x00;CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHz delay(40);BZOE=0; //关闭蜂鸣器信号输出P13=0x00; //第三、四个黄灯亮P14=0x08;P15=0x04;P3.4=1; //端口P3.4引脚上的灯亮CKS=0xC0; //打开蜂鸣器信号输出,输出频率为1.95KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x02; //第四、一个黄灯亮P14=0x00;P15=0x04;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xE0; //打开蜂鸣器信号输出,输出频率为0.98KHz delay(30);BZOE=0; //关闭蜂鸣器信号输出P13=0x04; //第一、二个绿灯亮P14=0x02;P15=0x00;P3.4=1; //端口P3.4引脚上的灯亮CKS=0x80; //打开蜂鸣器信号输出,输出频率为7.81KHz delay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x00; //第二、三个绿灯亮P14=0x02;P15=0x01;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHz delay(40);BZOE=0; //关闭蜂鸣器信号输出P13=0x00; //第三、四个绿灯亮P14=0x00;P15=0x09;P3.4=1; //端口P3.4引脚上的灯亮CKS=0x80; //打开蜂鸣器信号输出,输出频率为7.81KHzdelay(50);BZOE=0; //关闭蜂鸣器信号输出P13=0x04; //第四、一个绿灯亮P14=0x00;P15=0x08;P3.4=0; //端口P3.4引脚上的灯灭CKS=0xA0; //打开蜂鸣器信号输出,输出频率为3.90KHzdelay(60);BZOE=0; //关闭蜂鸣器信号输出}P13=0x00; //灯全灭P14=0x00;P15=0x00;P3.4=0; //端口P3.4引脚上的灯灭}//---------------------------------------------------------12、闹钟时分显示函数void nhm(){unsigned int a;unsigned int LCD_addr;LCD_addr=0xFA40;for(a=0;a<8;a++) //按显示位数循环8次{pokew (LCD_addr, bnhm[a]); //将变量b[a]中的内容写入地址为LCD_addr的2字节存储单元中delay(100); //延时函数LCD_addr=LCD_addr+2; //LCD_addr内存地址指针加2 }}//---------------------------------------------------------13、闹钟调时分函数void nhm_inter(){DI(); //关中断switch(q){case 1:{if(nhour<23) //闹钟时计数值小于,分值加一nhour++;elsenhour=0; //闹钟时计数值等于,分值清“”break;}case 2:{if(nminute<59) //闹钟分计数值小于,分值加nminute++;elsenminute=0; //闹钟分计数值等于,分值清“”break;}}EI(); //开中断}//---------------------------------------------------------14、外部中断处理函数void inter(){DI(); //关中断m++; //中断次数加welcome(); //调用欢迎函数m=0; //定义INTKR中断标志变量mn=0; //定义INTRTC中断标志变量np=0; //显示转换标志,i=0显示年,i=1显示月,i=2显示日,i=3显示时,i=4显示分,i=5显秒q=0; //显示闹钟转换标志,i=0显示时,i=1显示分KEY=0; //定义全局变量KEYyear=2000; //初始化使年单元=2000month=1; //初始化使月单元=1day=1; //初始化使日单元=1hour=0; //初始化使小时单元=0minute=0; //初始化使分单元=0second=0; //初始化使秒单元=0nhour=0; //初始化使闹钟小时单元=0nminute=0; //初始化使闹钟分单元=0tdays=0; //当前月份天数的临时变量EI(); //开中断}//---------------------------------------------------------15、按键中断处理函数void inter_key(){DI(); //关中断switch(P4 & 0x3F) //判断哪个键被按下{case 0x3e: KEY=1;break; //按键KEY1被按下case 0x3d: KEY=2;break; //按键KEY2被按下case 0x3b: KEY=3;break; //按键KEY3被按下case 0x37: KEY=4;break; //按键KEY4被按下case 0x2f: KEY=5;break; //按键KEY5被按下case 0x1f: KEY=6;break; //按键KEY6被按下default:break;}EI(); //开中断}//---------------------------------------------------------16、实时计数器1s中断处理函数void sec_INTERRUPT(){DI();n=1; //每隔1s,n的值赋值EI();}//---------------------------------------------------------主函数void main(){Begin();EI(); //开中断while(1){switch(KEY){case 0: //如果没有按键按下,时钟开始工作{time(); //调用时间函数noiled(); //闹钟响铃闪烁函数buffer(); //显示缓冲区刷新函数ymdhms(); //显示年月日时分秒函数break;}case 1: //如果按下按键P40,每次分别选中年、月、日、时、分、秒time(); //调用时间函数d_c_inter(); //调用时钟切换时间函数ymdhms(); //显示年月日时分秒函数KEY=0; //转到时钟工作模式break;}case 2: //如果按下按键P41,,对当前选中的一项进行加一调整{time(); //调用时间函数chtime_inter(); //调整时间函数buffer(); //调用显示缓冲区刷新函数ymdhms(); //显示年月日时分秒函数KEY=0; //转到时钟工作模式break;}case 3: //如果按下按键P42,显示闹钟{time(); //调用时间函数nhm(); //调用闹钟时分显示函数KEY=7;break;}case 4: //如果按下按键P43,开启或关闭闹钟,开启时P14、P17两灯都亮{time(); //调用时间函数P1.4=~P1.4; //小电路板两灯取反P1.7=~P1.7;KEY=0;break;}case 5: //如果按下按键P44,每次分别选中闹钟的时、分{time(); //调用时间函数d_n_inter(); //调用闹钟切换时间函数nhm(); //调用闹钟时分显示函数KEY=7; //转到闹钟显示模式break;}case 6: //如果按下按键P45,开启闹钟时,对当前选中的一项进行加一调整time(); //调用时间函数nhm_inter(); //闹钟调时分函数buffer(); //调用显示缓冲区刷新函数nhm(); //调用闹钟时分显示函数KEY=7; //转到时钟工作模式break;}case 7: //开启闹钟后,显示闹钟{time(); //调用时间函数noiled(); //闹钟响铃闪烁函数nhm(); //调用闹钟时分显示函数break;}}}}。