电子日历钟的设计不错的.docx
- 文档编号:29827710
- 上传时间:2023-07-27
- 格式:DOCX
- 页数:62
- 大小:77.72KB
电子日历钟的设计不错的.docx
《电子日历钟的设计不错的.docx》由会员分享,可在线阅读,更多相关《电子日历钟的设计不错的.docx(62页珍藏版)》请在冰豆网上搜索。
电子日历钟的设计不错的
研究生课程论文
电子日历钟设计
课程名称嵌入式系统设计
姓名张丽红
学号0900201045
专业信号与信息处理
任课教师王佳斌
开课时间2010年
教师评阅意见:
论文成绩
评阅日期
课程论文提交时间:
2010年8月5日
电子日历钟设计
【摘要】:
本文介绍了基于UP-NETARM3000嵌入式开发平台的日历/时钟设计,能同时显示年、月、日、时、分、秒和星期,年、月、日、星期自动转换,有闹钟定时功能。
该日历/时钟走时准确,调校方便。
液晶屏显示界面包括圆形表盘,电子时钟、日历和闹钟显示,触摸式功能与数字按钮,液晶屏尺寸为320*240。
【关键词】:
时钟,日历,星期,闹钟
一、系统的设计方案
根据设计要求,在ARM开发平台设计实现电子日历钟设计,带有模拟表盘与数字显示,支持键盘和触摸屏设置和月历,并带有闹钟功能等。
采用多任务设计,除了系统已经定义的任务外,定义时钟更新,时钟显示任务(包括闹钟),同时,通过在Main_Task任务中响应键盘消息,可以对系统的时钟进行设置更新。
并且使用uc/os-Ⅱ多任务系统中的信号量保证多个任务同时对系统的一个资源(系统时钟)访问而不产生冲突。
系统编程采用API函数,可以对液晶屏的显示,操作系统消息,控件(按钮,文本框),系统时间,字符串,系统图形等进行设计制作。
1、系统图形界面设计
液晶屏显示界面包括圆形表盘,电子时钟、日历和闹钟显示,触摸式功能与数字按钮,液晶屏尺寸为320*240,综合设计如下图1-1所示:
图1-1电子时钟界面设计图
触摸式按钮为功能设置,相应功能可从健名理解。
上移、下移:
用于日期和时间文本框的选择;
修改:
用于日期和时间文本框的编辑修改与修改后的确认;
闹设:
用于闹钟文本框的编辑即闹钟重新设置和设置后的确认。
闹消:
用于闹钟文本框取消及相应现象的取消
闹消:
用于将闹钟文本框ID转向日期文本框ID,从而可进一步重新设置各个文本框。
数字按钮键:
共12个,相应数字的输入,其中DELETE用于当字符输入错误时可删除最后一个字符。
2、电子钟
Get_Rtc(&tmptime);//////////模拟表盘显示tmptime.hour=((int)(tmptime.hour&0x000f)+10*(int)((tmptime.hour>>4)&0x000f));tmptime.minute=((int)(tmptime.minute&0x000f)+10*(int)((tmptime.minute>>4)&0x000f));
tmptime.second=((int)(tmptime.second&0x000f)+10*(int)((tmptime.second>>4)&0x000f));
………
SetPenWidth(pdc,1);
MoveTo(pdc,0.8*r*sin(2*3.14*tmptime.second/60),-0.8*r*cos(2*3.14*tmptime.second/60));
SetPenColor(pdc,0xd20000);
LineTo(pdc,0,0);
屏幕上的电子钟3条表针分别为时、分、秒对应,能够实时更新,每走一秒就跟着变,其中时针是用短线粗4来画的,分针是用较长线粗3来画的,秒针是用长线粗1画的。
能实现实时更新的原因是通过获得取当前时间的指针来进行时分秒与零点(12点)的数学关系,分别求出时针,分针,秒针的屏幕坐标,然后利用画线功能的函数来实现,表针走动的同时显示当前时间。
3、表盘
for(i1=0;i1<60;i1++)
{if(i1%5==0)SetPenWidth(pdc,3);
elseSetPenWidth(pdc,1);
MoveTo(pdc,r*sin(2*3.14*i1/60),-r*cos(2*3.14*i1/60));
LineTo(pdc,0.9*r*sin(2*3.14*i1/60),-0.9*r*cos(2*3.14*i1/60));}
时钟表盘上有12个整点刻度,相邻两个刻度之间的夹角是30度,用弧度表示是2T/12*i(i为当前时间整点),而每一时刻的像素点横坐标恰好是对应夹角与半径的正弦值。
列坐标等于对应夹角与半径的余弦值。
利用这个数学关系依次类推,我们就可以轻易地求出当前点像素坐标,然后利用画正方形,画点或画圆等命令画出各种表盘刻度。
本程序用画12个线(线粗为3)为表盘的整点刻度,其他的刻度用线粗为1来画线。
4、表针显示和走动的原理
Get_Rtc(&tmptime);//////////模拟表盘显示tmptime.hour=((int)(tmptime.hour&0x000f)+10*(int)((tmptime.hour>>4)&0x000f));tmptime.minute=((int)(tmptime.minute&0x000f)+10*(int)((tmptime.minute>>4)&0x000f));
tmptime.second=((int)(tmptime.second&0x000f)+10*(int)((tmptime.second>>4)&0x000f));
………
SetPenWidth(pdc,1);
MoveTo(pdc,0.8*r*sin(2*3.14*tmptime.second/60),-0.8*r*cos(2*3.14*tmptime.second/60));
SetPenColor(pdc,0xd20000);
LineTo(pdc,0,0);
通过函数取得时钟当前时间结构体指针,然后分离出时、分、秒的指针,再利用当前时间(时,分,秒)相对于零点(12点)的数学关系,分别求出时针,分针,秒针图形长度的终点像素坐标,再用不同颜色通过画线命令以表盘原点为起点分别画出时针,分针,秒针,这样即可在屏幕上显示当前时间,这些均在voidMy_Clock_Task(void*Id)这个任务中完成的。
按钟表走动的原理,设计秒针每隔一秒走动一次,当秒针走完60秒,也就是秒数为零时,分针走动一分,当分针每走5分钟或10分钟的同时,时针走动一下,如此循环就完成了表针的走动操作,实际编程时,先取得秒数,分数,时数,换算成屏幕像数点坐标,再用画线命令显示秒针,分针及时针,显示表针图形走动的同时,还要考虑表针走动后,前一个表针图形不能留在屏幕上,以及表针重合时不能覆盖背景屏幕。
5、万年历
万年历的算法中 阳历算法,具体算法见函数Void get_solar_day_date(void),这样阳历日历的星期排法就确定了。
表1:
月份 1 2 3 4 5 6 7 8 9 10 11 12
闰年 31 29 31 30 31 30 31 31 30 31 30 31
非闰年 31 28 31 30 31 30 31 31 30 31 30 31
首先取得当前月份,判断是否为1,3,5,7,8,10或12月,是就将当月天数设为31天,否则设置为30天。
然后再处理二月份平闰年问题。
历法上规定能被400整除者或是能被4整除但不能被100整除者即为闰年,如果是闰年,当月天数为29天,否则为28天。
显示当月日历,通过函数取得每月1日是该周的第几日,其中数值1对应日,2~7对应一~六,然后通过两个循环,即当月日历天数循环和每周日期循环,这样就可将当月日历显示在屏幕窗口中。
6、日历实时更新原理
Get_Rtc(&tmptime);
tmptime.year=((int)(tmptime.year&0x000f)+10*(int)((tmptime.year>>4)&0x000f));
tmptime.month=((int)(tmptime.month&0x000f)+10*(int)((tmptime.month>>4)&0x000f));
tmptime.day=((int)(tmptime.day&0x000f)+10*(int)((tmptime.day>>4)&0x000f));
gc_solar_calendar_year=tmptime.year+2000;
gc_solar_calendar_month=tmptime.month;
get_solar_day_date();//****获取本月的天数和本月第一天的星期几,还有本年的总天数
通过函数取得时钟当前日期结构体指针(这可以实现实时更新功能),然后分离出年、月、日的指针,再利用年、月去算出某阳历年阳历月的第一天是星期几和这个月的天数,再在voidMy_Clock_Task(void*Id)这个任务中写日历的显示及当天的特别标注(格子用灰色填充)。
7、日期、时间、闹钟的设置
当日期、时间设置完成后必须有这句OSSemPost(Rtc_Updata_Sem);//发送信号?
,才能将当前所设置的传送给系统,从而实现系统的日期和时间的变化。
而闹钟则不用,只需判断它是否输入正确。
程序中有设置“闹转”按钮目的是为了焦点移到设置时间文本框控件中,从而可以进行其他设置操作,写法类似于“上移”、“下移”按钮。
8、闹钟到时的现象
当闹钟到时开发板上的LED灯会一直闪烁,直到你把它取消,取消后可再进一步设置闹钟和其他操作。
闹钟响应程序是在voidMy_Clock_Task(void*Id)这个任务中进行判断。
二、操作系统多任务设计:
uc/os-Ⅱ操作系统支持多任务,本设计除了主任务Main_Task外,还创建了时钟更新显示的任务,日历、闹钟、表盘和数字时钟的实时显示任务在My_Clock_Task上完成,而更新显示任务是在Rtc_Disp_Task中完成。
系统主任务完成键盘,触摸屏,LCD刷新等。
本设计建立了两个任务即在Main_Task任务中创建文本框用于在其中显示和设置时钟,通过响应键盘消息设置时钟,每当时间过了一秒,用另一个任务更新时间显示,使用信号分量机制保证多个任务对系统一个资源(文本框)的访问而不产生冲突。
通过系统的消息循环来响应键盘的消息,通常在多任务操作系统中,任务之间的通讯是通过任务之间发送消息来实现的。
在本操作系统的Main_Task任务中,定义了两个消息队列。
将通过使用这两个消息队列接收键盘的按键消息和触摸屏消息。
电子时钟更新任务程:
Rtc_Disp_Task完成系统时钟的日期和时间的更新显示,其程序流程图如下图2-2所示:
图2-2电子时钟更新显示任务程序流程图
表盘时钟任务:
完成表盘指针的走针和日历显示,并进行闹钟功能。
其程序流程图如下图2-3所示:
图2-3日历表盘任务程序流程图
附件:
电子日历时钟源程序:
#include"..\ucos-ii\includes.h"/*uC/OSinterface*/
#include"..\ucos-ii\add\osaddition.h"
#include"..\inc\drv.h"
#include"..\inc\drv\OSFile.h"
#include
#include
#pragmaimport(__use_no_semihosting_swi)//ensurenofunctionsthatusesemihosting
////用于闹钟到时的响应
#include"..\inc\drv\zlg7289.h"
externintZlg7289SIOBand;
externintZlg7289SIOCtrl;
#include"..\inc\drv\tchScr.h"
///******************任务定义***************///
OS_STKMain_Stack[STACKSIZE*8]={0,};//Main_Test_Task堆栈
voidMain_Task(void*Id);//Main_Test_Task
#defineMain_Task_Prio12
///******************任务定义***************///
//系统任务
//实时时钟显示任务
OS_STKRtc_Disp_Stack[STACKSIZE*4]={0,};
voidRtc_Disp_Task(void*Id);
#defineRtc_Disp_Task_Prio14
//时钟任务
OS_STKMy_Clock_Stack[STACKSIZE*4]={0,};
voidMy_Clock_Task(void*Id);
#defineMy_Clock_Task_Prio15
staticU8input=FALSE;//编辑状态标志
INT8Uerr;
charerrinformation[]="dataflow!
";//数据溢出信息
/**************已经定义的OS任务*************
tcp监控任务11
以太网物理层监控任务8
触摸屏任务9
键盘任务10
lcd刷新任务59
系统任务1
*****************************************************/
///*****************事件定义*****************///
OS_EVENT*Nand_Rw_Sem;//Nand_Flash读写控制权旗语
OS_EVENT*Uart_Rw_Sem;//Uart读写控制权旗语
///*****************事件定义*****************///
OS_EVENT*Rtc_Updata_Sem;//时钟更新控制权
OS_EVENT*My_Clock_Sem;//时钟用得好!
!
!
//////////////////////////////////////////////////////////
//说明:
函数get_solar_day_date(void)的输入变量:
gc_solar_calendar_year和
//gc_solar_calendar_month
//输出变量:
start_day_of_week和temp_total_day
//////////////////////////运算某阳历年阳历月的第一天是星期几/////////////////////
staticU32temp_total_day;//返回总天数(公元后)
staticU32temp_total_day1;//本月天数
staticU8gc_solar_calendar_year;//阳历年
staticU8gc_solar_calendar_month;//阳历月
staticU8gc_solar_calendar_date;//阳历日
staticU8start_day_of_week;//本月第一天星期几(0---6)
staticU8calculate_temp;
voidget_solar_day_date(void)
{
unsignedchartemp01;
/*------calculatewhatdayisthedayofthecurrentmonthandyear.Mon~Sun?
---*/
/*条件初始化二次,减少运算数据量.temp_total_day是int型变量*/
start_day_of_week=2;
temp_total_day=0;
calculate_temp=1;
if(gc_solar_calendar_year>99)
{
start_day_of_week=6;calculate_temp=100;
}
for(temp01=calculate_temp;temp01 { if(temp01%4==0&&temp01%100! =0||temp01%400==0) { start_day_of_week+=2; temp_total_day+=366; } else { start_day_of_week+=1; temp_total_day+=365; } if(start_day_of_week>6) start_day_of_week%=7; } for(temp01=1;temp01 { switch(temp01) { case1: case3: case5: case7: case8: case10: case12: start_day_of_week+=3; temp_total_day+=31; break; case2: if(gc_solar_calendar_year%4==0&&gc_solar_calendar_year%100! =0||gc_solar_calendar_year%400==0) { start_day_of_week+=1; temp_total_day+=29; } else { start_day_of_week+=0; temp_total_day+=28; } break; case4: case6: case9: case11: start_day_of_week+=2; temp_total_day+=30; break; } } switch(gc_solar_calendar_month) { case1: case3: case5: case7: case8: case10: case12: temp_total_day1=31; break; case2: if(gc_solar_calendar_year%4==0&&gc_solar_calendar_year%100! =0||gc_solar_calendar_year%400==0) { temp_total_day1=29; } else { temp_total_day1=28; } break; case4: case6: case9: case11: temp_total_day1=30; break; } start_day_of_week%=7; } ////////////////////////////////////////////////////////// //初始化操作系统的图形界面 ////////////////////////////////////////////////////////// voidinitOSGUI()//初始化操作系统的图形界面 { initOSMessage(); initOSList(); initOSDC(); initOSCtrl(); initOSFile(); } ///////////////////////主函数/////////////////////////// intmain(void) { ARMTargetInit();//开发板初始化 OSInit();//操作系统初始化 uHALr_ResetMMU();//复位MMU LCD_Init();//初始化LCD模块 LCD_printf("LCDinitializationisOK\n");//向液晶屏输出数据 LCD_printf("320x240TextMode\n"); initOSGUI();//初始化图形界面 LoadFont();//调Unicode字库 LoadConfigSys();//使用config.sys文件配置系统设置 LCD_printf("CreatetaskonuCOS-II...\n"); OSTaskCreate(Main_Task,(void*)0,(OS_STK*)&Main_Stack[STACKSIZE*8-1],Main_Task_Prio);//创建系统任务 OSAddTask_Init();//创建系统附加任务 LCD_printf("StartinguCOS-II...\n"); LCD_printf("Enteringgraphmode...\n"); LCD_ChangeMode(DspGraMode);//变LCD显示模式为文本模式 InitRtc();//初始化系统时钟 Nand_Rw_Sem=OSSemCreate (1);//创建Nand-Flash读写控制权旗语,初值为1满足互斥条件// OSStart();//操作系统任务调度开始 return0; } ///////////////////////////////////////////////////// //控件ID定义 ///////////////////////////////////////////////////// #defineID_Main1Text300 #defineID_Main2Text301 #defineID_Main3Text302 #defineID_Main4Text303 #defineID_Main5Text304 #defineID_Main6Text305 #defineID_MyMainStatus310 #defineID_MyTimeStatus311 #defineID_Num10Button710 #defineID_Num1Button701 #defineID_Num2Button702 #defineID_Num3Button703 #defineID_Num4Button704 #defineID_Num5Button705 #defineID_Num6Button706 #defineID_Num7Button707 #defineID_Num8Button708 #defineID_Num9Button709 #defineID_Num0Button700 #defineID_Ctrl1Button650 #defineID_Ctrl2Button651 #defineID_Ctrl3Button652 /////////////改动/////////////////// #defineID_Ctrl3_3Button655 #defineID_Num11Button711
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子 日历 设计 不错