基于μPD78F0485单片机实验板的实时时钟程序设计与实现概要(共19页).doc

上传人:飞****2 文档编号:19327791 上传时间:2022-06-06 格式:DOC 页数:19 大小:865KB
返回 下载 相关 举报
基于μPD78F0485单片机实验板的实时时钟程序设计与实现概要(共19页).doc_第1页
第1页 / 共19页
基于μPD78F0485单片机实验板的实时时钟程序设计与实现概要(共19页).doc_第2页
第2页 / 共19页
点击查看更多>>
资源描述

《基于μPD78F0485单片机实验板的实时时钟程序设计与实现概要(共19页).doc》由会员分享,可在线阅读,更多相关《基于μPD78F0485单片机实验板的实时时钟程序设计与实现概要(共19页).doc(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精选优质文档-倾情为你奉上基于PD78F0485单片机实验板的实时时钟程序设计与实现 专业: 计算机科学与技术 班级: 11级 学号: 姓名: 基于PD78F0485单片机实验板的实时时钟程序设计与实现1实验环境 硬件:PC、PD78F0485单片机。 软件:Windows7 操作系统、开发环境支持软件NEC Electronics Microcomputer、 Microsoft Visio 绘图2功能描述 a)液晶屏可切换显示日期和时间。 b)具有日期和时间校对功能。 c)用LED1LED12模拟秒针走动。 d)有闹钟功能。3总体设计 3.1显示设计 a)在LCD上显示年月日,分别用两位数

2、表示年月日。年的值从0099;月的值从 0112;日的值如果是2月,闰年为0129,平年为0128,其他月份大月为0131, 小月为0130。图 3.1.1 年月日的显示 b)在LCD上显示星期时分,分别用两位数表示星期时分。星期的值从0006,其中 00表示星期天,其它的则一一对应;时采用24小时制,其值从0023;分的值从 0059。图 3.1.2 星期时分的显示 c)在LCD上显示时分秒。时采用24小时制,其值从0023;分的值从0059;秒的 值从0059。图 3.1.3 时分秒的显示 3.2时间显示切换设计 设置一个全局变量i,初值为0。每按一下KEY1,i的值加一。当i = 0,1

3、,2,3时,LCD显示年月日。当i = 4,5,6时,LCD显示星期时分。当i = 7时,LCD显示时分秒。当i 7时,i自动变为0。 3.3日期和时间校对设计 通过前面设置的全局变量i和KEY3来实现。当i = 1时,每按一下KEY3,年的值就加一,直到大于99时自动变为00。当i = 2时,每按一下KEY3,月的值就加一,直到大于12时自动变为01。当i = 3时,每按一下KEY3,日的值就加一,直到大于当月天数时自动变为01。当i = 4时,每按一下KEY3,星期的值就加一,直到大于06时自动变为00。当i = 5时,每按一下KEY3,时的值就加一,直到大于23时自动变为00。当i =

4、6时,每按一下KEY3,分的值就加一,直到大于59时自动变为00。 3.4闹钟显示设计当按下KEY2时,LCD显示闹钟设定的时间。图 3.4 闹钟的显示 3.5闹钟调整设计 当按下KEY5时,闹钟的时就加一,到23时就归零。当按下KEY6时,闹钟的分就加一,到59时就归零。 3.6闹钟开关设计 通过KEY4控制闹钟的开关,并用LED灯的亮灭来显示。将LED灯端口的输出信号 作为闹钟是否响铃的一个判断条件。按下KEY4,LED灯的输出信号取反,输出信号为 1时灯亮并且闹钟打开,为0时灯灭并且闹钟关闭。 3.7闹钟响铃设计 当闹钟设定的时分与时钟的时分相等并且闹钟处于打开状态时,蜂鸣器就会发出响声

5、。 3.8用LED1LED12模拟秒针走动设计 将端口13、14、15设置为输出模式,设置1个全局变量s,初值为-1。当1秒中断来到时s的值加一模12。根据s的值亮相应的灯,并且灭上一个灯。实现一秒亮一个灯。4功能模块设计 4.1主模块图 4.1 主模块流程图 当按键按下时,会改变KEY的值。当KEY1按下时,KEY的值就等于1,以此类推。主模块是一个无限循环,当KEY改变时,它就会转到相应的分支,执行相应的的功能。从而响应用户的操作。如KEY2被按下,则主模块就会转到分支2,然后调用闹钟显示函数,显示闹钟的当前设置值。 4.2 初始化模块 选定cpu的时钟为5.0Hz。将所有接LCD的引脚指

6、定为LCD引脚,确定LCD的显示频率,打开LCD显示。将P4的六个端口设置为输出模式,接通上拉电阻,并且允许六个按键中断。将P13、14、15的所有端口设置为输出模式。将P3.3和P3.4端口设置为输出。选择8MHz内部高速时钟作为主系统时钟,实时计数器时钟=fprs/28=32.768KHz。将周期性定时中断打开,设置为24小时制,1秒定时中断。将年的初值设置为13,月初值为01,日初值为01,星期初值为00,时初值为12,分初值为00。 4.3 实时时钟模块 利用实时计数器来实现实时时钟模块。实时计数器的秒计数寄存器、分计数寄存器、时计数寄存器、日计数寄存器、周计数寄存器、月计数寄存器、年

7、计数寄存器在开启计数模式后会自动计数。然后只要在一秒中断到来时,将寄存器中的值读入对应变量中,送到显示刷新模块刷新后显示就能实现实时时钟了。 4.4 闹钟设置模块 图 4.4 闹钟设置模块流程图 利用变量hour1和minute1来实现闹钟功能。当KEY5或KEY6被按下就会分别调用闹钟的调时、调分模块来设置闹钟的时间。Hour1的值大于23时归零,minute1的值大于59时归零。 4.5 INTRTC中断处理模块 在一秒中断到来时,将实时计数器的秒计数寄存器、分计数寄存器、时计数寄存器、日计数寄存器、周计数寄存器、月计数寄存器、年计数寄存器中的值从BCD码转换为十进制送入到相对应的变量中,

8、等待显示刷新模块调用。 4.6 显示刷新模块 主模块在循环中会不停的调用此模块,将实时时钟的最新值转换为LCD的显示码,并送入到显示的缓存中,等待显示模块调用。 4.7 时钟调时模块图 4.7 时钟调时模块流程图 此模块根据全局变量i的值,当KEY3被按下时,分别对实时时钟的年、月、日、星期、时、分、秒进行调整,达到调时目的。当各个寄存器的值达到所对应的最大值时,根据各自的性质归零或归一。 4.8 按键中断模块 根据被按下的键,将KEY设置成对应的值。KEY1对应的值为1,以此类推。 4.9 闹钟响铃模块 图 4.9 闹钟响铃模块流程图 当闹钟设置的时、分与实时时钟的时分相等并且P3.4端口的

9、输出值为1即LED灯亮时,打开蜂鸣器的输出。蜂鸣器就会发出声音提醒闹钟时间到了。 4.10 显示模块图 4.10 显示模块流程图 此模块根据全局变量i的值,将对应的显示缓存区中的内容依次显示。 4.11 流水灯模块 当一秒中断来到时,根据变量s的值,LED亮起对应的灯,并关闭上一个灯,s 的值加一模十二。5 操作说明 按下KEY1键,改变LCD的显示内容。按四下KEY1键显示从年月日变为星期时分再按三下KEY1键显示又变为时分秒。 按下KEY3键,进行调时。当按了一下KEY1键再按KEY3键时,对年进行调整;当按了两下KEY1键再按KEY3键时,对月进行调整;当按了三下KEY1键再按KEY3键

10、时,对日进行调整;当按了四下KEY1键再按KEY3键时,对星期进行调整;当按了五下KEY1键再按KEY3键时,对时进行调整;当按了六下KEY1键再按KEY3键时,对分进行调整。 按下KEY2键,显示闹钟的设定时间。再按下KEY5键,对闹钟的设定时间进行时调整;再按下KEY6键,对闹钟的设定时间进行分调整。 按下KEY4键,将P3.4 LED灯打开,并开启闹钟功能。再按一下关闭P3.4 LED灯,并关闭闹钟功能。 LED1LED12每一秒依次亮一个灯。6 总结 经过几周的单片机课程设计,已基本完成课题要求。功能上基本达标:时钟的显示,调时功能。时钟显示功能,精确度完全可以满足日常生活显示时间的需

11、要;调时功能,方便快捷。 本次设计是结合书本样例和老师给的样例,独立设计完成。 另外,在本次设计的过程中,我发现很多的问题,虽然以前没有做过这样的设计但通过这次设计我学会了很多东西,单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事,比如写一个程序看其功能很少认为编写程序简单,但到编的时候才发现一些细微的知识或低级错误经常犯做不到最后常常失败,所以有些东西只有学精弄懂并且要细心才行,只学习理论有些东西是很难理解的,更谈不上掌握。 从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识

12、用到实际当中,学习单机片机更是如此,程序只有在经常的练习的过程中才能提高,我想这就是我在这次课程设计中的最大收获。附录 程序清单:#pragma sfr /使用特殊功能寄存器#pragma access /使用绝对地址指令#pragma EI /使用开中断关中断功能#pragma DI#pragma interrupt INTKR inter RB1 /定义按键中断#pragma interrupt INTRTC RTC_INTRTC /定义周期性定时中断char SEC_Num; /定义一个秒单元char MIN_Num; /定义一个分单元char HOUR_Num; /定义一个时单元cha

13、r DAY_Num; /定义一个日单元char WEEK_Num; /定义一个周单元char MONTH_Num;/定义一个月单元char YEAR_Num; /定义一个年单元unsigned char hour1 = 0; /初始化闹钟时单元=0unsigned char minute1 = 0;/初始化闹钟分单元=0unsigned int numbercode10 = 0x070d , 0x0600 , 0x030e , 0x070a , 0x0603 , 0x050b , 0x050f , 0x0700 , 0x070f , 0x070b ;/数字“0”-“9”的显示码unsigned

14、 char i=0;/显示转换标志,i=0,1,2,3时显示年月日;i=4,5,6时显示星期时分;i=7时显示时分秒unsigned char KEY=0; /定义全局变量keyunsigned int s=-1; /定义全局变量sunsigned int buffy_m_d6; /年月日的数码显示缓存区unsigned int buffw_h_m6; /星期时分的数码显示缓存区unsigned int buffh_m_s6; /时分秒的数码显示缓存区unsigned int buffhm16; /闹钟的数码显示缓存区void delay(); /延时函数unsigned int BCDtoD

15、ec( char bcd) /BCD码转换十进制函数char DectoBCD(int Dec) /十进制转换BCD码函数unsigned int m_days(unsigned int mmonth) /计算当月天数函数void inter() /按键中断处理函数void RTC_INTRTC() /INTRTC中断处理函数void noise() /闹钟响铃函数void freshdisplaybuffer() /显示缓存区刷新函数void d_c_inter() /切换时间函数void play6bit() /显示函数void set_hour() /闹钟使显示函数void set_mi

16、nute() /闹钟分显示函数void set_inter() /调整时间函数void hour_inter() /闹钟调时函数void minute_inter() /闹钟调分函数/-延时函数void delay()int i;for(i=0;i4)&0x0F)*10 + (bcd&0x0F); return tmp;/-将十进制转换成BCD码的函数char DectoBCD(int Dec) char Bcd; Bcd = (Dec/10)4) + (Dec%10) & 0x0F); return Bcd;/-计算当前月中天数的函数unsigned int m_days(unsigned

17、int mmonth)unsigned int days;if(mmonth=4)|(mmonth=6)|(mmonth=9)|(mmonth=11)days=30;else if (mmonth=2)if(BCDtoDec(YEAR)%4=0) /判断是否是闰年days=29;elsedays=28;else days=31;return(days);/-按键中断处理函数void inter()DI(); switch(P4 & 0x3F) case 0x3e:KEY=1;break; case 0x3d:KEY=2;break; case 0x3b:KEY=3;break; case 0x

18、37:KEY=4;break; case 0x2f:KEY=5;break; case 0x1f:KEY=6;break; default: break; EI();/-INTRTC中断处理函数void RTC_INTRTC()RWAIT = 1; /RWAIT标志置1,读取实时时钟数据while(RWST=0); /检测是否处于读、写模式,RWST=1表示处于读写模式SEC_Num =BCDtoDec(SEC); /将秒钟数转换为十进制读取到SEC_Num中MIN_Num =BCDtoDec(MIN); /将分钟数转换为十进制读取到MIN_Num中HOUR_Num =BCDtoDec(HOU

19、R); /将小时数转换为十进制读取到HOUR_Num中DAY_Num =BCDtoDec(DAY); /将日计数转换为十进制读取到HOUR_Num中 WEEK_Num =BCDtoDec(WEEK); /将周计数转换为十进制读取到WEEK_Num中MONTH_Num =BCDtoDec(MONTH); /将月计数转换为十进制读取到MONTH_Num中YEAR_Num =BCDtoDec(YEAR); /将年计数转换为十进制读取到YEAR_Num中RWAIT = 0;while(RWST=1); /检测是否处于计数模式,RWST=0表示处于计数模式 s=(s+1)%12; /流水灯处理,每一秒换

20、一个灯显示switch(s) case 0: P15.3=0;P13.0=1; break; case 1: P13.0=0;P13.1=1; break; case 2: P13.1=0;P13.2=1; break; case 3: P13.2=0;P13.3=1; break; case 4: P13.3=0;P14.0=1; break; case 5: P14.0=0;P14.1=1; break; case 6: P14.1=0;P14.2=1; break; case 7: P14.2=0;P14.3=1; break; case 8: P14.3=0;P15.0=1; brea

21、k; case 9: P15.0=0;P15.1=1; break; case 10: P15.1=0;P15.2=1; break; case 11: P15.2=0;P15.3=1; break; default:break; /-闹钟响铃函数void noise()if(hour1=HOUR_Num&minute1=MIN_Num&P3.4=1)CKS=0X80;delay();BZOE=0;/-显示缓存区刷新函数void freshdisplaybuffer() buffy_m_d5=numbercodeYEAR_Num/10; /年月日显示刷新 buffy_m_d4=numberco

22、deYEAR_Num%10; buffy_m_d4|=0x0800; buffy_m_d3=numbercodeMONTH_Num/10; buffy_m_d2=numbercodeMONTH_Num%10; buffy_m_d2|=0x0800; buffy_m_d1=numbercodeDAY_Num/10; buffy_m_d0=numbercodeDAY_Num%10; buffw_h_m5=numbercodeWEEK_Num/10; /星期时分显示刷新 buffw_h_m4=numbercodeWEEK_Num%10; buffw_h_m4|=0x0800; buffw_h_m3=

23、numbercodeHOUR_Num/10; buffw_h_m2=numbercodeHOUR_Num%10; buffw_h_m2|=0x0800; buffw_h_m1=numbercodeMIN_Num/10; buffw_h_m0=numbercodeMIN_Num%10; buffh_m_s5=numbercodeHOUR_Num/10; /时分秒显示刷新 buffh_m_s4=numbercodeHOUR_Num%10; buffh_m_s4|=0x0800; buffh_m_s3=numbercodeMIN_Num/10; buffh_m_s2=numbercodeMIN_Nu

24、m%10; buffh_m_s2|=0x0800; buffh_m_s1=numbercodeSEC_Num/10; buffh_m_s0=numbercodeSEC_Num%10;/-切换时间函数void d_c_inter()DI();if(i7)i+;elsei=0; EI();/-显示函数void play6bit()unsigned int dp=0;unsigned int b6;unsigned int LCD_addr;LCD_addr=0xFA4A;while (dp6)switch(i) case 0: case 1: case 2: case 3:bdp = buffy_

25、m_d dp;break;/i=0,1,2,3时显示年月日 case 4: case 5: case 6:bdp = buffw_h_m dp;break;/i=4,5,6时显示星期时分 case 7:bdp = buffh_m_s dp;break;/i=7使显示时分秒pokew(LCD_addr,bdp);delay();pokew(LCD_addr,0x0000);LCD_addr = LCD_addr-2;dp+;/-闹钟时显示函数void set_hour()unsigned int dp=4;unsigned int a6;unsigned int LCD_addr;LCD_add

26、r=0xFA42;buffhm15=numbercodehour1/10; buffhm14=numbercodehour1%10;buffhm14|=0x0800;while (dp6)adp=buffhm1dp;pokew(LCD_addr,adp);delay();pokew(LCD_addr,0x0000);LCD_addr=LCD_addr-2;dp+;/-闹钟分显示函数void set_minute()unsigned int dp=0;unsigned int b6;unsigned int LCD_addr;LCD_addr=0xFA4A;buffhm13=numbercode

27、minute1/10;buffhm12=numbercodeminute1%10;buffhm11=0;buffhm10=0;while (dp4)bdp=buffhm1dp;pokew(LCD_addr,bdp);delay();pokew(LCD_addr,0x0000);LCD_addr=LCD_addr-2;dp+;/-调整时间函数void set_inter()DI();RTCE=0;switch(i)case 1: if(YEAR_Num99) YEAR = DectoBCD(YEAR_Num+1); else YEAR = 0; break;case 2: if(MONTH_Nu

28、m= temp) DAY =1; else DAY = DectoBCD(DAY_Num+1); break;case 4: if(WEEK_Num6) WEEK =DectoBCD(WEEK_Num+1); else WEEK = 0; break;case 5: if(HOUR_Num23) HOUR = DectoBCD(HOUR_Num+1); else HOUR =0; break;case 6: if(MIN_Num59) MIN = DectoBCD(MIN_Num+1); else MIN = 0; break; default : break; RTCE=1;EI();/-闹

29、钟调时函数void hour_inter()if(hour123) hour1+;else hour1=0;/-闹钟调分函数void minute_inter()if(minute159) minute1+;else minute1=0;/-主函数void main() PCC=0x00; /CPU的时钟选择(5.0Hz) PFALL=0x0F; /所有接LCD引脚指定为LCD引脚LCDC0=0x45; /确定LCD显示频率LCDMD=0x10; /LCD电源设置为1/5VDDLCDM=0xC0; /LCD显示开PM4=0x3F; /P4的六个端口设置为输入模式PU4=0x3F; /接通上拉电

30、阻KRM=0x3F; /允许六个按键中断KRMK=0;P3.4=0; /LED灯初始化为熄灭状态PM3.4=0; /P3.3和P3.4端口设置为输出模式P3.3=0;PM3.3=0; PM13=0xf0; /端口13,14,15设置为输出模式 PM14=0xf0; PM15=0xf0;EI();RTCCL=0X02; /8MHz内部高速时钟作为主系统时钟,实时计数器时钟=fprs/28=32.768KHzRIFG=0; /周期性定时中断打开RTCE=0; /停止计数操作RTCC0 = 0x0a; /无输出,24小时制,1秒钟定时中断MIN = 0X00; /设置分初值HOUR = 0X12;

31、/设置时初值DAY = 0X01; /设置日初值WEEK = 0x00; /设置周初值MONTH = 0X01; /设置月初值YEAR = 0X13; /设置年(2位数)初值RTCIF = 0; /清中断 固定中断标示RTCMK = 0; /固定周期中断开RTCE=1; /启动计数操作while(1) switch(KEY)case 0: /没有按键中断noise(); /调用闹钟响铃函数freshdisplaybuffer(); /调用显示缓存区刷新函数play6bit(); /调用显示函数break;case 1: /按键KEY1被按下d_c_inter(); /调用切换时间函数fresh

32、displaybuffer(); /调用显示缓存区刷新函数play6bit(); /调用显示函数KEY=0;break;case 2: /按键KEY2被按下set_hour(); /调用闹钟时显示函数set_minute(); /调用闹钟分显示函数KEY=7;break;case 3: /按键KEY3被按下set_inter(); /调用时间调整函数freshdisplaybuffer(); /调用显示缓存区刷新函数play6bit(); /调用显示函数KEY=0;break;case 4: /按键KEY4被按下P3.4=P3.4; /切换LED亮灭,调整闹钟开关KEY=0;break;case 5: /按键KEY5被按下hour_inter(); /调用闹钟调时函数set_hour(); /调用闹钟时显示函数KEY=7;break;case 6: /按键KEY6被按下minute_inter(); /调用闹钟调分函数 set_minute(); /调用闹钟分显示函数KEY=7;break;case 7:noise(); /调用闹钟响铃函数set_hour(); /调用闹钟时显示函数set_minute(); /调用闹钟分显示函数break;专心-专注-专业

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁