打印
[应用相关]

转:移植UCGUI时,调用GUI_Delay();的解决办法

[复制链接]
4718|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tianli1980|  楼主 | 2014-11-24 14:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
近在学习UCGUI一段时间了,终于成功移植了UCGUI里面的大部分源码,感觉移植代码量还是比较大的,不过倒是GUI_Delay();对于很多菜鸟可能会搞不懂,下面就说一下关于按照原子论坛里的教程成功移植UCGUI3.90后,会发现GUI_Delay();这个函数一调用程序就会卡在这个函数里面,修改一下底层函数,即使没加入操作系统,只移植了UCGUI也可以调用GUI_Delay();






解析GUI_Delay()函数:



使用GUI_Delay()函数时,对于其延时时间不确定,明明设置为最小值1,延时时间仍旧太长,不能达到需求。遂决定研究明白其实现机理。

第一使用操作系统uc/os时:



uC/OS-II使用OSTimeDly()函数实现延时,其单位是OS_TICKS,即延时多少个系统节拍。GUI使用GUI_Delay()函数延时,同时也实现显示刷新;基于同一个平台,估计也会调用OSTimeDly()函数以实现基本的延时功能。 下面分析GUI_Delay()函数功能 void GUI_Delay(int Period) {

  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., 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()也可以延时的。











沙发
mmuuss586| | 2014-11-24 22:38 | 只看该作者

支持楼主分享;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

482

主题

2214

帖子

11

粉丝