最近在学习UCGUI一段时间了,终于成功移植了UCGUI里面的大部分源码,感觉移植代码量还是比较大的,不过倒是GUI_Delay();对于很多菜鸟可能会搞不懂,下面就说一下关于按照原子论坛里的教程成功移植UCGUI3.90后,会发现GUI_Delay();这个函数一调用程序就会卡在这个函数里面,修改一下底层函数,即使没加入操作系统,只移植了UCGUI也可以调用GUI_Delay(); fficeffice" />
解析GUI_Delay()函数:
使用GUI_Delay()函数时,对于其延时时间不确定,明明设置为最小值1,延时时间仍旧太长,不能达到需求。遂决定研究明白其实现机理。
第一使用操作系统uc/os时:
uC/OS-II使用OSTimeDly()函数实现延时,其单位是OS_TICKS,即延时多少个系统节拍。GUI使用GUI_Delay()函数延时,同时也实现显示刷新;基于同一个平台,估计也会调用OSTimeDly()函数以实现基本的延时功能。 下面分析GUI_Delay()函数功能 void GUI_Delay(int eriod) {
int EndTime = GUI_GetTime()+Period; int tRem; /* remaining Time */ GUI_ASSERT_NO_LOCK();
while (tRem = EndTime- GUI_GetTime(), tRem>0) { GUI_Exec();
GUI_X_Delay((tRem >5) ? 5: tRem); } }
首先EndTime变量获得延时结束时间;
使用一个while循环,在结束时间之前循环调用GUI_Exec()函数和GUI_X_Delay()函数;
前者是GUI的刷新函数,保证在延时过程中不会停止GUI任务处理。后者就是我们要分析的延时函数GUI_X_Delay了。
参数用三目变量,每次送给延时的参数最大是5;
跟踪GUI_X_Delay()函数,在GUI_X_uCOS.C文件中实现。 void GUI_X_Delay (int period) {
INT32U ticks;
ticks = (period * 1000) / OS_TICKS_PER_SEC; OSTimeDly((INT16U)ticks); }
可以看到,在GUI_X_Delay()函数中调用了系统延时函数OSTimeDly(),就像前面我们说过的,OSTimeDly()函数的延时时间是系统节拍,如果要改变GUI_Delay()函数的延时时间,就需要从此着手。
再看看延时时间的取值:OS_TICKS_PER_SEC在OS_CFG.H中设置为100,即每秒产生100个系统节拍。ticks变量在这里被扩展了10倍。即GUI_Delay()函数传递一个延时参数1,而实际的延时时间就是10个节拍即100毫秒。在这个延时时间之内,调用GUI_Delay()函数的任务就不能执行,使得响应速度慢。为保持源程序的风格一致,这里改period的倍数为100,使GUI_Delay()函数的延时时间和OSTimeDly()函数时间单位一致,提高了响应速度增强其易用性。
第二,只移植了UCGUI时;也可以使用GUI_Delay();延时函数,不过要修改相关的底层函数:
按照网上的教程成功移植UCGUI3.90后,会发现GUI_Delay();这个函数一调用程序就会卡在这个函数里面,
找到:c文件: GUI_X.C
*********************************************************************************************************
* uC/GUI
* Universal graphic software for embedded applications
*
* (c) Copyright 2002, Micrium Inc., ffice:smarttags" />Weston, FL
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
* 礐/GUI is protected by international copyright laws. Knowledge of the
* source code may not be used to write a similar product. This file may
* only be used in accordance with a license and should not be redistributed
* in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File : GUI_X.C
Purpose : Config / System dependent externals for GUI
---------------------------END-OF-HEADER------------------------------
*/
#include "GUI.h"
#include "GUI_X.h"
/*********************************************************************
*
* Global data
*/
volatile int OS_TimeMS;
/*********************************************************************
*
* Timing:
* GUI_X_GetTime()
* GUI_X_Delay(int)
Some timing dependent routines require a GetTime
and delay function. Default time unit (tick), normally is
1 ms.
*/
int GUI_X_GetTime(void) {
return OS_TimeMS;
}
void GUI_X_Delay(int ms) {
int tEnd = OS_TimeMS + ms;
while ((tEnd - OS_TimeMS) > 0);
}
/*********************************************************************
*
* GUI_X_Init()
*
* Note:
* GUI_X_Init() is called from GUI_Init is a possibility to init
* some hardware which needs to be up and running before the GUI.
* If not required, leave this routine blank.
*/
void GUI_X_Init(void) {}
/*********************************************************************
*
* GUI_X_ExecIdle
*
* Note:
* Called if WM is in idle state
*/
void GUI_X_ExecIdle(void) {}
/*********************************************************************
*
* Logging: OS dependent
Note:
Logging is used in higher debug levels only. The typical target
build does not use logging and does therefor not require any of
the logging routines below. For a release build without logging
the routines below may be eliminated to save some space.
(If the linker is not function aware and eliminates unreferenced
functions automatically)
void GUI_X_Log (const char *s) { GUI_USE_PARA(s); }
void GUI_X_Warn (const char *s) { GUI_USE_PARA(s); }
void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }
修改volatile int OS_TimeMS;
可以使用STM32的系统嘀嗒定时器systick();设置好作为GUI_Delay()的时钟节拍,然后让滴答定时器作为volatile int OS_TimeMS;的时钟,就可以调UCGU的延时函数了。
或者直接调用原子哥delay_ms();加入到GUI_Delay()也可以延时的。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>