uCOSIII uCGUI STM32 平台移植
在写了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
UCGUI3.98源码.rar
http://pan.baidu.com/share/link?shareid=25407&uk=118334538
官方UCGUI4.04, 及说明书
http://pan.baidu.com/share/link?shareid=25413&uk=118334538
http://pan.baidu.com/share/link?shareid=25415&uk=118334538
下面上两个版本空的工程:
FWLib3.5+uCOSIII3.03
http://pan.baidu.com/share/link?shareid=25418&uk=118334538
FWLib2.0+uCOSIII3.03
http://pan.baidu.com/share/link?shareid=25419&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 下GUI_X_Touch.c,GUI_X_uCOS.c两个文件到uCGUI中,因为有触摸功能和uCOS系统。
- 复制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值。如果和我用同样的开发板,可以用如下代码。
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文件如下替换
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接口程序。修改后如下:
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();
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/