《基于单片机内部定时计数器的数字钟方案设计书.doc》由会员分享,可在线阅读,更多相关《基于单片机内部定时计数器的数字钟方案设计书.doc(9页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、. .方跃春(副教授) 大学城栏目:世界大学城居民新闻空间栏目:方法库共207篇论文| 附件【 数字钟调整日期、时间程序流程图.swf1.swfclock_2.c】 收藏到我的学习空间 收藏到我的课堂魔方方跃春(副教授) 发表于2011-5-26 1:54:23 阅读565 评论3 流程图!/*基于单片机内部定时计数器的数字钟设计1、用单片机内部定时计数器T0进展计时;2、用LCD1062液晶器显示日期、时间;3、具有闰年自动计算功能;4、具有根据年、月、日计算星期功能;5、具有时间、日期调整功能。Design:XX民政职业技术学院,方跃春*/#include#define uchar uns
2、igned char /宏定义#define uint unsigned int /宏定义sbit rs=P35。 /液晶数据/指令选择端:1-数据,0-指令sbit lcden=P34。 /液晶使能控制端:1-有效,0-无效sbit shift_key=P32。/位置移动键sbit up_key=P33。/增加键uchar temp=0。/定义定时器溢出计数变量,每隔50ms产生1次溢出,temp加1uint year=2011。/定义年变量并赋初值2011年uchar month=05,day=23,week。/定义月、日、星期变量,并赋初值5月23日uchar hour=0,minute
3、=00,second=00。/定义时、分、秒变量,并赋初值12时00分00秒uchar code week_string74=MON,TUE,WED,THU,FRI,SAT,SUN。/定义星期英文缩写表uchar data month_day12=31,0,31,30,31,30,31,31,30,31,30,31。/定义每月天数表/*-定时计数器T0及中断初始化函数-*/void init(void) TMOD=0x01。/设置定时器0为工作方式1 TH0=(65536-50000)/256。/16位计数初值除以256得到高8位初值 TL0=(65536-50000)%256。/16位计数初
4、值除以256的余数得到低8位初值 EA=1。/开总中断 ET0=1。/开启定时器0中断 EX0=1。/开启外部中断,外部中断用于调整时间 PT0=1。/将定时器0中断设置高优先级,调整时间期不停顿计时 TR0=1。/启动定时器0/*-1ms延时函数-*/void delay(uint n) uint i,j。 for(i=n。i0。i-) for(j=114。j0。j-)。/*-LCD1602写指令函数-*/void LCD1602_write_(uchar ) rs=0。/rs=0,置指令输入状态 P0=。/输出指令码 delay(1)。/延时1ms lcden=1。/lcden=1,使能端
5、有效 delay(1)。/延时1ms lcden=0。/lcden=0,使能端无效/*-LCD1602写数据函数-*/void LCD1602_write_dat(uchar dat) rs=1。/rs=1,置数据输入状态 P0=dat。 /输出待显示字符的字符码(ASCII码 delay(1)。/延时1ms lcden=1。/lcden=1,使能端有效 delay(1)。/延时1ms lcden=0。/lcden=0,使能端无效 /*公历平年的2月只有28天,公历闰年的2月有29天。判断公历闰年的算法:、普通年能被4整除且不能被100整除的为闰年。如:2011年不是闰年,2012年是闰年.2
6、100年也不是闰年。、世纪年能被400整除的是闰年。如:2000年是闰年,1900年不是闰年。*/void leapyear() /判断某年是否闰年函数 if (year%400=0) | (year%100!=0) & (year%4=0) month_day1=29。/闰年2月29天 else month_day1=28。/平年2月28天 /*由年、月、日计算星期的算法基姆拉尔森计算公式: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7公式中d表示日期中的日数,m表示月份数,y表示年数。注意:计算时要将一月和二月看成是上一年的十三月和十四月。例:2
7、012-1-10需要换算成2011-13-10来代入公式计算。*/uchar CaculateWeek(int y,char m, char d)/由年、月、日计算星期函数 uchar w。 if(m=1)m=13。y=y-1。 else if(m=2)m=14。y=y-1。 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7。 return w。/*定时计数器中断程序,每当定时计数器溢出时触发中断,执行该程序*/void time0() interrupt 1 TH0=(65536-50000)/256。/重装初值TL0=(65536-50000)%256。 if
8、(temp=19)/为了加快仿真速度,将temp设为1,实际应为20 temp=0。 if(second=59)/为了加快仿真速度,将second设为2,实际应为59 second=0。 if(minute=59)/为了加快仿真速度,将minute设为2,实际应为59 minute=0。 if(hour=23)/为了加快仿真速度,将hour设为2,实际应为23 hour=0。 leapyear()。/闰、平年计算 if(day=month_daymonth-1)/判断日期是否到了每月最后一天 day=1。 if(month=12) month=1。 year+。 else month+。 el
9、se day+。 else hour+。 else minute+。 else second+。 else temp+。 week=CaculateWeek(year,month,day)。/根据年月日计算星期void int0() interrupt 0/外部中断函数,当按下setup键时产生外部中断进入调整状态 bit flag。 uchar setup_bit=0。/setup_bit用于计数移位次数 do/循环 if(shift_key=0)/判断移位键是否按下 delay(1)。/延时消抖 if(shift_key=0)/确认移位键是否按下 while(!shift_key)。/等待
10、移位键释放 if(setup_bit=10)/共10位 setup_bit=0。 /移位计数值返回0 LCD1602_write_(0x0c)。/关闭光标显示 goto rep。/转移到中断程序完毕处 else setup_bit+。/移位计数值加1 LCD1602_write_(0x0e)。/翻开光标显示 switch(setup_bit)/判断调整哪位,从而确定光标显示位置 case 1: LCD1602_write_(0x80+0x44+4)。/光标设置到分个位显示位置 break。 case 2: LCD1602_write_(0x80+0x44+3)。/光标设置到分十位显示位置 br
11、eak。 case 3: LCD1602_write_(0x80+0x44+1)。/光标设置到时个位显示位置 break。 case 4: LCD1602_write_(0x80+0x44+0)。/光标设置到时十位显示位置 break。 case 5: LCD1602_write_(0x80+0x01+9)。/光标设置到日个位显示位置 break。 case 6: LCD1602_write_(0x80+0x01+8)。/光标设置到日十位显示位置 break。 case 7: LCD1602_write_(0x80+0x01+6)。/光标设置到月个位显示位置 break。 case 8: LC
12、D1602_write_(0x80+0x01+5)。/光标设置到月十位显示位置 break。 case 9: LCD1602_write_(0x80+0x01+3)。/光标设置到年个位显示位置 break。 case 10: LCD1602_write_(0x80+0x01+2)。/光标设置到年十位显示位置 break。 default: break。 if(up_key=0)/判断增加键是否按下delay(1)。/延时消抖 if(up_key=0)/确认增加键是否按下while(!up_key)。/等待增加键释放 flag=1。/增加键已按动 else flag=0。/增加键未按动 else
13、 flag=0。/增加键未按动 if(flag)/假设增加键按动 switch(setup_bit)/判断是哪位,从而调整哪位 case 1: if(minute%10=9)/假设分个位为9 minute=minute-9。/那么分个位清零 else minute+。/否那么分个位加1 LCD1602_write_dat(0x30+minute%10)。/写入1602 break。 case 2: if(minute/10=5)/假设分十位为5 minute=minute-50。/那么分十位清零 else minute=minute+10。/否那么分十位加1 LCD1602_write_dat
14、(0x30+minute/10)。/写入1602 break。 case 3: if(hour%10=9) hour=hour-9。 else hour+。 LCD1602_write_dat(0x30+hour%10)。/写入1602 break。 case 4: if(hour/10=2) hour=hour-20。 else hour=hour+10。 LCD1602_write_dat(0x30+hour/10)。/写入1602 break。 case 5: if(day%10=9) day=day-9。 else day+。 LCD1602_write_dat(0x30+day%10
15、)。/写入1602 break。 case 6: if(day/10=3) day=day-30。 else day=day+10。 LCD1602_write_dat(0x30+day/10)。/写入1602 break。 case 7: if(month%10=9) month=month-9。 else month+。 LCD1602_write_dat(0x30+month%10)。/写入1602 break。 case 8: if(month/10=1) month=month-10。 else month=month+10。 LCD1602_write_dat(0x30+month
16、/10)。/写入1602 break。 case 9: if(year%10=9) year=year-9。 else year+。 LCD1602_write_dat(0x30+year%10)。/写入1602 break。 case 10: if(year%100/10=9) year=year-90。 else year=year+10。 LCD1602_write_dat(0x30+year%100/10)。/写入1602 break。 default: break。 while(setup_bit!=0)。/假设所有位未调整完那么返回,否那么退出调整模式 rep:。/*-LCD160
17、2初始化函数-*/void LCD1602_init() LCD1602_write_(0x38)。 /设置液晶显示方式:16x2行,5x7点阵,8位数据总线 LCD1602_write_(0x0c)。 /设置字符显示开关及光标显示模式:开启字符显示,不显示光标 LCD1602_write_(0x06)。 /设置数据指针及显示屏移动模式:数据指针增(即光标右移,显示屏不移 LCD1602_write_(0x01)。 /液晶屏幕清屏/*-主函数-*/void main() init()。/定时计数器T0及中断初始化 LCD1602_init()。/LCD1602初始化 while(1) ucha
18、r i。 LCD1602_write_(0x80+0x01)。 /设置第1行显示首地址01 LCD1602_write_dat(0x30+year/1000)。/输出年千位的字符码 LCD1602_write_dat(0x30+(year%1000)/100)。/输出年百位的字符码 LCD1602_write_dat(0x30+(year%100)/10)。/输出年十位的字符码 LCD1602_write_dat(0x30+year%10)。/输出年个位的字符码 LCD1602_write_dat(-)。/输出-字符码 LCD1602_write_dat(0x30+month/10)。/输出月
19、十位的字符码 LCD1602_write_dat(0x30+month%10)。/输出月个位的字符码 LCD1602_write_dat(-)。/输出-字符码 LCD1602_write_dat(0x30+day/10)。/输出日十位的字符码 LCD1602_write_dat(0x30+day%10)。/输出日个位的字符码 LCD1602_write_dat()。/输出(字符码 for (i=0。i3。i+) LCD1602_write_dat(week_stringweeki)。/输出星期英文缩写字符码 LCD1602_write_dat()。/输出)字符码 LCD1602_write_(
20、0x80+0x40+0x04)。 /设置第2行显示首地址04 LCD1602_write_dat(0x30+hour/10)。/输出小时十位的字符码 LCD1602_write_dat(0x30+hour%10)。/输出小时个位的字符码 LCD1602_write_dat(:)。/输出:字符码 LCD1602_write_dat(0x30+minute/10)。/输出分十位的字符码 LCD1602_write_dat(0x30+minute%10)。/输出分个位的字符码 LCD1602_write_dat(:)。/输出:字符码 LCD1602_write_dat(0x30+second/10)。/输出秒十位的字符码 LCD1602_write_dat(0x30+second%10)。/输出秒个位的字符码 网友评论评论内容最多输入2000个字符李文 2011-6-1 20:44:14发表程序很详细,下来参考一下。支持0 反对0 X俊落新账号 2011-5-31 21:12:24发表我也把它悄悄偷走支持0 反对0 孟洋 2011-5-30 17:27:25发表好东西,我下借用了支持0 反对0 1 正在提交,请等待. 关于我们成长大事记工作时机合作通道联系我们声明所有-世界大学城. .word.zl.