基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx

上传人:b****5 文档编号:29914704 上传时间:2023-08-03 格式:DOCX 页数:28 大小:165.42KB
下载 相关 举报
基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx_第1页
第1页 / 共28页
基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx_第2页
第2页 / 共28页
基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx_第3页
第3页 / 共28页
基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx_第4页
第4页 / 共28页
基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx

《基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx》由会员分享,可在线阅读,更多相关《基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx(28页珍藏版)》请在冰豆网上搜索。

基于μPD78F0485单片机实验板的实时时钟程序设计与实现.docx

基于μPD78F0485单片机实验板的实时时钟程序设计与实现

 

基于μPD78F0485单片机实验板的实时时钟程序设计与实现

专业:

计算机科学与技术

班级:

11级

学号:

姓名:

 

基于μPD78F0485单片机实验板的实时时钟程序设计与实现

1实验环境

硬件:

PC、µPD78F0485单片机。

软件:

Windows7操作系统、开发环境支持软件NECElectronicsMicrocomputer、

MicrosoftVisio绘图

2功能描述

a)液晶屏可切换显示日期和时间。

b)具有日期和时间校对功能。

c)用LED1~LED12模拟秒针走动。

d)有闹钟功能。

3总体设计

3.1显示设计

a)在LCD上显示年月日,分别用两位数表示年月日。

年的值从00~99;月的值从

01~12;日的值如果是2月,闰年为01~29,平年为01~28,其他月份大月为01~31,

小月为01~30。

图3.1.1年月日的显示

b)在LCD上显示星期时分,分别用两位数表示星期时分。

星期的值从00~06,其中

00表示星期天,其它的则一一对应;时采用24小时制,其值从00~23;分的值从

00~59。

图3.1.2星期时分的显示

c)在LCD上显示时分秒。

时采用24小时制,其值从00~23;分的值从00~59;秒的

值从00~59。

图3.1.3时分秒的显示

3.2时间显示切换设计

设置一个全局变量i,初值为0。

每按一下KEY1,i的值加一。

当i=0,1,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=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闹钟响铃设计

当闹钟设定的时分与时钟的时分相等并且闹钟处于打开状态时,蜂鸣器就会发出响声。

3.8用LED1~LED12模拟秒针走动设计

将端口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的引脚指定为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实时时钟模块

利用实时计数器来实现实时时钟模块。

实时计数器的秒计数寄存器、分计数寄存器、

时计数寄存器、日计数寄存器、周计数寄存器、月计数寄存器、年计数寄存器在开启计

数模式后会自动计数。

然后只要在一秒中断到来时,将寄存器中的值读入对应变量中,

送到显示刷新模块刷新后显示就能实现实时时钟了。

4.4闹钟设置模块

图4.4闹钟设置模块流程图

利用变量hour1和minute1来实现闹钟功能。

当KEY5或KEY6被按下就会分别调

用闹钟的调时、调分模块来设置闹钟的时间。

Hour1的值大于23时归零,minute1的

值大于59时归零。

4.5INTRTC中断处理模块

在一秒中断到来时,将实时计数器的秒计数寄存器、分计数寄存器、时计数寄存器、

日计数寄存器、周计数寄存器、月计数寄存器、年计数寄存器中的值从BCD码转换为

十进制送入到相对应的变量中,等待显示刷新模块调用。

4.6显示刷新模块

主模块在循环中会不停的调用此模块,将实时时钟的最新值转换为LCD的显示码,

并送入到显示的缓存中,等待显示模块调用。

 

4.7时钟调时模块

图4.7时钟调时模块流程图

此模块根据全局变量i的值,当KEY3被按下时,分别对实时时钟的年、月、日、星

期、时、分、秒进行调整,达到调时目的。

当各个寄存器的值达到所对应的最大值时,

根据各自的性质归零或归一。

4.8按键中断模块

根据被按下的键,将KEY设置成对应的值。

KEY1对应的值为1,以此类推。

4.9闹钟响铃模块

图4.9闹钟响铃模块流程图

当闹钟设置的时、分与实时时钟的时分相等并且P3.4端口的输出值为1即LED灯

亮时,打开蜂鸣器的输出。

蜂鸣器就会发出声音提醒闹钟时间到了。

4.10显示模块

图4.10显示模块流程图

此模块根据全局变量i的值,将对应的显示缓存区中的内容依次显示。

4.11流水灯模块

当一秒中断来到时,根据变量s的值,LED亮起对应的灯,并关闭上一个灯,s

的值加一模十二。

5操作说明

按下KEY1键,改变LCD的显示内容。

按四下KEY1键显示从年月日变为星期时分

再按三下KEY1键显示又变为时分秒。

按下KEY3键,进行调时。

当按了一下KEY1键再按KEY3键时,对年进行调整;

当按了两下KEY1键再按KEY3键时,对月进行调整;当按了三下KEY1键再按KEY3

键时,对日进行调整;当按了四下KEY1键再按KEY3键时,对星期进行调整;当按

了五下KEY1键再按KEY3键时,对时进行调整;当按了六下KEY1键再按KEY3键

时,对分进行调整。

按下KEY2键,显示闹钟的设定时间。

再按下KEY5键,对闹钟的设定时间进行时

调整;再按下KEY6键,对闹钟的设定时间进行分调整。

按下KEY4键,将P3.4LED灯打开,并开启闹钟功能。

再按一下关闭P3.4LED灯,

并关闭闹钟功能。

LED1~LED12每一秒依次亮一个灯。

6总结

经过几周的单片机课程设计,已基本完成课题要求。

功能上基本达标:

时钟的显示,调时功能。

时钟显示功能,精确度完全可以满足日常生活显示时间的需要;调时功能,方便快捷。

本次设计是结合书本样例和老师给的样例,独立设计完成。

  

另外,在本次设计的过程中,我发现很多的问题,虽然以前没有做过这样的设计但通过这次设计我学会了很多东西,单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事,比如写一个程序看其功能很少认为编写程序简单,但到编的时候才发现一些细微的知识或低级错误经常犯做不到最后常常失败,所以有些东西只有学精弄懂并且要细心才行,只学习理论有些东西是很难理解的,更谈不上掌握。

  

从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的练习的过程中才能提高,我想这就是我在这次课程设计中的最大收获。

 

附录程序清单:

#pragmasfr//使用特殊功能寄存器

#pragmaaccess//使用绝对地址指令

#pragmaEI//使用开中断关中断功能

#pragmaDI

#pragmainterruptINTKRinterRB1//定义按键中断

#pragmainterruptINTRTCRTC_INTRTC//定义周期性定时中断

charSEC_Num;//定义一个秒单元

charMIN_Num;//定义一个分单元

charHOUR_Num;//定义一个时单元

charDAY_Num;//定义一个日单元

charWEEK_Num;//定义一个周单元

charMONTH_Num;//定义一个月单元

charYEAR_Num;//定义一个年单元

unsignedcharhour1=0;//初始化闹钟时单元=0

unsignedcharminute1=0;//初始化闹钟分单元=0

unsignedintnumbercode[10]={0x070d,0x0600,0x030e,0x070a,0x0603,0x050b,0x050f,0x0700,0x070f,0x070b};

//数字“0”-“9”的显示码

unsignedchari=0;

//显示转换标志,i=0,1,2,3时显示年月日;i=4,5,6时显示星期时分;i=7时显示时分秒

unsignedcharKEY=0;//定义全局变量key

unsignedints=-1;//定义全局变量s

unsignedintbuffy_m_d[6];//年月日的数码显示缓存区

unsignedintbuffw_h_m[6];//星期时分的数码显示缓存区

unsignedintbuffh_m_s[6];//时分秒的数码显示缓存区

unsignedintbuffhm1[6];//闹钟的数码显示缓存区

voiddelay();//延时函数

unsignedintBCDtoDec(charbcd)//BCD码转换十进制函数

charDectoBCD(intDec)//十进制转换BCD码函数

unsignedintm_days(unsignedintmmonth)//计算当月天数函数

voidinter()//按键中断处理函数

voidRTC_INTRTC()//INTRTC中断处理函数

voidnoise()//闹钟响铃函数

voidfreshdisplaybuffer()//显示缓存区刷新函数

voidd_c_inter()//切换时间函数

voidplay6bit()//显示函数

voidset_hour()//闹钟使显示函数

voidset_minute()//闹钟分显示函数

voidset_inter()//调整时间函数

voidhour_inter()//闹钟调时函数

voidminute_inter()//闹钟调分函数

//----------------------------------------------延时函数

voiddelay()

{

inti;

for(i=0;i<=100;i++)

;

}

//----------------------------------------------将BCD码转换成十进制的函数

unsignedintBCDtoDec(charbcd)

{

unsignedinti,tmp;

tmp=((bcd>>4)&0x0F)*10+(bcd&0x0F);

returntmp;

}

//----------------------------------------------将十进制转换成BCD码的函数

charDectoBCD(intDec)

{

charBcd;

Bcd=((Dec/10)<<4)+((Dec%10)&0x0F);

returnBcd;

}

//----------------------------------------------计算当前月中天数的函数

unsignedintm_days(unsignedintmmonth)

{

unsignedintdays;

if((mmonth==4)||(mmonth==6)||(mmonth==9)||(mmonth==11))

days=30;

elseif(mmonth==2)

{

if(BCDtoDec(YEAR)%4==0)//判断是否是闰年

days=29;

else

days=28;

}

elsedays=31;

return(days);

}

//----------------------------------------------按键中断处理函数

voidinter()

{

DI();

switch(P4&0x3F){

case0x3e:

KEY=1;break;

case0x3d:

KEY=2;break;

case0x3b:

KEY=3;break;

case0x37:

KEY=4;break;

case0x2f:

KEY=5;break;

case0x1f:

KEY=6;break;

default:

break;

}

EI();

}

//----------------------------------------------INTRTC中断处理函数

voidRTC_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(HOUR);//将小时数转换为十进制读取到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;//流水灯处理,每一秒换一个灯显示

switch(s)

{

case0:

P15.3=0;P13.0=1;break;

case1:

P13.0=0;P13.1=1;break;

case2:

P13.1=0;P13.2=1;break;

case3:

P13.2=0;P13.3=1;break;

case4:

P13.3=0;P14.0=1;break;

case5:

P14.0=0;P14.1=1;break;

case6:

P14.1=0;P14.2=1;break;

case7:

P14.2=0;P14.3=1;break;

case8:

P14.3=0;P15.0=1;break;

case9:

P15.0=0;P15.1=1;break;

case10:

P15.1=0;P15.2=1;break;

case11:

P15.2=0;P15.3=1;break;

default:

break;

}

}

//----------------------------------------------闹钟响铃函数

voidnoise()

{

if(hour1==HOUR_Num&&minute1==MIN_Num&&P3.4==1)

{

CKS=0X80;

delay();

BZOE=0;

}

}

//----------------------------------------------显示缓存区刷新函数

voidfreshdisplaybuffer()

{

buffy_m_d[5]=numbercode[YEAR_Num/10];//年月日显示刷新

buffy_m_d[4]=numbercode[YEAR_Num%10];

buffy_m_d[4]|=0x0800;

buffy_m_d[3]=numbercode[MONTH_Num/10];

buffy_m_d[2]=numbercode[MONTH_Num%10];

buffy_m_d[2]|=0x0800;

buffy_m_d[1]=numbercode[DAY_Num/10];

buffy_m_d[0]=numbercode[DAY_Num%10];

buffw_h_m[5]=numbercode[WEEK_Num/10];//星期时分显示刷新

buffw_h_m[4]=numbercode[WEEK_Num%10];

buffw_h_m[4]|=0x0800;

buffw_h_m[3]=numbercode[HOUR_Num/10];

buffw_h_m[2]=numbercode[HOUR_Num%10];

buffw_h_m[2]|=0x0800;

buffw_h_m[1]=numbercode[MIN_Num/10];

buffw_h_m[0]=numbercode[MIN_Num%10];

buffh_m_s[5]=numbercode[HOUR_Num/10];//时分秒显示刷新

buffh_m_s[4]=numbercode[HOUR_Num%10];

buffh_m_s[4]|=0x0800;

buffh_m_s[3]=numbercode[MIN_Num/10];

buffh_m_s[2]=numbercode[MIN_Num%10];

buffh_m_s[2]|=0x0800;

buffh_m_s[1]=numbercode[SEC_Num/10];

buffh_m_s[0]=numbercode[SEC_Num%10];

}

//----------------------------------------------切换时间函数

voidd_c_inter()

{

DI();

if(i<7)

{

i++;

}

else

{

i=0;

}

EI();

}

//----------------------------------------------显示函数

voidplay6bit()

{

unsignedintdp=0;

unsignedintb[6];

unsignedintLCD_addr;

LCD_addr=0xFA4A;

while(dp<6)

{

switch(i)

{

case0:

case1:

case2:

case3:

b[dp]=buffy_m_d[dp];break;//i=0,1,2,3时显示年月日

case4:

case5:

case6:

b[dp]=buffw_h_m[dp];break;//i=4,5,6时显示星期时分

case7:

b[dp]=buffh_m_s[dp];break;//i=7使显示时分秒

}

pokew(LCD_addr,b[dp]);

delay();

pokew(LCD_addr,0x0000);

LCD_addr=LCD_addr-2;

dp++;

}

}

//----------------------------------------------闹钟时显示函数

voidset_hour()

{

unsignedintdp=4;

unsignedinta[6];

unsignedintLCD_addr;

LCD_addr=0xFA42;

buffhm1[5]=numbercode[hour1/10];

buffhm1[4]=numbercode[hour1%10];

buffhm1[4]|=0x0800;

while(dp<6)

{

a[dp]=buffhm1[dp];

pokew(LCD_addr,a[dp]);

delay();

pokew(LCD_addr,0x0000);

LCD_addr=LCD_addr-2;

dp++;

}

}

//----------------------------------------------闹钟分显示函数

voidset_minute()

{

unsignedintdp=0;

unsignedintb[6];

unsignedintLCD_addr;

LCD_addr=0xFA4A;

buffhm1[3]=numbercode[minute1/10];

buffhm1[2]=numbercode[minute1%10];

buffhm1[1]=0;

buffhm1[0]=0;

while(dp<4)

{

b[dp]=buffhm1[dp];

pokew(LCD_addr,b[dp]);

delay();

pokew(LCD_addr,0x0000);

LCD_addr=LCD_addr-2;

dp++;

}

}

//----------------------------------------------调整时间函数

voidset_inter()

{

DI();

RTCE=0;

switch(i)

{

case1:

{

if(YEAR_Num<99)

YEAR

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1