收藏 分销(赏)

单片机综合性设计性实验可调节数字电子钟设计实验报告.doc

上传人:人****来 文档编号:9809302 上传时间:2025-04-09 格式:DOC 页数:21 大小:146.04KB
下载 相关 举报
单片机综合性设计性实验可调节数字电子钟设计实验报告.doc_第1页
第1页 / 共21页
单片机综合性设计性实验可调节数字电子钟设计实验报告.doc_第2页
第2页 / 共21页
点击查看更多>>
资源描述
综合性、设计性实验报告 姓名: *** 学号: *********** 姓名: *** 学号: *********** 专业 通信工程 班级 *** 级 班 实验课程名称 单片机原理及应用 指导教师及职称 ******* 开课学期 * 至 *学年 第* 学期 上课时间 ***** *******学院教务处编印 第 1 页 一、实验设计方案 实验名称:可调节数字电子钟设计 实验时间: ******** 小组合作: 是● 否○ 小组成员: 1、实验目的: 1)学习数码管的基本知识。 2)学会如何控制动态数码管扫描显示。 3)掌握定时器和外部中断的综合应用 2、实验设备及材料: 硬件设备:LH-M20单片机实验箱 操作系统:win7 开发工具:PROTEUS、KEIL C 3、实验内容: ①问题描述 利用共阴极的6/8位LED数码管进行显示,然后用定时器实现定时,实现一个数字电子钟,实现时、分、秒,并用“.”或“-”隔开显示。通过外部按键实现对数字电子钟控制,即能适时地设置时间,并完成相应的程序。另可扩展设计电路实现秒表及闹钟等附加功能。 ②编程任务 1. 利用通过修改电路实现对数字电子钟实现控制,即能适时地设置时间,并完成相应的程序。 2.利用通过修改电路实现一个电子秒表,启动秒表,暂停秒表,秒表清零,秒表显示到毫秒。 ③样例 1. 定时1秒,采用16位定时50ms,共定时20次才可达到1秒,进一步可实现分时。 2. 利用小延时或者另一个定时器实现对8个数码管的动态扫描显示。 3. 时间设置采用外部中断。 4、实验方法步骤及注意事项: ①实验步骤 1、根据实验任务书所提出的要求,明确自己的实验目的和实验预期结果。 2、确定可调数字时钟的具体功能: 3、Proteus画硬件仿真电路图。 4、思考各功能模块的实现流程,明确各模块具体的过程,画出程序流程图 5、KEIL环境编程实现 6、下载程序,调试程序和仿真电路,观察并记录实验现象。 ②解题思路 1. 如何实现定时1秒,1分,1小时 2. 如何实现对动态数码管的动态扫描显示 3. 如何实现多功能的电子表。 数码管动态扫描显示:将数码管显示抽象成时、分、秒、“-”,通过P0和74HC573锁存器复用输出显示段码和选择位码。将编写一个显示函数,根据输入的段码和位码显示两个数码管(实质是一位的循环显示),然后在不同功能模块的显示函数中调用该显示函数,来实现不同的显示需求和闪烁控制。 各功能模块的切换: 使用外部中断来更新相应的按键变量,主程序根据按键变量进行不同模式间的切换 走时调时功能的实现:利用51单片机的定时器0实现中断计时,在中断函数现实走时的时间更新。在主循环中不断扫描按键,根据按键变量来更新时间。 年月日显示和调节: 编写相应的年月日显示函数,在按键按下时,有时间显示转为日期显示,按键释放时,恢复正常的时间显示。进入调节年月日模式后,根据扫描的按键值来更新年月日变量,进行日期的修改。 闹钟:定义闹钟使用标志,和闹钟时间变量。在开启闹钟后,树立闹钟使用标志,主循环中会不断判断闹钟变量和当前时间是否相等,若相等就进行响铃,当按键按下取消响铃。 秒表:秒表计时使用定时器1,中断周期为10MS,秒表精确到0.01S。扫描启动/停止键,清零键,退出键。 5.参考文献: 《单片机原理及接口技术》张毅刚主编,人民邮电出版社,2008 《单片机原理及应用》(第二版), 曹巧媛 主编,电子工业出版社, 2004 指导老师对实验设计方案的意见: 指导老师签名: 年 月 日 二、实验报告 1、实验目的、设备及材料、实验内容、实验方法步骤见实验设计方案 2、 实验程序(请自行填写,可拉大表格) #include<reg52.h> #define uchar unsigned char #define uint unsigned int #define DataPort P0 //定义数据端口 sbit duanma_ea=P2^2;//定义锁存使能端口 段锁存 sbit weima_ea=P2^3;// 位锁存 sbit BEEP=P1^0; //蜂鸣器发生频率输出 char set; //菜单键 sbit select=P1^3; //选择键 sbit add=P1^1; //增加键 sbit sub=P1^2; //减少键 bit mod_flag; //菜单选择标志 bit alarm_flag; //闹钟启用标志 bit alarm_ri_flag; //闹钟响铃标志 char h_shi,h_ge, m_shi,m_ge, s_shi,s_ge; //全局的秒分时位变量 char year_shi,year_ge, month_shi,month_ge, day_shi,day_ge;//全局年月日 char ah_shi,ah_ge, am_shi,am_ge, as_shi,as_ge; //全局的闹钟秒分时位变量 char sm_shi,sm_ge, ss_shi,ss_ge, s1s_shi,s2s_ge; //全局秒表计时 uchar set_num,select_num; //设置键按下次数计数变量,根据此变量来翻转状态 char shi,fen,miao,count; //全局的时分秒数变量 char year,month,day; //全局的年月日数变量 char ashi,afen,amiao; //全局的闹钟时分秒数变量 char sfen,smiao,ssmiao; //全局的闹钟时分秒数变量 uchar code dofly_DuanMa[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};// 显示段码值0~9和“-”隔离号 uchar code dofly_WeiMa[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 void custom_delayms(uint); //带参数的ms级延时声明 void part_display(uchar ,uchar ,uchar ,uchar );//部分数码管显示函数声明 void display_time(uchar);//数码管扫描函数声明 void display_date(uchar set_flash);//显示日期 void display_alarm_time(uchar set_flash);//显示闹钟时间 void display_Stopwacth();//秒表计时显示 void KeyScan(void);//键盘扫描 void init_timer0();//定时器0初始化 void init_timer1();//定时器1初始化 void Init_EX_(); void Di(); void Du(); void Date_handle();//日期处理函数,对于闰年和大小月的计算 /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main(void) { Init_EX_(); //外部中断初始化 init_timer0(); //定时器0初始化 init_timer1(); //定时器1初始化 DataPort=0 ; //输出口置零,等待数据 set_num=0; //菜单键计数 year=16;month=12;day=24; year_shi=1;year_ge=6; month_shi=1;month_ge=2;day_shi=2;day_ge=4;//设定默认的年月日 while(1) //主循环 { if(mod_flag==1) //进入设置模式 { switch(set_num) { case 1:display_time(select_num); break;//调节时分秒 显示 case 2:display_date(select_num); break;//调节年月日显示 case 3:display_alarm_time(select_num);break;//调节闹钟显示 case 4:display_Stopwacth(); break;//秒表显示 } } else //正常时间显示 { if(alarm_flag==1) //如果开启闹钟 { if( (ashi==shi) && (afen==fen) && (amiao==miao) )alarm_ri_flag=1;//时间相等,开启闹铃 if(alarm_ri_flag==1){Di();Du();}//响铃 if(add==0||sub==0)alarm_ri_flag=0; //按下增,减键就取消响铃 } if(select==0) //正常显示时间时,按下选择键,显示年月日 display_date(select_num); else display_time(select_num); //正常显示年月日 } KeyScan();//键盘扫描 } } /*------------------------------------------------ 部分数码管显示函数,给定两位数据,两位指定时分秒的功能号 ------------------------------------------------*/ void part_display(uchar set_shi,uchar set_ge,uchar set_H_M_S_ten,uchar set_H_M_S_a) { DataPort=0; //数据端口置0,保证每次数据的更新都是从0状态改变,防止重叠。 duanma_ea=1; //段使能 DataPort=dofly_DuanMa[set_shi];//送显示数据 duanma_ea=0; //锁存段数据 custom_delayms(2); //延时2MS防止消影现象 DataPort=0; weima_ea=1; //位使能 DataPort=dofly_WeiMa[set_H_M_S_ten]; //送位数据,对应为显示数据 weima_ea=0; //锁存位数据 custom_delayms(2); //延时2MS防止消影现象 DataPort=0; duanma_ea=1; DataPort=dofly_DuanMa[set_ge]; duanma_ea=0; custom_delayms(2); DataPort=0; weima_ea=1; DataPort=dofly_WeiMa[set_H_M_S_a]; weima_ea=0; custom_delayms(2); } /*时分秒扫描显示函数,给定功能号,可以设定时分秒的闪烁状态。*/ void display_time(uchar set_flash) { static uchar flash1,flash2,flash3,n1,n2,n3; switch(set_flash) //闪烁状态控制 { case 3:flash1=25;flash2=0;flash3=0;break; case 2:flash1=0;flash2=25;flash3=0;break; case 1:flash1=0;flash2=0;flash3=25;break; case 0:flash1=0;flash2=0;flash3=0;break; } part_display(10,10,2,5); //显示“-” if(n1>=flash1) //可调节n*和flash*的值,改变显示的闪烁频率 {part_display(h_shi,h_ge,0,1);} n1++; if(n1==50)n1=0; if(n2>=flash2) {part_display(m_shi,m_ge,3,4);} n2++; if(n2==50)n2=0; if(n3>=flash3) {part_display(s_shi,s_ge,6,7);} n3++; if(n3==50)n3=0; } /*年月日扫描显示函数,给定功能号,可以设定年月日的闪烁状态。*/ void display_date(uchar set_flash) { static uchar flash1,flash2,flash3,n1,n2,n3; switch(set_flash) //闪烁状态控制 { case 3:flash1=25;flash2=0;flash3=0;break; case 2:flash1=0;flash2=25;flash3=0;break; case 1:flash1=0;flash2=0;flash3=25;break; case 0:flash1=0;flash2=0;flash3=0;break; } part_display(10,10,2,5); //显示“-” if(n1>=flash1) //可调节n*和flash*的值,改变显示的闪烁频率 {part_display(year_shi,year_ge,0,1);} n1++; if(n1==50)n1=0; if(n2>=flash2) {part_display(month_shi,month_ge,3,4);} n2++; if(n2==50)n2=0; if(n3>=flash3) {part_display(day_shi,day_ge,6,7);} n3++; if(n3==50)n3=0; } /*闹钟时分秒扫描显示函数,给定功能号,可以设定时分秒的闪烁状态。*/ void display_alarm_time(uchar set_flash) { static uchar flash1,flash2,flash3,n1,n2,n3; switch(set_flash) //闪烁状态控制 { case 3:flash1=25;flash2=0;flash3=0;break; case 2:flash1=0;flash2=25;flash3=0;break; case 1:flash1=0;flash2=0;flash3=25;break; case 0:flash1=0;flash2=0;flash3=0;break; } part_display(10,10,2,5); //显示“-” if(n1>=flash1) //可调节n*和flash*的值,改变显示的闪烁频率 {part_display(ah_shi,ah_ge,0,1);} n1++; if(n1==50)n1=0; if(n2>=flash2) {part_display(am_shi,am_ge,3,4);} n2++; if(n2==50)n2=0; if(n3>=flash3) {part_display(as_shi,as_ge,6,7);} n3++; if(n3==50)n3=0; } /*秒表描显示函数*/ void display_Stopwacth() { part_display(10,10,2,5); //显示“——” part_display(sm_shi,sm_ge,0,1); part_display(ss_shi,ss_ge,3,4); part_display(s1s_shi,s2s_ge,6,7); } /*初始化定时器0函数,设置定时器初值,打开中断,计时开启*/ void init_timer0() { TMOD=0x11; TH0=(65536-50000)/256; //定时中断周期50MS TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; } /*初始化定时器0函数,设置定时器初值,打开中断,计时开启*/ void init_timer1() { TMOD=0x11; TH1=(65536-10000)/256; //定时中断周期10MS TL1=(65536-10000)%256; EA=1; ET1=0; TR1=0; } /*初始化外部中断*/ void Init_EX_() { EX0=1; IT0=1; //边沿触发 EX1=1; IT1=1; } /*外部中断1*/ void SUB_KEY() interrupt 2 //菜单键按下,触发 { set_num++; select_num=0; //选择键置0 mod_flag=1; //树立设置模式标志,进入设置显示模式 Di(); //按键声 } /*定时器0中断函数,时分秒,累计计时*/ void timer_delay() interrupt 1 { TH0=(65536-50000)/256; //定时中断周期50MS TL0=(65536-50000)%256; count++; if(count==20) { count=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; day++; if(day>27)Date_handle();//万年历算法 day_shi=day/10; day_ge=day%10; } h_shi=shi/10; h_ge=shi%10; //时变化,改变输出时数 } m_shi=fen/10; m_ge=fen%10;//分变化,改变输出分数 } s_shi=miao/10; s_ge=miao%10;//秒变化,改变输出秒数 } } /*定时器1中断函数,秒表计时*/ void stopwacth_delay() interrupt 3 { TH1=(65536-10000)/256; //定时中断周期10MS TL1=(65536-10000)%256; ssmiao++; if(ssmiao==100) { ssmiao=0; smiao++; if(smiao==60) { smiao=0; sfen++; if(sfen==60) { sfen=0; } sm_shi=sfen/10; sm_ge=sfen%10;//分变化,改变输出分数 } ss_shi=smiao/10; ss_ge=smiao%10;//分变化,改变输出分数 } s1s_shi=ssmiao/10; s2s_ge=ssmiao%10;//秒变化,改变输出秒数 } /*定义MS延时函数,用于数码管扫描时的延时处理,以及按键设置时需要选定数码管显示*/ void custom_delayms(unsigned int xms) { unsigned int i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } /*蜂鸣器*/ void Di() { uchar i; for(i=0;i<100;i++) { custom_delayms(1); //产生500HZ的信号来使喇叭发生 BEEP=~BEEP; } } void Du() { uchar i; for(i=0;i<50;i++) { custom_delayms(2); //产生500HZ的信号来使喇叭发生 BEEP=~BEEP; } } /*万年历计算函数*/ void Date_handle() { if(month==2&&year%4==0&&day==30)day=1; else if(month==2&&year%4!=0&&day==29)day=1; else if((month==4||month==6||month==9||month==11)&&day==31)day=1; else if(day==32)day=1; if(day==1) { month++; if(month==13) { month=1; year++; if(year==100)year=0; year_shi=year/10; year_ge=year%10; } month_shi=month/10; month_ge =month%10; } } /*------------------------------------------------ 按键扫描函数,根据按键状态翻转 ------------------------------------------------*/ void KeyScan() { if(set_num==1)//进入时间调时分秒模式 { if(select==0) { // custom_delayms(5); //延时消抖 if(select==0) { select_num++; while(!select) {display_time(0);} Di(); TR0=0; ET0=0;//首先恢复计时,开启计时中断(定时器0) switch(select_num) //闪烁状态控制 { case 1:break;//display(1); //秒位置闪烁 case 2:break;//display(2); //分位置闪烁 case 3:break;//display(3); //时位置闪烁 case 4:select_num=0;set_num=0;mod_flag=0; TR0=1; ET0=1;//首先恢复计时,开启计时中断(定时器0) break; //选择键清零 } } } if(select_num!=0) { if(add==0) { while(!add)display_time(0); Di(); switch(select_num) //调节闪烁位置数据 { case 1:miao++;if(miao==60)miao=0; s_shi=miao/10; s_ge=miao%10;//每调节一次送回显示 break; case 2:fen++;if(fen==60)fen=0; m_shi=fen/10; m_ge=fen%10;//每调节一次送回显示 break; case 3:shi++;if(shi==24)shi=0; h_shi=shi/10; h_ge=shi%10; break; } } if(sub==0) { while(!sub)display_time(0); Di(); switch(select_num) //调节闪烁位置数据 { case 1:miao--;if(miao==-1)miao=59; s_shi=miao/10; s_ge=miao%10; break; case 2:fen--;if(fen==-1)fen=59; m_shi=fen/10; m_ge=fen%10; break; case 3:shi--;if(shi==-1)shi=23; h_shi=shi/10; h_ge=shi%10; break; } } } } if(set_num==2)//调节年月日模式 { if(select==0) { // custom_delayms(5); //延时消抖 if(select==0) { select_num++; while(!select)display_date(0); Di(); switch(select_num) //闪烁状态控制 { case 1:break;//display(1); //秒位置闪烁 case 2:break;//display(2); //分位置闪烁 case 3:break;//display(3); //时位置闪烁 case 4:select_num=0;set_num=0;mod_flag=0; break; //选择键清零 } } } if(select_num!=0) { if(add==0) { while(!add)display_date(0); Di(); switch(select_num) //调节闪烁位置数据 { case 1:day++;if(day==32)day=1; day_shi=day/10; day_ge=day%10;//每调节一次送回显示 break; case 2:month++;if(month==13)month=1; month_shi=month/10; month_ge=month%10;//每调节一次送回显示 break; case 3:year++;if(year==100)year=0; year_shi=year/10; year_ge=year%10; break; } } if(sub==0) { while(!sub)display_date(0); Di(); switch(select_num) //调节闪烁位置数据 { case 1:day--;if(day==0)day=31; day_shi=day/10; day_ge=day%10; break;
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服