在写了uCOS-III移植后,一直想把GUI移植上去。经过不断的努力,有了不错的进展。下面对移植过程进行详解,以方便大家共同学习。
我用的是uCGUI3.98版,在网上找了很久, 可是还不是完整版的。没办法,算是比较全的了,只好先用着。官方是4.03版的但是没有源码,是以库的形式。在搞开发的时候, 可以用官方提供的VC工程去开发,可以省去大量烧写芯片的时间。 我用vs2008测试过可以正常运行。
一、环境:
软件:
- STM32F10x 3.5固件库。
- MDK4.23 编译器。
- uCos-III v3.03。
- uCGUI v3.98。
硬件:
- 神舟三号开发板STM30F103ZE芯;
- 3.2寸屏320*240。
- SPI接口的触摸板。
二、资料
这是我搜集到的资料,都存现在网盘上了。现在115不好用了,只好换百度。
ucGUI中文手册.pdf
http://pan.baidu.com/share/link?shareid=25403&uk=118334538
提示:
- 下文的移植都是在FWLib3.5+uCOSIII3.03这个工程上进行的。
- 这两个工程STM32F固件没有完整添加,在用到哪个功能就添加哪个(减少编译量)。
在移植前最好看过一遍uCGUI中文手册,这样可以有个初步了解,和操作使用。
建立工程时用他推崇的结构:
图1
内容介绍:
图2
三、开始准备移植文件:
新建文件夹uCGUI
- 复制UCGUI3.98源码\uC-GUI-V3-98\Micrium\Software\uC-GUI\Start整个GUI和 Config文件夹到uCGUI。
- 复制UCGUI3.98源码\uC-GUI-V3-98\Micrium\Software\uC-GUI\Sample\GUI_X
- 复制UCGUI3.98源码\uC-GUI-V3-98\Micrium\Software\uC-GUI\Sample下整个GUIDemo文件夹到uCGUI。
- 在uCGUI文件夹下新建LCDDriver文件夹,把自己lcd的驱动程序写入其中。我新建的ili9320.c 和ili9320.h两个文件。需要写哪什么驱动函数,后面做详细的介绍。
图3
到此文件的准备就完成了,开始向程序中添加。
四、添加到工程
我还是直接上图,添加哪些文件。
图4
图5
图6
图7
直接添加所有Dome中的文件。
图8
添加所有GUI子文件。太多了,还是用CTRL+A吧,不然手都要点麻!
图9
重要的一步,让添加的文件可直接索引到。
好了,所有文件都添加到工程中了。下面是最后重要的一步,对文件进行修改。
五、移植修改文件
LCD的驱动,这一步也关系到LCD显示的成功于否,主要要写三个函数:
void LCDxxx_Init(void); //LCD硬件初始化
u16 LCDxxx _GetPoint(u16 x,u16 y); //获取(x,y)坐标的像素点
void LCDxxx _SetPoint(u16 x,u16 y,u16 point); //把像素点写入(x,y)坐标点
这三个函数以定要再在自己的开发板上测试好了,再复制过来。LCDxxx函数名可自定义。只要这三个函数没有问题,移植就成功一大半了
我的是:
void ili9320_Initializtion(void);
u16 ili9320_GetPoint(u16 x,u16 y);
void ili9320_SetPoint(u16 x,u16 y,u16 point);
写好后,在uCGUI\GUI\LCDDriver下找到LCDTemplate.c文件。
找到LCD_L0_SetPixelIndex 添加ili9320_SetPoint函数;
找到 LCD_L0_GetPixelIndex添加ili9320_GetPoint函数。
如下代码:
1 /*********************************************************************
2 *
3 * Exported functions
4 *
5 **********************************************************************
6 */
7
8 /*********************************************************************
9 *
10 * LCD_L0_SetPixelIndex
11 *
12 * Purpose:
13 * Sets the index of the given pixel. The upper layers
14 * calling this routine make sure that the coordinates are in range, so
15 * that no check on the parameters needs to be performed.
16 */
17 void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
18 int xPhys = 0;
19 int yPhys = 0;
20 GUI_USE_PARA(x);
21 GUI_USE_PARA(y);
22 GUI_USE_PARA(PixelIndex);
23 /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
24 #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
25 xPhys = LOG2PHYS_X(x, y);
26 yPhys = LOG2PHYS_Y(x, y);
27 #else
28 xPhys = x;
29 yPhys = y;
30 #endif
31 /* Write into hardware ... Adapt to your system */
32 {
33 ili9320_SetPoint(xPhys, yPhys, PixelIndex);/* ... */
34 }
35 }
36
37 /*********************************************************************
38 *
39 * LCD_L0_GetPixelIndex
40 *
41 * Purpose:
42 * Returns the index of the given pixel. The upper layers
43 * calling this routine make sure that the coordinates are in range, so
44 * that no check on the parameters needs to be performed.
45 */
46 unsigned int LCD_L0_GetPixelIndex(int x, int y) {
47 int xPhys = 0;
48 int yPhys = 0;
49 LCD_PIXELINDEX PixelIndex;
50
51 GUI_USE_PARA(x);
52 GUI_USE_PARA(y);
53 /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
54 #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
55 xPhys = LOG2PHYS_X(x, y);
56 yPhys = LOG2PHYS_Y(x, y);
57 #else
58 xPhys = x;
59 yPhys = y;
60 #endif
61 /* Read from hardware ... Adapt to your system */
62 {
63 PixelIndex = ili9320_GetPoint(xPhys, yPhys);/* ... */
64 }
65 return PixelIndex;
66 }
在uCGUI\Config找到三个配置文件。
LCDConf.h
在pdf的第20章有详细介绍
图10
先设定这几个必需的。
初始化宏定义
驱动如果是自己写的需要以下宏定义
#define LCD_CONTROLLER -1
#define LCD_INIT_CONTROLLER() ili9320_Initializtion();
GUIConf.h
可以用默认配置
GUITouchConf.h
先用默认值,等运行Dome后,有个校准,获得校准值,再进行修改。
参图:
GUI_X_Touch.c文件修改
主要添加读X轴和Y轴的AD值。如果和我用同样的开发板,可以用如下代码。
GUI_X_Touch.c
1 1 /*
2 2 *********************************************************************************************************
3 3 * uC/GUI V3.98
4 4 * Universal graphic software for embedded applications
5 5 *
6 6 * (c) Copyright 2002, Micrium Inc., Weston, FL
7 7 * (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
8 8 *
9 9 * 礐/GUI is protected by international copyright laws. Knowledge of the
10 10 * source code may not be used to write a similar product. This file may
11 11 * only be used in accordance with a license and should not be redistributed
12 12 * in any way. We appreciate your understanding and fairness.
13 13 *
14 14 ----------------------------------------------------------------------
15 15 File : GUI_TOUCH_X.C
16 16 Purpose : Config / System dependent externals for GUI
17 17 ---------------------------END-OF-HEADER------------------------------
18 18 */
19 19
20 20
21 21 #include "GUI.h"
22 22 #include "GUI_X.h"
23 23 #include "ili9320.h"
24 24 #include "bsp.h"
25 25
26 26 //#define NEW8989_LCD // 如果触摸屏的触摸与指针的移动方向是反的请注释掉该宏定义
27 27
28 28 unsigned short int X,Y;
29 29
30 30 void GUI_TOUCH_X_ActivateX(void) {
31 31 }
32 32
33 33 void GUI_TOUCH_X_ActivateY(void) {
34 34 }
35 35
36 36
37 37 int GUI_TOUCH_X_MeasureX(void)
38 38 {
39 39 unsigned char t=0,t1,count=0;
40 40 unsigned short int databuffer[10]={5,7,9,3,2,6,4,0,3,1};//数据组
41 41 unsigned short temp=0,X=0;
42 42
43 43 while(/*GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0&&*/count<10)//循环读数10次
44 44 {
45 45 #ifndef NEW8989_LCD
46 46 databuffer[count]=TPReadX();
47 47 #else
48 48 databuffer[count]=TPReadY();
49 49 #endif
50 50 count++;
51 51 }
52 52 if(count==10)//一定要读到10次数据,否则丢弃
53 53 {
54 54 do//将数据X升序排列
55 55 {
56 56 t1=0;
57 57 for(t=0;t<count-1;t++)
58 58 {
59 59 if(databuffer[t]>databuffer[t+1])//升序排列
60 60 {
61 61 temp=databuffer[t+1];
62 62 databuffer[t+1]=databuffer[t];
63 63 databuffer[t]=temp;
64 64 t1=1;
65 65 }
66 66 }
67 67 }while(t1);
68 68 X=(databuffer[3]+databuffer[4]+databuffer[5]+databuffer[6])>>2;
69 69 }
70 70 #ifndef NEW8989_LCD
71 71 return(X);
72 72 #else
73 73 return((X>100)?(X-100): 0);
74 74 #endif
75 75
76 76 }
77 77
78 78 int GUI_TOUCH_X_MeasureY(void) {
79 79 unsigned char t=0,t1,count=0;
80 80 unsigned short int databuffer[10]={5,7,9,3,2,6,4,0,3,1};//数据组
81 81 unsigned short temp=0,Y=0;
82 82
83 83 while(/*GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0&&*/count<10) //循环读数10次
84 84 {
85 85 #ifndef NEW8989_LCD
86 86 databuffer[count]=TPReadY();
87 87 #else
88 88 databuffer[count]=TPReadX();
89 89 #endif
90 90 count++;
91 91 }
92 92 if(count==10)//一定要读到10次数据,否则丢弃
93 93 {
94 94 do//将数据X升序排列
95 95 {
96 96 t1=0;
97 97 for(t=0;t<count-1;t++)
98 98 {
99 99 if(databuffer[t]>databuffer[t+1])//升序排列
100 100 {
101 101 temp=databuffer[t+1];
102 102 databuffer[t+1]=databuffer[t];
103 103 databuffer[t]=temp;
104 104 t1=1;
105 105 }
106 106 }
107 107 }while(t1);
108 108 Y=(databuffer[3]+databuffer[4]+databuffer[5]+databuffer[6])>>2;
109 109 }
110 110 #ifndef NEW8989_LCD
111 111 return(Y);
112 112 #else
113 113 Y = 4095-Y;
114 114 return((Y>100)?(Y-100): 0);
115 115 #endif
116 116 }
117 117
118 118
GUI_X_uCOS.c文件如下替换
GUI_X_uCOS.c
1 1 /*
2 2 *********************************************************************************************************
3 3 * uC/GUI
4 4 * Universal graphic software for embedded applications
5 5 *
6 6 * (c) Copyright 2002, Micrium Inc., Weston, FL
7 7 * (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
8 8 *
9 9 * 礐/GUI is protected by international copyright laws. Knowledge of the
10 10 * source code may not be used to write a similar product. This file may
11 11 * only be used in accordance with a license and should not be redistributed
12 12 * in any way. We appreciate your understanding and fairness.
13 13 *
14 14 ---Author-Explanation
15 15 *
16 16 * 1.00.00 020519 JJL First release of uC/GUI to uC/OS-II interface
17 17 *
18 18 *
19 19 * Known problems or limitations with current version
20 20 *
21 21 * None.
22 22 *
23 23 *
24 24 * Open issues
25 25 *
26 26 * None
27 27 *********************************************************************************************************
28 28 */
29 29
30 30 #include "os.h"
31 31 #include "os_Cfg_app.h"
32 32 #include "GUI_Private.H"
33 33 #include "stdio.H"
34 34
35 35
36 36 /*
37 37 *********************************************************************************************************
38 38 * GLOBAL VARIABLES
39 39 *********************************************************************************************************
40 40 */
41 41
42 42 static int KeyPressed;
43 43 static char KeyIsInited;
44 44
45 45 static OS_SEM dispSem;
46 46 static OS_SEM eventSem;
47 47 static OS_SEM keySem;
48 48
49 49 /*
50 50 *********************************************************************************************************
51 51 * TIMING FUNCTIONS
52 52 *
53 53 * Notes: Some timing dependent routines of uC/GUI require a GetTime and delay funtion.
54 54 * Default time unit (tick), normally is 1 ms.
55 55 *********************************************************************************************************
56 56 */
57 57
58 58 int GUI_X_GetTime(void)
59 59 {
60 60 OS_ERR err;
61 61
62 62 return ((int)OSTimeGet( (OS_ERR *)&err));
63 63 }
64 64
65 65 void GUI_X_Delay(int period)
66 66 {
67 67 OS_TICK ticks;
68 68 OS_ERR err;
69 69
70 70 ticks = period * OS_CFG_TICK_RATE_HZ / 1000;
71 71 OSTimeDly( (OS_TICK )ticks,
72 72 (OS_OPT )OS_OPT_TIME_DLY,
73 73 (OS_ERR *)&err);
74 74 }
75 75
76 76
77 77 /*
78 78 *********************************************************************************************************
79 79 * GUI_X_ExecIdle()
80 80 *********************************************************************************************************
81 81 */
82 82 /*WM空闲时调用*/
83 83 void GUI_X_ExecIdle(void)
84 84 {
85 85 OS_ERR err;
86 86
87 87 OSTimeDly( (OS_TICK )50,
88 88 (OS_OPT )OS_OPT_TIME_DLY,
89 89 (OS_ERR *)&err);
90 90 }
91 91
92 92
93 93 /*
94 94 *********************************************************************************************************
95 95 * MULTITASKING INTERFACE FUNCTIONS
96 96 *
97 97 * Note(1): 1) The following routines are required only if uC/GUI is used in a true multi task environment,
98 98 * which means you have more than one thread using the uC/GUI API. In this case the #define
99 99 * GUI_OS 1 needs to be in GUIConf.h
100 100 *********************************************************************************************************
101 101 */
102 102
103 103 void GUI_X_InitOS (void)
104 104 {
105 105 OS_ERR err;
106 106
107 107 OSSemCreate( (OS_SEM *)&dispSem, //建立一个互斥型信号量
108 108 (CPU_CHAR *)"dispSem",
109 109 (OS_SEM_CTR )1,
110 110 (OS_ERR *)&err );
111 111
112 112 OSSemCreate( (OS_SEM *)&eventSem,
113 113 (CPU_CHAR *)"eventSem",
114 114 (OS_SEM_CTR )1,
115 115 (OS_ERR *)&err );
116 116 }
117 117
118 118
119 119 void GUI_X_Lock(void)
120 120 {
121 121 OS_ERR err;
122 122 CPU_TS ts;
123 123
124 124 OSSemPend( (OS_SEM *)&dispSem,
125 125 (OS_TICK )0,
126 126 (OS_OPT )OS_OPT_PEND_BLOCKING,
127 127 (CPU_TS *)&ts,
128 128 (OS_ERR *)&err);
129 129 }
130 130
131 131
132 132 void GUI_X_Unlock(void)
133 133 {
134 134 OS_ERR err;
135 135
136 136 OSSemPost( (OS_SEM *)&dispSem,
137 137 (OS_OPT )OS_OPT_POST_1,
138 138 (OS_ERR *)&err);
139 139 }
140 140
141 141
142 142 U32 GUI_X_GetTaskId(void)
143 143 {
144 144 return ((U32)(OSTCBCurPtr->Prio));
145 145 }
146 146
147 147 /*
148 148 *********************************************************************************************************
149 149 * GUI_X_WaitEvent()
150 150 * GUI_X_SignalEvent()
151 151 *********************************************************************************************************
152 152 */
153 153
154 154
155 155 void GUI_X_WaitEvent(void)
156 156 {
157 157 OS_ERR err;
158 158 CPU_TS ts;
159 159
160 160 OSSemPend( (OS_SEM *)&eventSem,
161 161 (OS_TICK )0,
162 162 (OS_OPT )OS_OPT_PEND_BLOCKING,
163 163 (CPU_TS *)&ts,
164 164 (OS_ERR *)&err);
165 165 }
166 166
167 167
168 168 void GUI_X_SignalEvent(void)
169 169 {
170 170 OS_ERR err;
171 171
172 172 OSSemPost( (OS_SEM *)&eventSem,
173 173 (OS_OPT )OS_OPT_POST_1,
174 174 (OS_ERR *)&err);
175 175 }
176 176
177 177 /*
178 178 *********************************************************************************************************
179 179 * KEYBOARD INTERFACE FUNCTIONS
180 180 *
181 181 * Purpose: The keyboard routines are required only by some widgets.
182 182 * If widgets are not used, they may be eliminated.
183 183 *
184 184 * Note(s): If uC/OS-II is used, characters typed into the log window will be placed in the keyboard buffer.
185 185 * This is a neat feature which allows you to operate your target system without having to use or
186 186 * even to have a keyboard connected to it. (useful for demos !)
187 187 *********************************************************************************************************
188 188 */
189 189
190 190 static void CheckInit(void)
191 191 {
192 192 if(KeyIsInited==DEF_FALSE)
193 193 {
194 194 KeyIsInited = DEF_TRUE;
195 195 GUI_X_Init();
196 196 }
197 197 }
198 198
199 199
200 200 /*被GUI_Init()调用,用来初始化一些GUI运行之前需要用的硬件,如键盘或者鼠标之类的.如果不需要的话,可以为空*/
201 201 void GUI_X_Init(void)
202 202 {
203 203 OS_ERR err;
204 204
205 205 OSSemCreate( (OS_SEM *)&keySem,
206 206 (CPU_CHAR *)"keySem",
207 207 (OS_SEM_CTR )0,
208 208 (OS_ERR *)&err );
209 209 }
210 210
211 211
212 212 int GUI_X_GetKey(void)
213 213 {
214 214 int r;
215 215 r = KeyPressed;
216 216 CheckInit();
217 217 KeyPressed = 0;
218 218 return (r);
219 219 }
220 220
221 221
222 222 int GUI_X_WaitKey(void)
223 223 {
224 224 int r;
225 225 OS_ERR err;
226 226 CPU_TS ts;
227 227
228 228 CheckInit();
229 229 if(KeyPressed==0)
230 230 {
231 231 OSSemPend( (OS_SEM *)&keySem, //等待信号量
232 232 (OS_TICK )0,
233 233 (OS_OPT )OS_OPT_PEND_BLOCKING,
234 234 (CPU_TS *)&ts,
235 235 (OS_ERR *)&err);
236 236 }
237 237 r= KeyPressed;
238 238 KeyPressed = 0;
239 239 return (r);
240 240 }
241 241
242 242
243 243 void GUI_X_StoreKey(int k)
244 244 {
245 245 OS_ERR err;
246 246
247 247 KeyPressed = k;
248 248 OSSemPost( (OS_SEM *)&keySem, //释放信号量
249 249 (OS_OPT )OS_OPT_POST_1,
250 250 (OS_ERR *)&err);
251 251 }
252 252
253 253 void GUI_X_Log(const char *s)
254 254 {
255 255 GUI_USE_PARA(s);
256 256 }
257 257
258 258 void GUI_X_Warn(const char *s)
259 259 {
260 260 GUI_USE_PARA(s);
261 261 }
262 262
263 263 void GUI_X_ErrorOut(const char *s)
264 264 {
265 265 GUI_USE_PARA(s);
266 266 }
在BSP.c文件中添加触摸板SPI接口程序。修改后如下:
BSP.C
1 1 /*
2 2 ********************************************************************************
3 3 * uC/OS-III
4 4 *
5 5 * ARM Cortex-M3 Port
6 6 *
7 7 * File : Config.C
8 8 * Version : V1.0
9 9 * By : 王宏强
10 10 *
11 11 * For : Stm32f10x
12 12 * Mode : Thumb2
13 13 * Toolchain :
14 14 * RealView Microcontroller Development Kit (MDK)
15 15 * Keil uVision
16 16 * Description : STM32F10x 内部 系统的配置
17 17 *
18 18 * 1,系统中断优先级模式设置
19 19 * 2,系统程序启动指定
20 20 * 3,系统时钟计时器配置
21 21 * 4,芯片引脚初始化
22 22 *
23 23 * Date : 2012.05.22
24 24 *******************************************************************************/
25 25
26 26 #include "misc.h"
27 27 #include "stm32f10x_gpio.h"
28 28 #include "stm32f10x_rcc.h"
29 29 #include "stm32f10x_iwdg.h"
30 30 #include "stm32f10x_spi.h"
31 31 #include "bsp.h"
32 32
33 33
34 34 GPIO_InitTypeDef GPIO_InitStructure;
35 35
36 36 /*******************************************************************************
37 37 * Function Name : GPIO_Configuration
38 38 * Description : Configures the different GPIO ports.
39 39 * Input : None
40 40 * Output : None
41 41 * Return : None
42 42 *******************************************************************************/
43 43 void GPIO_Configuration(void)
44 44 {
45 45 #ifdef USE_STM3210B_EVAL
46 46 /* Enable the USART2 Pins Software Remapping */
47 47 GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
48 48 #endif
49 49
50 50 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
51 51 RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
52 52 RCC_APB2Periph_GPIOE, ENABLE);
53 53
54 54 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
55 55 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
56 56 GPIO_Init(GPIOA, &GPIO_InitStructure);
57 57 GPIO_Init(GPIOB, &GPIO_InitStructure);
58 58 GPIO_Init(GPIOC, &GPIO_InitStructure);
59 59 GPIO_Init(GPIOD, &GPIO_InitStructure);
60 60 GPIO_Init(GPIOE, &GPIO_InitStructure);
61 61
62 62 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
63 63 RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
64 64 RCC_APB2Periph_GPIOE, DISABLE);
65 65
66 66 }
67 67
68 68
69 69 /*******************************************************************************
70 70 * Function Name : Delay
71 71 * Description : Inserts a delay time.
72 72 * Input : nCount: specifies the delay time length.
73 73 * Output : None
74 74 * Return : None
75 75 *******************************************************************************/
76 76 //void Delay(volatile CPU_INT32U nCount)
77 77 //{
78 78 // for(; nCount != 0; nCount--);
79 79 //}
80 80
81 81 /*******************************************************************************
82 82 函 数 名:void IWDG_Init(void)
83 83 功能描述:看门狗初始化
84 84 入口参数:
85 85 返回参数:
86 86 创建时间: 2011.6.24
87 87 ********************************************************************************/
88 88 void IWDG_Init(void)
89 89 {
90 90 IWDG_WriteAccessCmd( IWDG_WriteAccess_Enable );
91 91 IWDG_SetPrescaler( IWDG_Prescaler_64); //最小
92 92 IWDG_SetReload( 0x138); //40KHz内部时钟 (1/40000 * 64 * 0x138 = 0.5s)
93 93 IWDG_WriteAccessCmd( IWDG_WriteAccess_Disable );
94 94 IWDG_Enable();
95 95 IWDG_ReloadCounter();
96 96 }
97 97
98 98 /*******************************************************************************
99 99 * Function Name :void SysTickInit(void)
100 100 * Description :系统定时器时间配置
101 101 * Input :
102 102 * Output :
103 103 * Other :时基为1ms
104 104 * Date :2011.11.03 12:59:13
105 105 *******************************************************************************/
106 106 void SysTickInit(void)
107 107 {
108 108 SysTick_Config(SystemCoreClock / 1000); //uCOS时基1ms
109 109 }
110 110
111 111 /*******************************************************************************
112 112 * Function Name :void InterruptOrder(void)
113 113 * Description :中断向量,优先级
114 114 * Input :
115 115 * Output :
116 116 * Other :
117 117 * Date :2011.10.27 11:50:05
118 118 *******************************************************************************/
119 119 void NVIC_Configuration(void)
120 120 {
121 121 NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4);//优先级设置 全为抢占式优先级
122 122 }
123 123
124 124
125 125 /*******************************************************************************
126 126 * Function Name :void SystemConfig(void)
127 127 * Description :系统时间戳 初始化
128 128 * Input :
129 129 * Output :
130 130 * Other :
131 131 * Date :2012.6.15 13:14:59
132 132 *******************************************************************************/
133 133 #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
134 134 void CPU_TS_TmrInit (void)
135 135 {
136 136 }
137 137 #endif
138 138
139 139
140 140 /*******************************************************************************
141 141 * Function Name :void SystemConfig(void)
142 142 * Description :读时间戳 计数值
143 143 * Input :读到的计数值
144 144 * Output :
145 145 * Other :
146 146 * Date :2012.6.15 13:14:59
147 147 *******************************************************************************/
148 148 #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
149 149 CPU_TS_TMR CPU_TS_TmrRd (void)
150 150 {
151 151 return (SysTick->VAL);
152 152 }
153 153 #endif
154 154
155 155 /*******************************************************************************
156 156 * Function Name :void SystemConfig(void)
157 157 * Description :系统初始化
158 158 * Input :
159 159 * Output :
160 160 * Other :
161 161 * Date :2011.10.27 13:14:59
162 162 *******************************************************************************/
163 163 void BspInit(void)
164 164 {
165 165 NVIC_Configuration(); //中断优先级设置
166 166 GPIO_Configuration(); //端口初始化,所有端口关
167 167 SPI_Config(); //触摸接口初始化
168 168 }
169 169
170 170 void led_init(void)
171 171 {
172 172 GPIO_InitTypeDef GPIO_InitStructure;
173 173 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOF, ENABLE);
174 174 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
175 175 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
176 176 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
177 177 GPIO_Init(GPIOA, &GPIO_InitStructure);
178 178
179 179 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
180 180 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
181 181 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
182 182 GPIO_Init(GPIOF, &GPIO_InitStructure);
183 183 }
184 184
185 185
186 186
187 187 void led_on(CPU_INT32U n)
188 188 {
189 189 switch (n)
190 190 {
191 191 case LED_0:
192 192 GPIO_SetBits(GPIOD, GPIO_Pin_2);
193 193 break;
194 194 case LED_1:
195 195 GPIO_SetBits(GPIOD, GPIO_Pin_3);
196 196 break;
197 197 case LED_2:
198 198 GPIO_SetBits(GPIOD, GPIO_Pin_4);
199 199 break;
200 200 case LED_3:
201 201 GPIO_SetBits(GPIOF, GPIO_Pin_6);
202 202 break;
203 203 case LED_4:
204 204 GPIO_SetBits(GPIOF, GPIO_Pin_7);
205 205 break;
206 206 case LED_5:
207 207 GPIO_SetBits(GPIOF, GPIO_Pin_8);
208 208 break;
209 209 default:
210 210 break;
211 211 }
212 212 }
213 213
214 214
215 215 void led_off(CPU_INT32U n)
216 216 {
217 217 switch (n)
218 218 {
219 219 case LED_0:
220 220 GPIO_ResetBits(GPIOD, GPIO_Pin_2);
221 221 break;
222 222 case LED_1:
223 223 GPIO_ResetBits(GPIOD, GPIO_Pin_3);
224 224 break;
225 225 case LED_2:
226 226 GPIO_ResetBits(GPIOD, GPIO_Pin_4);
227 227 break;
228 228 case LED_3:
229 229 GPIO_ResetBits(GPIOF, GPIO_Pin_6);
230 230 break;
231 231 case LED_4:
232 232 GPIO_ResetBits(GPIOF, GPIO_Pin_7);
233 233 break;
234 234 case LED_5:
235 235 GPIO_ResetBits(GPIOF, GPIO_Pin_8);
236 236 break;
237 237 default:
238 238 break;
239 239 }
240 240 }
241 241 /*
242 242 T_CS PA4
243 243 SPI1_SCK PA5
244 244 SPI1_MISO PA6
245 245 SPI1_MOSI PA7
246 246 T_BUSY PA8
247 247 */
248 248 void SPI_Config(void)
249 249 {
250 250 GPIO_InitTypeDef GPIO_InitStructure;
251 251 SPI_InitTypeDef SPI_InitStructure;
252 252
253 253 //GPIOA Periph clock enable
254 254 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
255 255 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
256 256 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
257 257 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);
258 258 //SPI1 Periph clock enable
259 259 // RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
260 260 //SPI2 Periph clock enable
261 261 RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE ) ;
262 262
263 263 //Configure SPI2 pins: SCK, MISO and MOSI
264 264 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
265 265 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
266 266 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
267 267 GPIO_Init(GPIOB,&GPIO_InitStructure);
268 268 /*
269 269 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;
270 270 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
271 271 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
272 272 GPIO_Init(GPIOA,&GPIO_InitStructure);
273 273
274 274 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
275 275 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
276 276 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
277 277 GPIO_Init(GPIOA,&GPIO_InitStructure); */
278 278
279 279 //Configure PF10 pin: TP_CS pin
280 280 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
281 281 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
282 282 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
283 283 GPIO_Init(GPIOB,&GPIO_InitStructure);
284 284
285 285 //Configure PA8 pin: TP_BUSY pin
286 286 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
287 287 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
288 288 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
289 289 GPIO_Init(GPIOE,&GPIO_InitStructure);
290 290
291 291 /* Configure PE.06 as input floating For TP_IRQ*/
292 292 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
293 293 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
294 294 GPIO_Init(GPIOE,&GPIO_InitStructure);
295 295
296 296 // SPI1 Config
297 297 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
298 298 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
299 299 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
300 300 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
301 301 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
302 302 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //SPI_NSS_Hard
303 303 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
304 304 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
305 305 SPI_InitStructure.SPI_CRCPolynomial = 7;
306 306 SPI_Init(SPI2,&SPI_InitStructure);
307 307
308 308 // SPI1 enable
309 309 SPI_Cmd(SPI2,ENABLE);
310 310 }
311 311
312 312
313 313 unsigned char SPI_WriteByte(unsigned char data)
314 314 {
315 315 unsigned char Data = 0;
316 316
317 317 //Wait until the transmit buffer is empty
318 318 while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);
319 319 // Send the byte
320 320 SPI_I2S_SendData(SPI2,data);
321 321
322 322 //Wait until a data is received
323 323 while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET);
324 324 // Get the received data
325 325 Data = SPI_I2S_ReceiveData(SPI2);
326 326
327 327 // Return the shifted data
328 328 return Data;
329 329 }
330 330 void SpiDelay(unsigned int DelayCnt)
331 331 {
332 332 unsigned int i;
333 333 for(i=0;i<DelayCnt;i++);
334 334 }
335 335
336 336 u16 TPReadX(void)
337 337 {
338 338 u16 x=0;
339 339 TP_CS();
340 340 SpiDelay(10);
341 341 SPI_WriteByte(0x90);
342 342 SpiDelay(10);
343 343 x=SPI_WriteByte(0x00);
344 344 x<<=8;
345 345 x+=SPI_WriteByte(0x00);
346 346 SpiDelay(10);
347 347 TP_DCS();
348 348 x = x>>3;
349 349 return (x);
350 350 }
351 351
352 352 u16 TPReadY(void)
353 353 {
354 354 u16 y=0;
355 355 TP_CS();
356 356 SpiDelay(10);
357 357 SPI_WriteByte(0xD0);
358 358 SpiDelay(10);
359 359 y=SPI_WriteByte(0x00);
360 360 y<<=8;
361 361 y+=SPI_WriteByte(0x00);
362 362 SpiDelay(10);
363 363 TP_DCS();
364 364 y = y>>3;
365 365 return (y);
366 366 }
向工程中添加两个stm32f10x_fsmc.c,stm32f10x_spi.c这两个文件。
好了,大部分的准备工作都好了, 再在让新建一个任务来运行Dome中的MainTask();在任务3中调用GUI_TOUCH_Exec();
APP.C
1 1 /*-------------------------------------------------------------------------
2 2
3 3 软件主体
4 4
5 5
6 6 -------------------------------------------------------------------------*/
7 7
8 8 #include "bsp.h"
9 9 #include "App.h"
10 10
11 11 extern void MainTask(void);
12 12 extern void GUI_TOUCH_Exec(void);
13 13
14 14 static OS_TCB taskStartTCB;
15 15 static CPU_STK taskStartStk[STARTUP_TASK_STK_SIZE]; //启动任务的程序空间
16 16
17 17 static OS_TCB task1TCB;
18 18 static CPU_STK task1Stk[TASK1_STK_SIZE];
19 19
20 20 static OS_TCB task2TCB;
21 21 static CPU_STK task2Stk[TASK2_STK_SIZE];
22 22
23 23 static OS_TCB task3TCB;
24 24 static CPU_STK task3Stk[TASK3_STK_SIZE];
25 25
26 26 static OS_TCB dispTCB;
27 27 static CPU_STK dispStk[TASK4_STK_SIZE];
28 28
29 29 static volatile OS_SEM taskSem;
30 30
31 31
32 32
33 33 /*******************************************************************************
34 34 * Function Name :void TaskStart(void)
35 35 * Description :任务启动
36 36 * Input :
37 37 * Output :
38 38 * Other :
39 39 * Date :2012.04.18 11:48:23
40 40 *******************************************************************************/
41 41 static void TaskStart(void)
42 42 {
43 43 OS_ERR err;
44 44
45 45 led_init();
46 46 SysTickInit();
47 47
48 48
49 49 OSTaskCreate( (OS_TCB *)&task1TCB,
50 50 (CPU_CHAR *)"Task1",
51 51 (OS_TASK_PTR)Task1,
52 52 (void *)0,
53 53 (OS_PRIO )TASK1_PRIO,
54 54 (CPU_STK *)&task1Stk[0],
55 55 (CPU_STK_SIZE)TASK1_STK_SIZE / 10,
56 56 (CPU_STK_SIZE)TASK1_STK_SIZE,
57 57 (OS_MSG_QTY )0,
58 58 (OS_TICK )0,
59 59 (void *)0,
60 60 (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
61 61 (OS_ERR *)&err);
62 62
63 63 OSTaskCreate( (OS_TCB *)&task2TCB,
64 64 (CPU_CHAR *)"Task2",
65 65 (OS_TASK_PTR)Task2,
66 66 (void *)0,
67 67 (OS_PRIO ) TASK2_PRIO,
68 68 (CPU_STK *)&task2Stk[0],
69 69 (CPU_STK_SIZE)TASK2_STK_SIZE / 10,
70 70 (CPU_STK_SIZE)TASK2_STK_SIZE,
71 71 (OS_MSG_QTY )0,
72 72 (OS_TICK )0,
73 73 (void *)0,
74 74 (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
75 75 (OS_ERR *)&err);
76 76
77 77
78 78 OSTaskCreate( (OS_TCB *)&task3TCB,
79 79 (CPU_CHAR *)"Task3",
80 80 (OS_TASK_PTR)Task3,
81 81 (void *)0,
82 82 (OS_PRIO )TASK3_PRIO,
83 83 (CPU_STK *)&task3Stk[0],
84 84 (CPU_STK_SIZE)TASK3_STK_SIZE / 10,
85 85 (CPU_STK_SIZE)TASK3_STK_SIZE,
86 86 (OS_MSG_QTY )0,
87 87 (OS_TICK )0,
88 88 (void *)0,
89 89 (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
90 90 (OS_ERR *)&err);
91 91
92 92 OSTaskCreate( (OS_TCB *)&dispTCB,
93 93 (CPU_CHAR *)"LCD display",
94 94 (OS_TASK_PTR)MainTask,
95 95 (void *)0,
96 96 (OS_PRIO )Disp_PRIO,
97 97 (CPU_STK *)&dispStk[0],
98 98 (CPU_STK_SIZE)TASK4_STK_SIZE / 10,
99 99 (CPU_STK_SIZE)TASK4_STK_SIZE,
100 100 (OS_MSG_QTY )0,
101 101 (OS_TICK )0,
102 102 (void *)0,
103 103 (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
104 104 (OS_ERR *)&err);
105 105
106 106 OSSemCreate( (OS_SEM *)&taskSem,
107 107 (CPU_CHAR *)"taskSem",
108 108 (OS_SEM_CTR )0,
109 109 (OS_ERR *)err);
110 110
111 111 OSTaskDel( (OS_TCB *)&taskStartTCB,
112 112 (OS_ERR *)&err);
113 113 }
114 114
115 115 static void Task1(void *p_arg)
116 116 {
117 117 OS_ERR err;
118 118
119 119 while (1)
120 120 {
121 121 led_on(LED_4);
122 122 OSTimeDly( (OS_TICK )200,
123 123 (OS_OPT )OS_OPT_TIME_DLY,
124 124 (OS_ERR *)&err);
125 125
126 126 led_off(LED_4);
127 127 OSTimeDly( (OS_TICK )200,
128 128 (OS_OPT )OS_OPT_TIME_DLY,
129 129 (OS_ERR *)&err);
130 130
131 131 OSSemPost( (OS_SEM *)&taskSem,
132 132 (OS_OPT )OS_OPT_POST_ALL,
133 133 (OS_ERR *)&err);
134 134 }
135 135 }
136 136
137 137 static void Task2(void *p_arg)
138 138 {
139 139 OS_ERR err;
140 140
141 141 while (1)
142 142 {
143 143 led_on(LED_5);
144 144 OSSemPend( (OS_SEM *)&taskSem,
145 145 (OS_TICK )10000,
146 146 (OS_OPT )OS_OPT_PEND_BLOCKING,
147 147 (CPU_TS *)0,
148 148 (OS_ERR *)&err);
149 149
150 150 led_off(LED_5);
151 151 OSSemPend( (OS_SEM *)&taskSem,
152 152 (OS_TICK )10000,
153 153 (OS_OPT )OS_OPT_PEND_BLOCKING,
154 154 (CPU_TS *)0,
155 155 (OS_ERR *)&err);
156 156 }
157 157 }
158 158
159 159 static void Task3(void *p_arg)
160 160 {
161 161 OS_ERR err;
162 162 static int tasCon = 0;
163 163 while (1)
164 164 {
165 165 GUI_TOUCH_Exec();
166 166 OSTimeDly( (OS_TICK )10,
167 167 (OS_OPT )OS_OPT_TIME_DLY,
168 168 (OS_ERR *)&err);
169 169
170 170 OSTimeDly( (OS_TICK )10,
171 171 (OS_OPT )OS_OPT_TIME_DLY,
172 172 (OS_ERR *)&err);
173 173
174 174 if ((tasCon++ % 50) < 25)
175 175 led_on(LED_3);
176 176 else
177 177 led_off(LED_3);
178 178 }
179 179 }
180 180
181 181
182 182 void KernelMain(void)
183 183 {
184 184 OS_ERR err;
185 185
186 186 CPU_Init();
187 187 OSInit( (OS_ERR *)&err);
188 188
189 189 OSTaskCreate( (OS_TCB *)&taskStartTCB,
190 190 (CPU_CHAR *)"Task Start",
191 191 (OS_TASK_PTR)TaskStart,
192 192 (void *)0,
193 193 (OS_PRIO ) STARTUP_TASK_PRIO,
194 194 (CPU_STK *)&taskStartStk[0],
195 195 (CPU_STK_SIZE)STARTUP_TASK_STK_SIZE / 10,
196 196 (CPU_STK_SIZE)STARTUP_TASK_STK_SIZE,
197 197 (OS_MSG_QTY )0,
198 198 (OS_TICK )0,
199 199 (void *)0,
200 200 (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
201 201 (OS_ERR *)&err);
202 202
203 203 OSStart( (OS_ERR *)&err);
204 204 }
设定优先级 和分配空间。任务3分配350个字节,MainTask分配500个字节
优先级设定触摸版 比MainTask()高就可以了。
需要注意一个问题,GUI中用到了获取获取时基计数器的值。而时基计数器是在优先级为10的任务中进行刷新的。所以必需把 MainTask()任务的优先级比10优先级低。
还有一个解决办法:修改时基计数器任务的优先级,在uCOS-III\uCOS-III文件os_cfg_app.h
OS_CFG_TMR_TASK_PRIO
OS_CFG_TICK_TASK_PRIO
到此就可以进行编译了。
几分钟的等待,下载~~~
每次编译的时间实在是太长了。这样咱们把源代码生成库,再进行编译。如下图:
图11
再编译生成
到Obj文件夹下到Project.lib 找到,改下名子GUI3_98.lib
把工程中的uCGUI/lib里的所有文件删除,用GUI3_98.lib替换。
再切换回来
图13
图12
再编译, 是不是非常快了。
注意:在对LCD配置变更时,需要重新制作.lib库。
以下两个连接是编译完成后的工程。
FWLib3.5+uCOSIII3.03+uCGUI3.98(源文件版).rar
http://pan.baidu.com/share/link?shareid=25616&uk=118334538
FWLib3.5+uCOSIII3.03+uCGUI3.98(库形式版).rar
http://pan.baidu.com/share/link?shareid=25619&uk=118334538
总结:
在移植的过程中主要讲述了三点
- 三个LCD的驱动函数。
- GUI程序在uCOS-III优先级的选择。
- GUI库的制作。
好了,就这些了,后期还会慢慢更新最新版。希望以上对新学习uCGUI的朋友有所帮助。
下面传几个Dome的照片。
视频http://www.tudou.com/programs/view/Ut-yCR2jTs0/