ARM开发平台上时钟程序设计.docx
- 文档编号:24089669
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:31
- 大小:138.54KB
ARM开发平台上时钟程序设计.docx
《ARM开发平台上时钟程序设计.docx》由会员分享,可在线阅读,更多相关《ARM开发平台上时钟程序设计.docx(31页珍藏版)》请在冰豆网上搜索。
ARM开发平台上时钟程序设计
ARM开发平台上基于
操作系统的时钟程序设计
一、硬件平台和操作系统简介
硬件平台为博创科技提供的基于ARM7的开发平台,带有开发软件ARMSDTv2.51和案例,支持μc/os-Ⅱ操作系统。
ARM已成为移动通信、手持设备、多媒体数字消费嵌入式解决方案的RISC标准。
ARM处理器具有三大特点:
1、小体积、低功耗、低成本而高性能。
2、16/32位双之指令集。
3、全球众多的合作伙伴。
μc/os-Ⅱ是uc/os的升级版本,也是目前被广泛使用的版本。
μc/os-Ⅱ源代码具有以下一些特点:
1、源代码完全公开的;
2、可移植性好,μc/os-Ⅱ绝大部分源代码是用ANSIC写的。
3、可固化,μc/os-Ⅱ可以嵌入到开发者的产品中,成为产品的一部分。
4、可裁剪,可以只使用μc/os-Ⅱ中应用程序需要的那些系统服务。
5、抢占式内核,μc/os-Ⅱ总是运行就绪条件下优先级最高的任务。
6、多任务,μc/os-Ⅱ可以管理64个任务,其中保留8个任务给系统,应用程序最多可以有56个任务。
二、软件设计
结合上面介绍的硬件平台和操作系统,设计实现了时钟程序。
时钟程序的设计分成界面设计和功能设计两个部分来介绍。
1、界面设计
在ARM开发平台基于
操作系统设计实现一个时钟,带有模拟表盘与数字显示,支持键盘设置,并带闹钟功能。
液晶屏尺寸为320*240,液晶屏显示界面包括圆形表盘,数字时钟、日期和闹钟显示。
图1是时钟程序的图形界面。
图1时钟程序的图形界面
2、功能设计
参考博创科技公司提供的示例程Exp19,采用多任务设计。
除了系统已定义的任务外,再定义了Main_Task和Rtc_Disp_Task两个任务,任务优先级分别为12和14。
通过Main_Task任务中响应键盘消息,可以对时钟和闹钟进行设置。
通过Rtc_Disp_Task实现系统时钟的显示和更新,并判断闹钟时间是否到达并做到达后的相应处理。
使用
多任务系统中的信号量保证多个任务同时对系统的一个资源(系统时钟)访问而不产生冲突。
编程采用
系统的API函数,可以对液晶屏的显示,操作系统消息,文本框控件,系统时间,字符串,系统图形等进行设计制作。
(1)Main_Task任务设计
Main_Task负责时钟界面初始化和键盘消息处理。
时钟界面初始化包括清屏、画表盘、生成文本框和时钟控制信号量。
键盘信息处理包括闹钟设定和时钟设定。
Main_Task的程序流程图如图2所示。
图2Main_Task任务的程序流程图
(2)Rtc_Disp_Task任务设计
Rtc_Disp_Task实现系统时钟的显示和更新,并判断闹钟时间是否到达以及到达后相应的处理。
Rtc_Disp_Task的流程图如图3所示。
(3)几处关键部分的实现
①表盘绘制函数jiemian
圆形表盘的实现先画一个圆,对圆12等分获得分针刻度,60等分获得表针刻度。
使用sin和cos获得坐标值,利用API函数MoveTo和LineTo画出刻度。
值得注意的是屏幕坐标和自然坐标不同,所以在计算坐标的采用下图的计算方式。
x
y
θ
②时间设定函数SetSystemTime
首先从文本框中取出时间,把时间从字符型转化为整型,最后用Set_Rtc_Date和Set_Rtc_Clock把整型时间设置为系统时间。
③选择文本框
利用键盘上的“*”按键做为功能键,利用SetWndCtrlFocus实现文本框间的焦点切换。
文本框焦点的作用是:
获得焦点的文本框才有资格获得键盘的输入消息。
部分代码如下:
case2:
//“*”按键
if(funckey==FALSE)
{
SetWndCtrlFocus(NULL,ID_MainTextCtrl);//焦点移到文本框中
funckey=TRUE;
}
else
{
SetWndCtrlFocus(NULL,ID_MainTextCtrlAlarm);//焦点移到文本框中
funckey=FALSE;
}
④表盘指针的更新
表盘的更新实际上只更新指针部分,避免复杂的画图,节省系统资源。
具体的实现是每次更新的时候,绘制“前一秒”和“当前秒”两套(时、分、秒)指针,“前一秒”这套指针用背景色(白色)绘制,“当前秒”这套指针用前景色绘制。
⑤闹钟功能
本设计用一个文本框来模拟闹钟。
先设置闹钟时间并开启闹钟,在Rtc_Disp_Task判断当前系统时间达到闹钟设置的时间,如果是闹钟相应——闹钟文本框内容变为AlarmOn!
如果当前的系统时间超过闹钟设置的时间一分钟以上,关闭闹钟——闹钟文本框内容变为AlarmOff。
三、附录(本文开发的程序程序)
#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
///******************任务定义***************///
OS_STKMain_Stack[STACKSIZE*8]={0,};//Main_Test_Task堆栈
voidMain_Task(void*Id);//Main_Test_Task
#defineMain_Task_Prio12
#definePI3.1415926
intcha;
/**************已经定义的OS任务*************
tcp监控任务11
以太网物理层监控任务8
触摸屏任务9
键盘任务10
lcd刷新任务59
系统任务1
*****************************************************/
///*****************事件定义*****************///
OS_EVENT*Nand_Rw_Sem;//Nand_Flash读写控制权旗语
//andyoucanuseitasfolloeing:
//Nand_Rw_Sem=OSSemCreate
(1);//创建Nand-Flash读写控制权旗语,初值为1满足互斥条件//
//OSSemPend(Nand_Rw_Sem,0,&err);
//OSSemPost(Nand_Rw_Sem);
OS_EVENT*Uart_Rw_Sem;//Uart读写控制权旗语
//andyoucanuseitasfolloeing:
//Uart_Rw_Sem=OSSemCreate
(1);//创建Uart读写控制权旗语,初值为1满足互斥条件//
//OSSemPend(Uart_Rw_Sem,0,&err);
//OSSemPost(Uart_Rw_Sem);
//////////////////////////////////////////////////////////
voidinitOSGUI()//初始化操作系统的图形界面
{
initOSMessage();
initOSList();
initOSDC();
initOSCtrl();
initOSFile();
//InitRtc();//,目的初始化系统时钟
}
voidjiemian()
{
PDCpdc;
//pdc=CreateDC();
inti,x1,x2,y1,y2,oldx,oldy,m,n;
m=240;n=120;
pdc=CreateDC();
SetDrawOrg(pdc,m,n,&oldx,&oldy);
for(i=0;i<=60;i++)
{
x1=50*cos(PI/30*i);
y1=50*sin(PI/30*i);
x2=45*cos(PI/30*i);
y2=45*sin(PI/30*i);
MoveTo(pdc,x2,y2);
LineTo(pdc,x1,y1);
//OSTimeDly(10);
}
for(i=0;i<=12;i++)
{
x1=50*cos(PI/6*i);
y1=50*sin(PI/6*i);
x2=40*cos(PI/6*i);
y2=40*sin(PI/6*i);
MoveTo(pdc,x2,y2);
LineTo(pdc,x1,y1);
//OSTimeDly(10);
}
/*##########画3##########*/
/*MoveTo(pdc,36,-4);
LineTo(pdc,40,-4);
LineTo(pdc,40,4);
LineTo(pdc,36,4);
MoveTo(pdc,36,0);
LineTo(pdc,40,0);*/
MoveTo(pdc,35,-4);
LineTo(pdc,39,-4);
LineTo(pdc,39,4);
LineTo(pdc,35,4);
MoveTo(pdc,35,0);
LineTo(pdc,39,0);
/*#########画6##########*/
MoveTo(pdc,2,31);
LineTo(pdc,-2,31);
LineTo(pdc,-2,39);
LineTo(pdc,2,39);
LineTo(pdc,2,35);
LineTo(pdc,-2,35);
/*##########画9##########*/
MoveTo(pdc,-35,0);
LineTo(pdc,-39,0);
LineTo(pdc,-39,-4);
LineTo(pdc,-35,-4);
LineTo(pdc,-35,4);
LineTo(pdc,-39,4);
/*##########画12##########*/
MoveTo(pdc,-2,-39);
LineTo(pdc,-2,-31);
MoveTo(pdc,-1,-39);
LineTo(pdc,2,-39);
LineTo(pdc,2,-35);
LineTo(pdc,-1,-35);
LineTo(pdc,-1,-31);
LineTo(pdc,2,-31);
DestoryDC(pdc);
}
/////////////////////////////////////////////////////
/*voidxianshi()
{
inttime_s,oldx,oldy,timex,timey;
PstructTimetime;
PDCpdc;
pdc=CreateDC();
SetDrawOrg(pdc,240,120,&oldx,&oldy);
//time=Unicode2Int(strtimeh);
//InitRtc();
//Get_Rtc(time);
time_s=(time->second);
MoveTo(pdc,0,0);
timey=35*sin(PI/30*time_s);
timex=35*cos(PI/30*time_s);
LineTo(pdc,timex,timey);
}*/
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;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PTextCtrlpTextCtrl;//文本框结构
#defineID_MainTextCtrl101//文本框ID
PTextCtrlpTextCtrlStatic;//文本框结构
#defineID_MainTextCtrlStatic102//文本框ID
PTextCtrlpTextCtrlAlarm;//文本框结构
#defineID_MainTextCtrlAlarm103//文本框ID
PTextCtrlpTextCtrlAlarmStatic;//文本框结构
#defineID_MainTextCtrlAlarmStatic104//文本框ID
staticU8AlarmIsOn=FALSE;//闹钟开启标志
U8SetSysTime()
{
U16*ptext=pTextCtrl->text;//得到文本框文本指针
//U32tmp[3],i;
U32tmp[6],i;
structClockclock;
structDatedate;
for(i=0;i<6;i++){//从文本中分离出时间,bcd码
tmp[i]=0;
while(*ptext&&*ptext!
=':
'&&*ptext!
='/'){
tmp[i]<<=4;
tmp[i]|=(*ptext)-'0';
ptext++;
}
ptext++;
}
date.year=tmp[0];
date.month=tmp[1];
date.day=tmp[2];
clock.hour=tmp[3];
clock.minute=tmp[4];
clock.second=tmp[5];
if((date.year>0)&&(date.month>0&&date.month<=0x12)&&(date.day>0&&date.day<=0x31))
Set_Rtc_Date(&date);
//else
//returnFALSE;
/**********************0x->dec*****************************/
if((clock.hour<=0x24&&clock.hour>=0)&&
(clock.minute>=0&&clock.minute<=0x60)&&
(clock.second>=0&&clock.second<=0x60))//小时在0~24,分和秒在0~60
{
//Set_Rtc_Date(&date);
Set_Rtc_Clock(&clock);//设置时间
returnTRUE;
}
else
{
returnFALSE;
}
}
/*#################################
增加闹钟设置函数
###############################*/
U8SetAlarm()
{
U16*ptext=pTextCtrlAlarm->text;//得到文本框文本指针
U32tmp[3],i;
//pTextCtrlAlarm->text[0]=0;//清空文本框
//SetTextCtrlEdit(pTextCtrlAlarm,TRUE);
for(i=0;i<3;i++){//从文本中分离出时间,bcd码
tmp[i]=0;
while(*ptext&&*ptext!
=':
'){
tmp[i]<<=4;
tmp[i]|=(*ptext)-'0';
ptext++;
}
ptext++;
}
if((tmp[0]<=0x24&&tmp[0]>=0)&&(tmp[1]>=0&&tmp[1]<=0x60)&&(tmp[2]>=0&&tmp[2]<=0x60)){//小时在0~24,分和秒在0~60
//AlarmIsOn=TURE;
returnTRUE;
}
else{
//AlarmIsOn=FALSE;
returnFALSE;
}
}
voidCreateText()
{
staticcharTimeKeyTable[]={0,'/','*','\b','7','8','9',0,'4','5','6','1','2','3',0,'0',':
'};//键值映射表
structRECTrect;//定义矩形结构
inti=0;
U16str[20];
charalarminformation[]="off";//数据溢出信息
charAlarmtext[]="Alarm";
charTimetext[]="Time";
SetRect(&rect,160,210,300,230);//设置文本框
//jiemian();
pTextCtrl=CreateTextCtrl(ID_MainTextCtrl,&rect,FONTSIZE_MIDDLE,CTRL_STYLE_FRAME,TimeKeyTable,NULL);//创建文本框
//SetWndCtrlFocus(NULL,ID_MainTextCtrl);//焦点移到文本框中
DrawTextCtrl(pTextCtrl);//重绘文本框
SetRect(&rect,120,210,155,230);//设置文本框
pTextCtrlStatic=CreateTextCtrl(ID_MainTextCtrlStatic,&rect,FONTSIZE_MIDDLE,CTRL_STYLE_FRAME,TimeKeyTable,NULL);//创建文本框
//DrawTextCtrl(pTextCtrlStatic);//重绘文本框
strChar2Unicode(pTextCtrlStatic->text,Timetext);//数据溢出信息转换成unicode
DrawTextCtrl(pTextCtrlStatic);//重绘文本框控件
pTextCtrlStatic->text[0]=0;//清空文本框
SetRect(&rect,45,210,115,230);//设置文本框
pTextCtrlAlarm=CreateTextCtrl(ID_MainTextCtrlAlarm,&rect,FONTSIZE_MIDDLE,CTRL_STYLE_FRAME,TimeKeyTable,NULL);//创建文本框
//DrawTextCtrl(pTextCtrlAlarm);//重绘文本框
strChar2Unicode(pTextCtrlAlarm->text,alarminformation);//数据溢出信息转换成unicode
DrawTextCtrl(pTextCtrlAlarm);//重绘文本框控件
pTextCtrlAlarm->text[0]=0;//清空文本框
SetRect(&rect,5,210,40,230);//设置文本框
pTextCtrlAlarmStatic=CreateTextCtrl(ID_MainTextCtrlAlarmStatic,&rect,FONTSIZE_MIDDLE,CTRL_STYLE_FRAME,TimeKeyTable,NULL);//创建文本框
//DrawTextCtrl(pTextCtrlAlarmStatic);//重绘文本框
strChar2Unicode(pTextCtrlAlarmStatic->text,Alarmtext);//数据溢出信息转换成unicode
DrawTextCtrl(pTextCtrlAlarmStatic);//重绘文本框控件
pTextCtrlAlarmStatic->text[0]=0;//清空文本框
}
U8onKey(intnkey,intfnkey);
OS_EVENT*Rtc_Updata_Sem;//时钟更新控制权
OS_STKRtc_Disp_Stack[STACKSIZE]={0,};//Rtc_Disp_Task堆栈
voidRtc_Disp_Task(void*Id);//Rtc_Disp_Task
#defineRtc_Disp_Task_Prio14
voidMain_Task(void*Id)//Main_Test_Task
{
POSMSGpMsg=0;//消息结构
ClearScreen();//清屏
jiemian();//朱建清反注释
//xianshi();//添加
CreateText();//创建文本框
Rtc_Updata_Sem=OSSemCreate
(1);/*通知uc/os-II在某一时刻只有一个任务可以使用文本框资源*/
OSTaskCreate(Rtc_Disp_Task,(void*)0,
(OS_S
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARM 开发 平台 时钟 程序设计