《嵌入式系统》综合实验报告实验内容基于uC/OS-II的时钟设计系自动控制专业自动化班级学号学生姓名指导教师2011年05月25日基于uC/OS-II的时钟设计一.实验要求1.按正常逻辑显示“年-月-日”,“时:分:秒”,其中分与秒间“:”每0.5秒闪烁1次。2.可利用键盘的上,下,左,右键进行日期,时间设置;按“ESC”退出程序;3.可利用键盘的上,下键进行走时快慢调整,以便检验走时逻辑[可选功能];4.功能的实现过程中,必须体现所学的uC/OS-II相关知识,信号量、互斥量、消息邮箱、消息队列必须用到;5.独立完成,正常演示结果,且正确回答老师抽查问题。二.实验设计思想1、划分了6个任务,分别为year、month、day、hour、min、sec,建立了2个信号量semsec、semhalfsec。2、dis1Num(charx,chary,charnum)表示在界面(x,y)坐标上显示一位数,dis2Num(charx,chary,charnum)表示两位数组成一个时间块。3、用方向键定义了4个key,left、right可以进行年月日时分秒的切换,up、down可以对每一项的数值的加减。4、每过一个信号量semsec,时间加1秒,OSSemPend(semHalfSec,0,&err)调用semhalfsec实现两个点亮半秒、暗半秒的闪烁功能。OSMboxPost(mboxPosNumMode,&dateTime)调用semhalfsec实现被选中的任务时间块的闪烁。5、通过key实现任务之间的调度,left和right方向键对时间块的选择用到了互斥量。6、OSMboxPost(mboxPosNumMode,&dateTime)把dateTime的地址发送给mboxPosNumMode。7、。“消息队列”是在消息的传输过程中保存消息的容器。三.具体程序实现实验结果代码/************************************************************************************************uC/OS-II*TheReal-TimeKernel**description:移植uC/OS-II(2.51Kernal)在VisualC++Complier运行。*date:2006.10.19*changeby:HCF***********************************************************************************************版本历史*10_19:1.0版本------------------------------------------------------------------------------------------------*目前发现的问题:*任务堆栈只能设置成2048(OS_STK)大小------------------------------------------------------------------------------------------------*/#includeincludes.h#includestdlib.h/************************************************************************************************CONSTANTS***********************************************************************************************/#defineTASK_STK_SIZE2048//任务堆栈长度,只能设置为2048!!!!!/************************************************************************************************必须定义以下任务堆栈空间使用,作为创建优先级别为0的TaskStart()任务的任务堆栈***********************************************************************************************/OS_STKTASKSTARTSTK[10*TASK_STK_SIZE];//TaskStart的任务堆栈空间OS_STKtaskTimeTickStk[TASK_STK_SIZE];OS_STKtaskTimeRefreshStk[TASK_STK_SIZE];OS_STKtaskShow2DotStk[TASK_STK_SIZE];OS_STKtaskDispDateTimeStk[TASK_STK_SIZE];OS_STKtaskdispDateTimeOptStk[TASK_STK_SIZE];OS_STKtaskKeyDealStk[TASK_STK_SIZE];INT8Ux=0,y=0;//字符显示位置chardateTime[7]={11,5,18,10,30,12,0};HANDLEmainhandle;//主线程句柄CONTEXTContext;//主线程切换上下文BOOLEANFlagEn=1;//增加一个全局变量,做为是否时钟调度的标志OS_EVENT*semSec;OS_EVENT*semHalfSec;OS_EVENT*mutexDis;OS_EVENT*mboxDateTime;OS_EVENT*mboxPosNumMode;OS_EVENT*qKey;void*keyQTbl[110];/************************************************************************************************FUNCTIONPROTOTYPES***********************************************************************************************/voidVCInit(void);//初始化相关变量,一定需要voidTaskStart(void*pParam);voidtaskShow2Dot(void*pdata);voidtaskTimeTick(void*pdata);voidtaskTimeRefresh(void*pdata);voidtaskDispDateTime(void*pdata);voidtaskdispDateTimeOpt(void*pdata);voidtaskKeyDeal(void*pdata);/************************************************************************************************函数名:main(intargc,char**argv)*函数功能:*入口参数:*返回参数:***********************************************************************************************/voidmain(intargc,char**argv){VCInit();//初始化一些变量,编译器相关OSInit();//初始化uCOS_II//必须创建以下这个任务,作为设置uCOS_II时钟频率使用,与MyTask()中的这两行代码等效OSTaskCreate(TaskStart,0,&TASKSTARTSTK[10*TASK_STK_SIZE-1],0);//必须使用OSStart();//启动uCOS_II的多任务管理}/************************************************************************************************函数名:VCInit()*函数功能:编译器初始化,VC环境下一定需要*入口参数:无*返回参数:无***********************************************************************************************/voidVCInit(void){HANDLEcp,ct;Context.ContextFlags=CONTEXT_CONTROL;cp=GetCurrentProcess();//得到当前进程句柄ct=GetCurrentThread();//得到当前线程伪句柄DuplicateHandle(cp,ct,cp,&mainhandle,0,TRUE,2);//伪句柄转换,得到线程真句柄}/************************************************************************************************函数名:Task_start()*函数功能:启动统计任务(只创建,不做参与任务调度),该任务创建,作为设置uCOS_II时钟频率使用,*与MyTask()中的这两行代码等效:*PC_VectSet(0x08,OSTickISR);//安装uCOS_II时钟中断向量*PC_SetTickRate(OS_TICKS_PER_SEC);//设置uCOS_II时钟频率*入口参数:*返回参数:无***********************************************************************************************/voidTaskStart(void*pParam){INT16Skey;//用于退出uCOS_II的键charkey8;timeSetEvent(1000/OS_TICKS_PER_SEC,0,OSTickISR,0,TIME_PERIODIC);//开启一个定时器线程,感觉10ticks/s比较好OSStatInit();semSec=OSSemCreate(0);semHalfSec=OSSemCreate(0);mboxDateTime=OSMboxCreate(0);mboxPosNumMode=OSMboxCreate(0);qKey=OSQCreate(keyQTbl,100);OSTaskCreate(taskTimeTick,0,&taskTimeTickStk[TASK_STK_SIZE-1],20);//使任务MyTask的优先级别为1OSTaskCreate(taskKeyDeal,0,&taskKeyDealStk[TASK_STK_SIZE-1],21);OSTaskCreate(taskdispDateTimeOpt,0,&taskdispDateTimeOptStk[TASK_STK_SIZE-1],22);OSTaskCreate(taskShow2Dot,0,&taskShow2DotStk[TASK_STK_SIZE-1],30);//使任务MyTask的优先级别为1OSTaskCreate(taskTimeRefresh,0,&taskTimeRefreshStk[TASK_STK_SIZE-1],40);//使任务MyTask的优先级别为0OSTaskCreate(taskDispDateTime,0,&taskDispDateTimeStk[TASK_STK_SIZE-1],50);//使任务MyTask的优先级别为0//使任务MyTask的优先级别为0while(1){//sle