OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11102|回复: 13

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

[复制链接]

8

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2013-7-13
在线时间
24 小时
发表于 2013-10-8 23:32:58 | 显示全部楼层 |阅读模式
 
最近在学习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_SECOS_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" />WestonFL
*                       (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()也可以延时的。

 

 

 

 



。。。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2013-7-13
在线时间
24 小时
 楼主| 发表于 2013-10-8 23:33:45 | 显示全部楼层
回复【楼主位】神通广大:
---------------------------------
裸跑,没有系统,在调用GUI_Delay()时,出现死循环的问题,跟踪发现,GUI_Delay()需要调用GUI_X_GetTime(),GUI_X_GetTime是获取系统时间用的,我裸跑时,除了去获取控制芯片实时时钟外,我还没想到其他的办法(这种方法还没调试,前提是控制芯片本身有实时时钟模块),能获取系统时间,在网上查了好多资料,还是没有其他的解决办法,最后索性修改GUI_Delay(),反正这个也主要是延时用的,我就直接修改了,我修改的代码如下:

void GUI_Delay(int eriod) {

  GUI_ASSERT_NO_LOCK();

  while (Period) {
    GUI_Exec();
    eriod--;
  }

}
。。。
回复 支持 反对

使用道具 举报

17

主题

146

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
400
金钱
400
注册时间
2013-7-9
在线时间
57 小时
发表于 2013-10-8 23:56:07 | 显示全部楼层
MARK 也碰到这个问题,学习一下。
回复 支持 反对

使用道具 举报

6

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2013-6-24
在线时间
0 小时
发表于 2013-10-9 11:34:29 | 显示全部楼层
回复【楼主位】神通广大:
---------------------------------

问一个问题,我用的mini版,但是使用横屏时void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color); 
这个函数就不能用了,只填充很少一部分,竖屏时没有问题,求大神解答
回复 支持 反对

使用道具 举报

6

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2013-6-24
在线时间
0 小时
发表于 2013-10-9 11:53:56 | 显示全部楼层
回复【4楼】衡阳落雁:
---------------------
找到解决办法了,新版子的函数已经修正了
回复 支持 反对

使用道具 举报

17

主题

146

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
400
金钱
400
注册时间
2013-7-9
在线时间
57 小时
发表于 2013-10-9 12:29:22 | 显示全部楼层
回复【5楼】衡阳落雁:
---------------------------------
新版子?什么新版子?
回复 支持 反对

使用道具 举报

6

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2013-6-24
在线时间
0 小时
发表于 2013-10-9 19:08:27 | 显示全部楼层
回复【6楼】传说中的松哥:
---------------------------------
就是那个大版,好像是2.0吧,不是mini版
实际上他这个函数应该横竖屏时代码都一样的,他分开写反而错了
回复 支持 反对

使用道具 举报

8

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2013-7-13
在线时间
24 小时
 楼主| 发表于 2013-10-9 20:10:33 | 显示全部楼层
回复【3楼】传说中的松哥:
MARK 也碰到这个问题,学习一下。
---------------------------------
一起学习,共同进步!哈哈!
。。。
回复 支持 反对

使用道具 举报

8

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2013-7-13
在线时间
24 小时
 楼主| 发表于 2013-10-9 20:12:11 | 显示全部楼层
回复【4楼】衡阳落雁:
回复【楼主位】神通广大: --------------------------------- 问一个问题,我用的mini版,但是使用横屏时void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);  这个函数就不能用了,只填充很少一部分,竖屏时没有问题,求大神解答
---------------------------------
横屏我还没用啊,不过感觉源码例程用横屏比较适合啊!
。。。
回复 支持 反对

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-3-17
在线时间
0 小时
发表于 2014-5-18 16:17:38 | 显示全部楼层
查了半天不知道 为什么进入GUI_Delay OSTimeDly 会死机 看了这个瞬间明白了 感谢楼主啊
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-7-25
在线时间
2 小时
发表于 2015-8-22 16:30:35 | 显示全部楼层
论坛好强大,基本上可以解决初学者遇到的问题,good
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2015-12-16
在线时间
0 小时
发表于 2015-12-16 15:37:18 | 显示全部楼层
帮了我大忙了
回复 支持 反对

使用道具 举报

3

主题

14

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-3-11
在线时间
8 小时
发表于 2016-7-25 21:50:05 | 显示全部楼层
学习了 楼主强大 学习学习
回复 支持 反对

使用道具 举报

20

主题

143

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2015-8-28
在线时间
108 小时
发表于 2017-1-4 20:00:35 | 显示全部楼层
牛逼,新手收下了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-29 05:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表