emWin522(uCGUI)图形用户接口移植详细实例_STM32_2013_12_30

合集下载

uCGUI在stm32内核上的移植

uCGUI在stm32内核上的移植

LCDConf.h UCGUI390a\Start\Config
此文件用于 LCD 的相关应用配置,介绍如下
#ifndef LCDCONF_H
#define LCDCONF_H
#define LCD_XSIZE
(240)
#define LCD_YSIZE
(320)
#define LCD_CONTROLLER (9320) //控制器编号
配置文件目录
GUI\ConvertMono
灰度色彩转换支持
GUI\ConvertColor
色彩转换支持
GUI\Core
核心文件
GUI\Font
字体文件
GUI\JPEG
JPEG 格式图像显示支持
GUI\LCDDriver
LCD 驱动文件
GUI\MemDev
存储设备支持
这是今年暑假移植的,刚刚翻译完 uC/OS-III 用户手册,并移植了
uC/OS-III 到 stm32 处理器上,我就想把 uC/GUI 也放到网上去,希望
能帮到大家。
——屈环宇
——2011 年 11 月 6 号晚
Void LCD_MyInit(); 注意 LCD 的初始化函数名不能用 LCD_Init(); uC/GUI 中已有如此定义的 函数,会导致重定义。 接口函数的设计是跟处理器和 LCD 相关的,在移植 uC/GUI 前必须完成以 上 3 个 函 数 的 设 计 , 即 能 用 LCD_MyInit() 实 现 LCD 的 初 始 化 , LCD_ReadPoint(u16 x,u16 y)返回对应点的颜色,LCD_DrawPoint(u16 x, u16 y, u16 color)在 LCD 上显示对应点的颜色。

基于STM32的UCGUI移植解析(新手入门)

基于STM32的UCGUI移植解析(新手入门)
UCGUI 移植初级解析
-----------------如何建立一个简单的 UC/GUI 工程
仅供像我这样的新手学习 UCGUI 使用
做 UCGUI 移植,首先要选择好自己硬件平台,UCGUI 源码,液晶的底层驱 动。关于硬件和 GUI 源码(我选的源码 3.90 版,原子 STM32MINI 开发板)不 必多说。其次,液晶的底层驱动函数得要好好准备,这可是直接和 GUI 源码打 交道的。
(7) 修改:LCDDriver / LCDDummy.c 文件 方法:在这里面添加几个函数,关于这几个函数就是我在开始列举
的几个函数 LCD_ReadPoint(u16 x, u16 y);//读取点坐标 LCD_SetPoint(u16 x, u16 y, u16 color );//画点 你的函数也许不是这个名字哦,大家不要照搬,这是你自己的驱动函数, 在哪里添加这两个函数呢,不要着急,听我来说,
还有一个问题,网上有人说触摸用不到,可以不用添加,然后字体也只
添加几个用得到的,我的意见是:全部添加,避免难以修改的 KEIL 警告, 这点很重要,我是新手,我很清楚怎么过来的,呵呵呵。
(4):文件添加完了,还有一步呢,还要在添加路径。点击魔术棒,出现一 个选项卡,点击 C/C++,在 Include Paths 里包含文件路径,所有文件的都 要包进来哦。能玩移植的朋友们,我相信(3)(4)两步对你们来说不难。
(2):复制 源码/Sample/GUI_X 文件夹下的 GUI_X.c 文件,粘贴到工程 模板下的 Config 里; 图片指示:
(3):打开 KEIL 工程(事先准备好的),KEIL 界面左边有个 Project 视窗, 在 Target1 单击右键,出现一个选项卡,在 Groups 里创建各文件,然后依 次 Add Files,即添加.c .h 文件,这里要着重说明:添加文件的时候,尤 其是 GUI 源码,文件类型选择 ALL Files(系统默认.c 文件),就是为了添 加.h 文件,这一点很重要。举个例子吧,在 Config 文件夹下要添加 GUI_X.c GUIConf.h GUITouch.h LCDConf.h。

UCOS-II ucGUI的完美移植

UCOS-II ucGUI的完美移植

stm32 UCGUI 完美移植作者:Changing发表时间:09-16 04:13分类:电子相关1 Comment前一篇:stm32 DA 数模转换后一篇:Stm32 SWD 下载 调试配置UCGUI是一种嵌入式应用中的图形支持系统。

它设计用于为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器的图形用户接口,它适用单任务或是多任务系统环境, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示。

它的设计架构是模块化的,由不同的模块中的不同层组成,由一个LCD驱动层来包含所有对LCD的具体图形操作。

UCGUI可以在任何的CPU上运行,因为它是100%的标准C代码编写的。

类似程序还有国产的一个MINIGUI (/zhcn/),MiniGUI 是一个自由软件项目。

其目标是提供一个快速、稳定、跨操作系统的图形用户界面(GUI)支持系统,尤其是基于 Li nux/uClinux、eCos 以及其他传统 RTOS(如 VxWorks、ThreadX、uC/OS-II、Nucleus 等)的实时嵌入式操作系统。

有机会尝试下,支持下国产,毕竟国内这样的公司不多。

这里移植的UCGUI3.90a版本,虽然已经有更新的版本,比如UCGUI3.98、甚至4.04版本。

但是目前来说只有这个版本的代码是最全的,包括了JPEG , MULTILAYER , MEMDEV ,AntiAlias等模块。

一直想尝试做一个数码相册,JEPG模块自然少不了,所以移植了这个版本。

UCGUI390a 下载整个移植过程,让LCD显示图案倒是没花多少时间,资料也比较多,但是在移植触摸屏的时候卡了好几天,然后又是 UCGUI 指针图标 移动有重影(LCD读取像素颜色函数有问题)。

总之移植是个累人的活首先需要保证你的LCD驱动和触摸屏驱动是有效的,如果你的LCD也是ili93xx 控制器 XPT2046控制器的触摸屏可以参考 stm32 驱动 T F T LCD stm32 驱动 触摸屏 两篇文章UCGUI的文件数量很大,主要用到UCGUI390a/Start/Con f ig 和 UCGUI390a/Start/GUI两个文件夹下文件,不过文件数量也已经很多了 。

uCGUI(emWin)的应用与移植

uCGUI(emWin)的应用与移植

uCGUI(emWin)的应用与移植uC/GUI(emWin)的应用与移植 2006-11-19 01:38当你开始使用emWin进行编程时,通常遵循以下的步骤:第1步:配置emWin第一步通常是通过修改头文件LCDConf.h来配置emWin。

LCDConf.h中的宏定义描述了LCD显示部分硬件特性;根据你的具体情况修改这些宏定义(例如显示屏的长、宽,每像素点用几位表示,LCD控制器的类型等参数)。

第2步:定义LCD的底层驱动函数底层函数包括对LCD(控制器)的初始化函数,LCD显示缓冲区的读写函数等,完成对LCD显示硬件的直接操作。

对于映射在系统存储器上的LCD,对显示缓冲区的操作仅需要在LCDConf.h中进行定义就可以了。

但对于采用I/O端口/缓冲区操作的LCD,就必须定义相应的接口函数了。

第3步:编译,链接和测试例子代码emWin对于单任务和多任务环境下的应用都提供了例子代码。

在编程之前,对这些例子代码进行编译、链接和测试,使你能够初步了解这些代码的使用。

第4步:修改例子程序对例子代码作少量的修改。

逐步添加一些额外的指令,例如显示不同大小的文字,显示多行等等,从而进一步理解代码的应用。

第5步:emWin的多任务应用,加入到你的操作系统中如果你的系统有可能多个任务同时对显示进行操作,这时就要用到GUITask.C文件中的GUI_MAXTASK和GUI_OS宏。

第6步:采用emWin编写你自己的应用到这一步你应该对怎样使用emWin有一个清楚的了解了。

考虑如何采用emWin提供的函数来构建你的应用,并通过阅读手册来获得各函数更详细的功能和使用上的信息。

emWin的移植移植是指对emWin进行配置和修改,使它能够在你的目标系统上运行。

参考第3.4节中的第一步和第二步,移植工作主要是针对配置头文件中的宏定义进行修改。

这些宏包括:1. LCD宏,定义了显示的尺寸和一些可选择的特性(例如镜像,等等)2.LCD控制器宏,定义了怎样对控制器进行操作。

STM32平台的_C_GUI移植与图形界面设计

STM32平台的_C_GUI移植与图形界面设计

( ) 5 6 5
/ /指定颜色模式为 5 6 5 / /激活 C P U和L C D 控制器中的反转 ) i e f i n e L C D_ I N I T_ C ON T R O L L E R( l i 9 3 2 0_ I n i t i a l i z t i o n #d ( ) ; / / i l i 9 3 2 0 L C D 控制器初始化
表 1 G U I文件目录内容说明
文件目录 GU I A n t i A l i a s \ GU I C o n v e r t M o n o \ GU I C o n v e r t C o l o r \ GU I C o r e \ GU I F o n t \ GU I L C D D r i v e r \ GU I e mD e v \M GU I T o u c h \ GU I i d e t \W g GU I \WM 配置文件 抗锯齿功能 , 优化 L C D 边缘模糊效果 单色及灰度显示的颜色转换程序 彩色显示的颜色转换程序 / C GU I内核 μ 多种字体文件 L C D 硬件驱动文件 内存设备支持 , 防止在画图时产生抖动 触摸屏支持 ( 只支持模拟的触摸屏 ) 窗口控件库 窗口管理器
/ 1 C G U I结构框架 μ
/ 1. 1 μ C G U I的文件组织
/ 其中较为重要的 C GU I软件采用模块化组 织 架 构 , μ 文件目录是配置文件目录 C 和 o n f i I库文件目录 。 考 g GU / 虑到未来升级方 便 , 建议保持 μ C GU I原 有 的 目 录 结 构 , 这样升级到新版本时只要覆盖原文件目录即可 , 而不 会 改 变整个工程的文件路径 。 / 它提供了丰 C GU I是一个源代码开放 的 图 形 系 统 , μ 包 括 二 维 绘 图 库, 多 字 体、 可 扩 充 的 字 符 集, 富的资源 ,

STM32平台的μC/GUI移植与图形界面设计

STM32平台的μC/GUI移植与图形界面设计

STM32平台的μC/GUI移植与图形界面设计摘要:μC/GUI是一种专为嵌入式应用设计的通用图形接口软件。

本文详细介绍了μC /GUI的结构框架和基于STM32平台的μC/OS-II上的μC/GUI移植过程,并在此基础上进行图形界面设计;阐述了μC/GUI的窗口管理机制,提出了实现μC/GUI中文小型字库的两种方法并采用存储设备解决了图形显示的闪烁问题。

关键词:μC/GUI移植;STM32平台;图形界面;中文小型字库;存储设备引言嵌入式系统的图形用户界面,要求具有占用资源少、性能高、可靠性高、可移植、可配置等特点,μC/GUI就是这样一种专门为嵌入式应用设计的图形用户界面软件。

μC/GUI 可应用于多任务环境中,同时使用实时操作系统与μC/GUI,既可以发挥优先级的实时性,又能实现良好的人机界面。

本文使用Cortex-M3内核的STM32平台,介绍了基于STM32平台的μC/OS-II上的μC/GUI移植过程,并在此基础上开发了基于μC/GUI的图形用户界面。

1 μC/GUI结构框架1.1 μC/GUI的文件组织μC/GUI软件采用模块化组织架构,其中较为重要的文件目录是配置文件目录Config和GUI库文件目录。

考虑到未来升级方便,建议保持μC/GUI原有的目录结构,这样升级到新版本时只要覆盖原文件目录即可,而不会改变整个工程的文件路径。

μC/GUI是一个源代码开放的图形系统,它提供了丰富的资源,包括二维绘图库,多字体、可扩充的字符集,Unicode,位图显示,多级RGB颜色管理及灰度处理调整机制,动画优化显示,具有Windows风格的对话框和预定义控件(按钮、编辑框、列表框、进度条、单选复选框、滑动条等);同时,支持键盘、鼠标、触摸屏等输入设备和双LCD的输出,提供占用极少RAM的窗口管理体系。

各个子目录的路径及功能支持如表1所列。

1.2 μC/GUI的层次结构μC/GUI内核提供多种图形显示功能,用户程序通过API函数接口调用μC/GUI函数库中的各个功能函数,然后各个功能函数通过调用硬件驱动实现图形界面显示。

stm32之UCGUI3.90a移植教程-裸奔-不带触摸版本_V1.0

stm32之UCGUI3.90a移植教程-裸奔-不带触摸版本_V1.0

uCGUI3.90a移植教程声明:本教程是作者学习uCGUI过程中的笔记,最后整理出来,献给初学者,旨在带领初学者入门uCGUI,仅供学习之用,不得用于商业。

如需转载,请注明出处。

作者:Stone_up时间:2013-08-01版本:V1.0说明平台: stm32f103zet6 TFTLCD型号: 2.8寸9341控制器ucgui源码: 3.90a版本触屏:不带触屏(后续更新)操作系统:不支持移植教程一、准备工作:(一)源码:准备3.90版本的UCGUI源码注:如果需要跑GUIDEMO,那么还需准备GUIDEMO源码。

(二)LCD底层驱动:准备LCD屏的底层驱动,接口函数如下:1、设置坐标点;static void lcd_set_cursor(u16 xpos, u16 ypos);2、在指定点画指定颜色的点;void lcd_set_point(u16 xpos, u16 ypos, u16 color);3、读取某个点的颜色值;u16 lcd_get_point(u16 x, u16 y);4、在指定区域填充颜色(开窗口的方式,速度更快);void lcd_window_fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 color);5、LCD屏初始化(主要是出厂初始化代码);void ili9341_initialize(void);注:这里列出了和UCGUI的接口函数,这些函数的具体实现需要根据自己的LCD屏具体实现这些函数。

二、移植过程(一)把UCGUI源码copy到自己的工程中,UCGUI文件夹下面,方便管理;(二)添加UCGUI源码到工程中,放在对应的组下面,方便管理,如图:(三)添加头文件路径,如图:(四)打开GUI_Config文件夹,编辑GUIConf.h文件,内容如下:#define GUI_OS (0)#define GUI_SUPPORT_TOUCH (0)#define GUI_SUPPORT_UNICODE (1)#define GUI_DEFAULT_FONT &GUI_Font6x8#define GUI_ALLOC_SIZE 40*1024#define GUI_WINSUPPORT 0#define GUI_SUPPORT_MEMDEV 1#define GUI_SUPPORT_AA 1(五)打开GUI_Config文件夹,编辑LCDConf.h文件,内容如下:#define LCD_XSIZE (320)#define LCD_YSIZE (240)#define LCD_BITSPERPIXEL (16)#define LCD_CONTROLLER (-1)#define LCD_FIXEDPALETTE (565)#define LCD_SWAP_RB (1)#define LCD_INIT_CONTROLLER() ili9341_initialize();(六)打开GUI_LCDDriver文件夹,编辑LCDDummy.c文件,内容如下:1、先添加LCD驱动文件的头文件,以便下面函数调用;如:#include "tftlcd.h"2、确保#if (LCD_CONTROLLER == -1) \&& (!defined(WIN32) | defined(LCD_SIMCONTROLLER))中的LCD_CONTROLLER == -1 ,和LCDConf.h中的宏定义对应3、在void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) 函数最后一行添加如下语句:lcd_set_point(xPhys, yPhys, PixelIndex);4、在unsigned int LCD_L0_GetPixelIndex(int x, int y) 函数return语句之前添加如下语句:PixelIndex = lcd_get_point(x, y);5、现在回到main函数1)添加头文#include "GUI.h"#include "GUIDEMO.h"2)在main函数中先调用必要的初始化函数后,再调用GUI_Init(); 函数,这个函数会调用LCD屏的初始化函数3)为了测试UCGUI是否初始化成功,我们先调用几个函数试试,在GUI_Init();下面接着调用如下函数:GUI_SetBkColor(GUI_BLACK);GUI_SetColor(GUI_RED);GUI_Clear();GUI_SetFont(&GUI_Font24_1);GUI_DispStringAt("- - uCGUI disp Function sample - -",4,10);// 延时3s,方便观看结果delay_ms(1000);delay_ms(1000);delay_ms(1000);看看是否把LCD刷成黑色,是否显示红色字符串4)然后再while循环中调用GUIDEMO_main(); 函数,开始运行GUIDEMO(七)定时器中断配置,给UCGUI系统一个时钟(个人观点,仅供参考),否则GUIDEMO程序无法运行1、在这里用定时器2,所以需要配置定时器和NVIC中断,配置函数大家就自己做了,只是这里的定时器配置成2KHz的频率,如果想要界面变化快点,那么提高频率即可;然后我们进入定时器2的中断函数,首先在stm32f10x_it.c 文件中加入外部变量声明extern volatile int OS_TimeMS; 然后加入定时器2中断函数,如下:void TIM2_IRQHandler(void){if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ){TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);OS_TimeMS++;if(OS_TimeMS%20==0){//GUI_TOUCH_Exec(); // 不带触摸不需要这条语句}} }后记作者新浪博客:/s/blog_9763553701018h2h.html技术讨论QQ:2898295180如有bug,恳请指出,欢迎各位网友一起讨论,一起进步,祝大家学业有成。

(转载)在STM32上移植ucGUI之触摸屏

(转载)在STM32上移植ucGUI之触摸屏

在STM32上移植ucGUI之触摸屏(2013-07-0809:16:33)之前的三篇文章分别介绍了如何在STM32裸机上移植ucGUI,移植ucGUI源例程以及ucGUI的存储设备和抗锯齿。

现将STM32裸机上移植ucGUI触摸屏的过程详述如下:1、将正点原子的《触摸屏移植实验》中HARDWRAE/TOUCH目录复制到已经建立好的ucGUI工程目录的HARDWARE文件夹下,并添加touch.c文件和头文件路径。

2、打开ucGUI工程中的GUIConf.h文件,将其中的GUI_SUPPORT_TOUCH和GUI_WINSUPPORT总开关打开。

如下所示:#define GUI_SUPPORT_TOUCH1#define GUI_WINSUPPORT1此时编译程序,会出现四个函数未定义的错误。

3、在GUI_X中添加文件GUI_X_Touch.c,此时编译工程错误消失。

4、在GUI_X_Touch.c中添加预处理命令#include“touch.h”。

然后将其中的GUI_TOUCH_X_MeasureX和GUI_TOUCH_X_MeasureY两个函数改为如下所示的形式:int GUI_TOUCH_X_MeasureX(void){u16x,y;Read_ADS2(&x,&y);return x;}int GUI_TOUCH_X_MeasureY(void){u16x,y;Read_ADS2(&x,&y);return y;}5、由于是在裸机上运行ucGUI程序,对话框程序会阻塞当前进程的执行。

所以需要在定时器中断中不断的去扫描触摸屏的状态。

设置定时器10ms中断一次,在定时器中断处理函数中加入GUI_TOUCH_Exec()语句。

6、在主函数中加入初始化定时器和触摸屏,并在GUI_Init()函数之后加入GUI_CURSOR_Show函数以显示指针。

7、以上就完成了触摸屏的移植操作,下面对触摸屏的工作状态进行配置。

基于STM32F103移植uCGUI详细说明

基于STM32F103移植uCGUI详细说明

STM32平台移植uCGUI详细说明v1.0硬件平台:盘古UE-STM32F103开发板软件平台:RVMDK_v4.20 + uCOS-II_v2.86 + StmLib_v3.5 + uCGUI_v3.9联系方式:淘宝店铺:文档作者:合嵌电子科技有限公司uCGUI是一种嵌入式应用中的图形支持系统.它设计用于为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器的图形用户接口,它适用单任务或是多任务系统环境, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示。

它的设计架构是模块化的, 由不同的模块中的不同层组成, 由一个LCD驱动层来包含所有对LCD的具体图形操作, uCGUI可以在任何的CPU上运行, 因为它是100%的标准C代码编写的。

uCGUI能够适应大多数的使用黑白或彩色LCD的应用, 它提供非常好的允许处理灰度的颜色管理.还提供一个可扩展的2D图形库及占用极少RAM的窗口管理体系.移植准备本文档基于盘古STM32F103开发板进行uCGUI的移植实验,移植的软件基础为RVMDK_v4.20 + uCOS-II_v2.86 + StmLib_v3.5。

具体uCOS-II的移植过程请参见文档《STM32平台移植uCOS-II详细说明》,在移植最后,将通过uCOS-II创建进程运行uCGUI自带DEMO代码,以熟悉其运行流程。

1. 打开盘古UE-STM32F103光盘中的基础例程:27_uCOS-II移植由于此例程已经移植完成uCOS-II_v2.86,因此直接在此基础移植就可以,此例程文件结构如下:2. 下载uCGUI_v3.9源码解压后,有如下文件结构其源代码主要在start文件夹下,Sample是官方制作的一个Demo例程,我们一会再移植的过程中,需要用到里面的文件,这儿跳过,以下是对start作出简介:3.这3关于1.2.3. 在4. 对例程的工程名和输出文件名等进行相应的修改。

STM32如何移植uCGUI,看这里!

STM32如何移植uCGUI,看这里!

STM32 如何移植uCGUI,看这里!
第一部分:在UCGUI 移植之前
在移植之前,首先要了解在网上下的UCGUI 3.98 源码的文件结构是。

UCGUI 3.98 源码中有三个文件夹:
1)tool 文件夹是用来使用一些uCgui 的上位机程序,基本都是字体和模板查看之类的.
2)sample 文件夹下面是已经别人帮你写好了很多有用的东西,像跟操作系统有关的GUI_X 或者一些模板(后面我们会用到的自己定义的Demo),或者是gui 配置.后面再一一详细叙说这个文件夹的功能.
3)Start 文件夹里面,这是我们最主要的文件夹.里面就包含了uCGUI 的源代码,uCGUI 的作者把源代码放进vc 里面进行编译了(当然,这是用标准C 语言写的程序,所以我们可以放在任何c 语言平台下编译而不会担心兼容性问题,这个uCGUI 在这方面做的算是完美了),所以,我们可以在vc 平台下写界面,然后再把代码拷进我们的下位机编译器进行编译,这样子效率就会非常高了。

Start 文件夹目录内容:
Config,配置文件;。

基于STM32嵌入式系统的uCGUI移植与实现

基于STM32嵌入式系统的uCGUI移植与实现

图 1 STM3在 STM32 处理器与 FY70 - 8048 - 65K LCD 控制器 上移植 UCGUI 的第一步工作是对配置头文件的修改, 根据硬件电路的连接, 以及所连接的 LCD 控制器的具 体情况, 修改配置头文件的相关内容 。具体如下: GUIConf. h 文件用于配置 UCGUI 自身: define GUI_OS ( 1 ) / * 支持多任务操作系统( UCOSII) * / define GUI_SUPPORT_TOUCH ( 1 ) / * 支持触摸屏( 需窗口管理器的支持) * / define GUI_SUPPORT_UNICODE ( 1 ) / * 支持 UNICODE 字符串* / define GUI_DEFAULT_FONT &GUI_Font6x8 / * 定义默认字体 * / define GUI_ALLOC_SIZE 5000 / * 为窗口管理器及内存设备分配的 RAM * / define GUI_WINSUPPORT 1 / * 窗口管理器有效 * / define GUI_SUPPORT_MEMDEV 1 / * 内存设备有效 * / define GUI_SUPPORT_AA 1 / * 抗锯齿有效 * / LCDConf. h 文件用于配置 LCD 控制器: define LCD_XSIZE ( 800 ) / * 定义 LCD 屏幕宽度 * / define LCD_YSIZE ( 480 ) / * 定义 LCD 屏幕高度 * /
[3 ]

1. 2 目录结构 uCGUI 图形接口采用源代码方式提供, 理解其目录 结构, 对于完成 UCGUI 图形接口的移植是非常重要的 。 uCGUI 图形接口由 Config 配置目录和 LIB 库函数 目录组成 。Config 配置目录中包括 3 个配置头文件, 分 LCD 控制器和触摸 别用于配置 uCGUI 图形接口自身 、 LCDConf. h、 GUITouchConf. h 。 屏, 文件名为 GUIConf. h 、 LIB 库函数目录中又分为多个子目录, 用于实现核 LCD 驱动程序 、 调色板 、 触摸屏驱动程序 、 窗口控件 、 心、

STM32移植UCGUI3.90笔记

STM32移植UCGUI3.90笔记

STM32移植UCGUI3.90笔记在MDK环境下,终于将3.90版本的UCGUI移植到STM32下了,在网上看到的都是例程代码,很少看到有关于在STM32下移植UCGUI的教程方法,为了方便大家,特写此移植方法,大家可以借鉴(有错误之处,望大家指点出来共同讨论!)移植步骤:第一步:首先,得把你的TFT底层驱动写好,既在裸机下,可以正常显示。

第二步:加入UCGUI程序包。

第三步:配置LCDConf.h GUIConf.h GUITouchConf.h(由于我的液晶不带触摸功能,此配置在此不讲。

)配置LCDConf.h文件如下:#ifndef LCDCONF_H#define LCDCONF_H#define LCD_XSIZE (160) //配置TFT的水平分辨率#define LCD_YSIZE (128) //配置TFT的垂直分辨率#define LCD_CONTROLLER (54124) //TFT控制器的名称#define LCD_BITSPERPIXEL (16) //每个像素的位数#define LCD_FIXEDPALETTE (565) //调色板格式#define LCD_SWAP_RB (0) //红蓝反色交换#define LCD_INIT_CONTROLLER() TFT_Init() ; //此处需要定义的是你的TFT 初始化函数#endif /* LCDCONF_H */配置GUIConf.h文件如下:#ifndef GUICONF_H#define GUICONF_H#define GUI_OS (1) //多任务#define GUI_SUPPORT_TOUCH (0) //触摸#define GUI_SUPPORT_UNICODE (1) //Unicode支持#define GUI_DEFAULT_FONT &GUI_Font6x8 //GUI默认字体#define GUI_ALLOC_SIZE 5000 //动态内存的大小#define GUI_WINSUPPORT 1 //窗口控件支持#define GUI_SUPPORT_MEMDEV 1 //支持内存设备#define GUI_SUPPORT_AA 1 /* Anti aliasing available */#endif /* Avoid multiple inclusion */第四步:最关键的一步。

基于STM32的uCGUI移植和优化

基于STM32的uCGUI移植和优化

基于STM32的uCGUI移植和优化移植篇首先,我们需要准备的东西有uCGUI3.90,这个版本是大家现在用的比较多的,效率也比较高,别人都是这么评论的,至于其他版本的,我没有接触很多,所以不能过多评论.uCGUI有三个文件夹,一个是tool,这个文件夹是用来使用一些uCgui的上位机程序,基本都是字体和模板查看之类的.在sample文件夹下面是已经别人帮你写好了很多有用的东西,像跟操作系统有关的GUI_X或者一些模板(后面我们会用到的自己定义的Demo),或者是gui配置.后面再一一详细叙说这个文件夹的功能.在Start文件夹里面,这是我们最主要的文件夹.里面就包含了uCGUI的源代码,uCGUI的作者把源代码放进vc里面进行编译了(当然,这是用标准C语言写的程序,所以我们可以放在任何C语言平台下编译而不会担心兼容性问题,这个uCGUI在这方面做的算是完美了),所以,我们可以在vc平台下写界面,然后再把代码拷进我们的下位机编译器进行编译,这样子效率就会非常高了.(像51那时候写界面就是疯狂的一次一次的烧,真是纠结..).然后这里放的就是uCGUI的源代码了,在GUI文件夹下面.这则是每个文件夹的功能(参考uCGUI中文手册,翻译).大概看一下就可以了,这个跟我们移植的关系不大,关键点是带*的可以不包含进去(待会配置会讲到.).然后其他的都要包含进去.接着我们要把我们的文件包含进我们已经搭建好的工程,这里说明下我们的工程要求.一般来说,我们要画一个图形,最基本的就是从点开始,从点到线,从点到面...,所以在已经建好的工程里面你要能点亮你的屏幕,能点出最基本的点,能填充出最基本矩阵(这是uCGUI最包含的函数),反正我移植的时候涉及到的包括三个函数,LCD_Init();LCD_Draw_Point(x,y,color),LCD_Fillcircuit(x1,x2,y1,y 2).这三个函数是必须的,后面也会说明如何把这三个函数进行填充.当我们把文件复制进去的时候,再加上我们一开始已经创建好的工程的时候,文件结构差不多就是这个样子了,截图如下user包括,main函数就是我们初始化和函数调用,绘图用的文件,另外那几个文件相信大家都明白了把,tft_lcd.c就是你在,没有移植uCGUI的情况下,纯液晶屏驱动,这里建议把液晶屏的API和最底层驱动(API就是画圆啊,画椭圆啊,清除屏幕之类的,底层驱动就是驱动液晶屏的管脚运作,fsmc初始化,时钟配置之类的),不过我这里也是集成在一起了,比较懒,大家别学.其他文件夹我都包含进去了,在没包含进去的时候,编译是可以通过的,但是,那么多文件包含进去,有些配置还是没有设定好的.所以会有错误,蛮编译一下.没事的.这里我们需要修改的文件只有这几个:,,,这是ucgui开放给我们的用户层的文件,在ucgui中,lcdDrive文件夹要自己加进去,GUI_X.c也是,另外三个文件都是包含了,在GUIConf.h中1 #ifndef GUICONF_H2#define GUICONF_H34#define GUI_OS (0) // 这里指的是对操作系统的支持,因为我们这里只有单纯的移植uCGUI,5// 所以,要把这个关闭,不然后面会有很多东西编译进去6// 不然到时候编译的时候会发生很多你无法修改的错误7#define GUI_SUPPORT_TOUCH (0) // 这里则是对触摸屏的支持,触摸屏我是能做,但是没有用,8//所以省去麻烦,把触摸屏关掉,相信移植好之后,要支持触摸屏大家都会有门路了9#define GUI_SUPPORT_UNICODE (1) // UNICODE编码支持,如果大家只是单纯的想用英文显示,而不移植中文字库进去,10//这个是可以关掉的,因为UNICODE是向下支持的,所以开不开无所谓11 // 反正都是能够正常显示的12#define GUI_DEFAULT_FONT &GUI_Font6*8 // 这里是设定默认字体的,我们可以在要写什么字的时候把该字号的字体.13//c包含进我们的主函数里面,所以这里不用改14#define GUI_ALLOC_SIZE 5000 // 这里讲的是动态内存机制15// 这里rgb接口模式的可能会有用到,uCGUI就是在我们的ram开辟一块空间,//然后uCGUI把运算好的每个点都放进我们主控ram里面的空间16// 所以,这里就相当于把写进液晶gram里面的操作变成了写进主控ram里面,//那么大家可能就会问了,干嘛这么多次一举,直接写进去不就可以了1718/*原理: 一般来说,在大的屏幕上面(4.0以上吧,印象中),都是没有控制器,(像我的液晶屏就是spfd5420,当然,19不同的屏幕的液晶主控都是不一样的,但是寄存器操作都是差不多的,20所以有些初始化配置还是能互用的.)所以呢,这时候我们要用到的就只有RGB接口了,21 RGB要求我们要不断的刷新屏幕,刷新率越高,效果就越好,因为一般这种用来做动态的,uCGUI就是属于静态类型的22像如果我们要用stm32主控做视频应用的时候,就是动态的,我们需要不断的刷新屏幕,但是当我们主控一边运算,23一边往液晶接口送数据的时候,会有明显刷屏的感觉(运算->画点->运算->画点....,这个运算24 ->运算.......画点->画点->画点...是不一样的,因为对屏幕一直画点,填充,而中间不用插入运算,25刷一个屏幕时间时间倍速差别是非常巨大的,后面大家也会见识到这种差别.),所以,用GUI申请的空间里面26边运算,边填充,填充完再一次性运出去(这里可以通过DMA控制FSMC总线,不断的从外置SRAM往GRAM自动搬运数据,27这是不用主控去插手的,所以,主控大部分时间是负责运算,其他时间可以空闲出来, 28让DMA自己去忙活),同理,因为dma跟cpu的分工,所以,这里同样的把画点,画点,运算,运算不完全的分开了,29屏幕刷新速度非常之可观(DMA的速度相比大家还是非常了解的,它就是为速度而生的.),*/3031//#define GUI_ALLOC_SIZE 1024*1024/* Size of dynamic memory ... For WM and memory devices*/ 3233/************************************************************** *******34 *35 * Configuration of available packages36 */3738#define GUI_WINSUPPORT 1 // 这个是窗口支持,一般开始开着的39#define GUI_SUPPORT_MEMDEV 1 // 内存控制,开40#define GUI_SUPPORT_AA 0 // 抗锯齿,为了性能着想,还是关了比较好4142#endif /* Avoid multiple inclusion */复制代码GUITouchConf.h是有关于触摸屏配置的,这里我们就略过了.1 #ifndef LCDCONF_H2#define LCDCONF_H34/********************************************************************* 5*6* General configuration of LCD7*8********************************************************************** 9*/1011/*12 * 这个定义的是你x轴的长度,像我这里的屏幕长为400个像素13 */14#define LCD_XSIZE (400)1516/*17 * 这里这是屏幕的宽18 */19#define LCD_YSIZE (240) /* Y轴长度 */2021/*22 * 这里是屏幕的颜色有多少个位23 */24#define LCD_BITSPERPIXEL (16) /* 定义数据长度为16bit*/2526/*27 * 控制器类型,如果你里面有包含这些判断变量,这个最好改成你认识的28 */29#define LCD_CONTROLLER 9325 /* 定义控制器类型 */303132#endif /* LCDCONF_H */复制代码配置层的东西我们都已经搞定了,接下来我们要修改的是uCGUI开放给我们的用户层的东西,GUI_X.c可以直接拷进去,这个是用户层和系统层的关联文件,一些demo也会用到这个文件的时间函数或者延迟函数,所以这个文件拷进去放着就可以了.1 #include "GUI.h"2 #include "GUI_X.h"34/********************************************************************* 5*6* Global data7*/8volatile int OS_TimeMS;910/********************************************************************* 11*12* Timing:13* GUI_X_GetTime()14* GUI_X_Delay(int)16 Some timing dependent routines require a GetTime17 and delay function. Default time unit (tick), normally is18 1 ms.19译:一些需要时间的相关函数需要用到gettime和延迟.20默认时间单位为1ms.21*/2223int GUI_X_GetTime(void) {24return0;25 }2627void GUI_X_Delay(int ms)28 {29 }3031/********************************************************************* 32*33* GUI_X_Init()34*35* Note:36* GUI_X_Init() is called from GUI_Init is a possibility to init37* some hardware which needs to be up and running before the GUI.38* If not required, leave this routine blank.39*40* 译:GUI_X_Init()是在gui_init()调用前,gui启动或者运行前准备.41* 如果不是必须的,可以把这个函数留空白.42*/4344void GUI_X_Init(void)45 {4647 }48495051/********************************************************************* 52*53* GUI_X_ExecIdle54*55* Note:56* Called if WM is in idle state57* 译:视窗管理器空闲时候调用58*/60void GUI_X_ExecIdle(void) {}6162/********************************************************************* 63*64* Logging: OS dependent6566Note:67 Logging is used in higher debug levels only. The typical target68 build does not use logging and does therefor not require any of69 the logging routines below. For a release build without logging70 the routines below may be eliminated to save some space.71 (If the linker is not function aware and eliminates unreferenced72 functions automatically)73译:系统日志层应用程序7475*/7677void GUI_X_Log (const char *s) {}78void GUI_X_Warn (const char *s) {}79void GUI_X_ErrorOut(const char *s) {}复制代码在uCGUI和底层驱动的接口文件时LCDDriver.c,大家打开文件夹可以看到这几个文件:lcdwin.c,lcdnull.c,lcdDummy.c,这三个文件你随便修改哪个都行,一开始我是直接修改lcdnull.c的,不过一开始没经验,一直不能正常调用我的uCGUI函数,所以,我的队友告诉我,要修改另外一个(lcdwin.c),这次才反应过来,理论上,修改lcdnull.c也是可以的,就是一些细节性的东西可以要多注意点.下面我讲解下怎么修改lcdwin.c这个文件.源文件我先贴出来:#if defined(WIN32) && !defined(LCD_SIMCONTROLLER)#include <windows.h>#include "LCD.h"#include "LCD_Private.h" /* include LCDConf.h */#include "LCDSIM.h"#include "GUI_Private.h"#include "memory.h"/*********************************************************************** Defines***********************************************************************#if LCD_BITSPERPIXEL <= 8#define PIXELINDEX U8#else#define PIXELINDEX WORD#endif#ifdef WIN32#ifndef ASSERT#define ASSERT(Val) \if (!(Val)) \MessageBox(NULL,"...in file "__FILE__,"Assertion failed...",MB_OK);#endif#endif#ifdef LCD_ASSERT#undef LCD_ASSERT#endif#define LCD_ASSERT(v) ASSERT(v)#ifndef LCD_DISPLAY_INDEX#define LCD_DISPLAY_INDEX 0#endif/*********************************************************************** Macros for internal use*/#ifdef _DEBUGstatic int _CheckBound(unsigned int c) {unsigned int NumColors = LCD_BITSPERPIXEL > 8 ? 0xffff : (1 << LCD_BITSPERPIXEL) - 1; if (c > NumColors) {GUI_DEBUG_ERROROUT("LCDWin::SETPIXEL: parameters out of bounds");return 1;}return 0;}#define SETPIXEL(x, y, c) \if (!_CheckBound(c)) { \LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX); \}#else#define SETPIXEL(x, y, c) LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX)#endif#define XORPIXEL(x, y) _XorPixel(x,y)/*********************************************************************** Static code************************************************************************//*********************************************************************** _XorPixel*/static void _XorPixel(int x, int y) {unsigned int Index = LCD_L0_GetPixelIndex(x,y);LCDSIM_SetPixelIndex(x, y, LCD_NUM_COLORS-1-Index, LCD_DISPLAY_INDEX);}/*********************************************************************** _DrawBitLine1BPP*/static void _DrawBitLine1BPP(int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {LCD_PIXELINDEX Index0 = *(pTrans+0);LCD_PIXELINDEX Index1 = *(pTrans+1);x+=Diff;switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {case 0: /* Write mode */do {LCDSIM_SetPixelIndex(x++,y, (*p & (0x80>>Diff)) ? Index1 : Index0,LCD_DISPLAY_INDEX);if (++Diff==8) {Diff=0;p++;}} while (--xsize);break;case LCD_DRAWMODE_TRANS:do {if (*p & (0x80>>Diff))LCDSIM_SetPixelIndex(x,y, Index1, LCD_DISPLAY_INDEX);if (++Diff==8) {Diff=0;p++;}} while (--xsize);break;case LCD_DRAWMODE_XOR:;do {if (*p & (0x80>>Diff)) {int Pixel = LCDSIM_GetPixelIndex(x,y, LCD_DISPLAY_INDEX);LCDSIM_SetPixelIndex(x,y, LCD_NUM_COLORS-1-Pixel, LCD_DISPLAY_INDEX);}x++;if (++Diff==8) {Diff=0;p++;}} while (--xsize);break;}}/*********************************************************************** _DrawBitLine2BPP*/#if (LCD_MAX_LOG_COLORS > 2)static void _DrawBitLine2BPP(int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {LCD_PIXELINDEX Pixels = *p;int CurrentPixel = Diff;x += Diff;switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {case 0:if (pTrans) {do {int Shift = (3 - CurrentPixel) << 1;int Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift;LCD_PIXELINDEX PixelIndex = *(pTrans + Index);SETPIXEL(x++, y, PixelIndex);if (++CurrentPixel == 4) {CurrentPixel = 0;Pixels = *(++p);} while (--xsize);} else {do {int Shift = (3 - CurrentPixel) << 1;int Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; SETPIXEL(x++, y, Index);if (++CurrentPixel == 4) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);}break;case LCD_DRAWMODE_TRANS:if (pTrans) {do {int Shift = (3 - CurrentPixel) << 1;int Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; if (Index) {LCD_PIXELINDEX PixelIndex = *(pTrans + Index);SETPIXEL(x, y, PixelIndex);}x++;if (++CurrentPixel == 4) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);} else {do {int Shift = (3 - CurrentPixel) << 1;int Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; if (Index) {SETPIXEL(x, y, Index);}x++;if (++CurrentPixel == 4) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);}break;}}#endif/*********************************************************************** _DrawBitLine4BPP*/#if (LCD_MAX_LOG_COLORS > 4)static void _DrawBitLine4BPP(int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) {LCD_PIXELINDEX Pixels = *p;int CurrentPixel = Diff;x += Diff;switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {case 0:if (pTrans) {do {int Shift = (1 - CurrentPixel) << 2;int Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;LCD_PIXELINDEX PixelIndex = *(pTrans + Index);SETPIXEL(x++, y, PixelIndex);if (++CurrentPixel == 2) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);} else {do {int Shift = (1 - CurrentPixel) << 2;int Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;SETPIXEL(x++, y, Index);if (++CurrentPixel == 2) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);}break;case LCD_DRAWMODE_TRANS:if (pTrans) {do {int Shift = (1 - CurrentPixel) << 2;int Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;if (Index) {LCD_PIXELINDEX PixelIndex = *(pTrans + Index);SETPIXEL(x, y, PixelIndex);}x++;if (++CurrentPixel == 2) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);} else {do {int Shift = (1 - CurrentPixel) << 2;int Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift;if (Index) {SETPIXEL(x, y, Index);}x++;if (++CurrentPixel == 2) {CurrentPixel = 0;Pixels = *(++p);}} while (--xsize);}break;}}#endif/*********************************************************************** _DrawBitLine8BPP*/#if (LCD_MAX_LOG_COLORS > 16)static void _DrawBitLine8BPP(int x, int y, U8 const*p, int xsize, const LCD_PIXELINDEX*pTrans) {LCD_PIXELINDEX pixel;if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {if (pTrans) {for (;xsize > 0; xsize--,x++,p++) {pixel = *p;SETPIXEL(x, y, *(pTrans+pixel));}} else {for (;xsize > 0; xsize--,x++,p++) {SETPIXEL(x, y, *p);}}} else { /* Handle transparent bitmap */if (pTrans) {for (; xsize > 0; xsize--, x++, p++) {pixel = *p;if (pixel) {SETPIXEL(x+0, y, *(pTrans+pixel));}}} else {for (; xsize > 0; xsize--, x++, p++) {pixel = *p;if (pixel) {SETPIXEL(x+0, y, pixel);}}}}}#endif/*********************************************************************** _DrawBitLine16BPP*/#if (LCD_BITSPERPIXEL > 8)static void _DrawBitLine16BPP(int x, int y, U16 const*p, int xsize, const LCD_PIXELINDEX*pTrans) {LCD_PIXELINDEX pixel;if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS)==0) {if (pTrans) {for (;xsize > 0; xsize--,x++,p++) {pixel = *p;SETPIXEL(x, y, *(pTrans+pixel));}} else {for (;xsize > 0; xsize--,x++,p++) {SETPIXEL(x, y, *p);}}} else { /* Handle transparent bitmap */if (pTrans) {for (; xsize > 0; xsize--, x++, p++) {pixel = *p;if (pixel) {SETPIXEL(x+0, y, *(pTrans+pixel));}}} else {for (; xsize > 0; xsize--, x++, p++) {pixel = *p;if (pixel) {SETPIXEL(x+0, y, pixel);}}}}}#endif/********************************************************************* ** Exported code*********************************************************************** *//********************************************************************* ** LCD_L0_DrawPixel** Purpose: Writes 1 pixel into the display.*/void LCD_L0_DrawPixel(int x, int y) {if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {XORPIXEL(x, y);} else {SETPIXEL(x, y, LCD_COLORINDEX);}}/********************************************************************* ** LCD_L0_DrawHLine*/void LCD_L0_DrawHLine(int x0, int y, int x1) {if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {for (;x0 <= x1; x0++) {XORPIXEL(x0, y);}} else {for (;x0 <= x1; x0++) {SETPIXEL(x0, y, LCD_COLORINDEX);}}}/********************************************************************* ** LCD_L0_DrawVLine*/void LCD_L0_DrawVLine(int x, int y0, int y1) {if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {while (y0 <= y1) {XORPIXEL(x, y0);y0++;}} else {while (y0 <= y1) {SETPIXEL(x, y0, LCD_COLORINDEX);y0++;}}}/********************************************************************* ** LCD_L0_FillRect*/void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {for (; y0 <= y1; y0++) {LCD_L0_DrawHLine(x0,y0, x1);}}/********************************************************************* ** LCD_L0_DrawBitmap*/void LCD_L0_DrawBitmap(int x0, int y0,int xsize, int ysize,int BitsPerPixel,int BytesPerLine,const U8* pData, int Diff,const LCD_PIXELINDEX* pTrans){int i;/*Use DrawBitLineXBPP*/for (i=0; i<ysize; i++) {switch (BitsPerPixel) {case 1:_DrawBitLine1BPP(x0, i+y0, pData, Diff, xsize, pTrans);break;#if (LCD_MAX_LOG_COLORS > 2)case 2:_DrawBitLine2BPP(x0, i+y0, pData, Diff, xsize, pTrans);break;#endif#if (LCD_MAX_LOG_COLORS > 4)case 4:_DrawBitLine4BPP(x0, i+y0, pData, Diff, xsize, pTrans);break;#endif#if (LCD_MAX_LOG_COLORS > 16)case 8:_DrawBitLine8BPP(x0, i+y0, pData, xsize, pTrans);break;#endif#if (LCD_BITSPERPIXEL > 8)case 16:_DrawBitLine16BPP(x0, i+y0, (const U16 *)pData, xsize, pTrans); break;#endif}pData += BytesPerLine;}}/********************************************************************* ** LCD_L0_DrawBitmap* Purpose:* Sets the original position of the virtual display.* Has no function at this point with the PC-driver.*/void LCD_L0_SetOrg(int x, int y) {GUI_USE_PARA(x);GUI_USE_PARA(y);}/********************************************************************* ** Support for verification** Purpose:* The following routines are implemented, but have no functionility * at this point. The reason is that these functions are supposed* to supervise the hardware, which for obvious reasons can not be * done in a simulation.*/#if LCD_VERIFYint LCD_GetErrStat(void) {return 0;}void LCD_ClrErrStat(void) {}int LCD_GetErrCnt (void) {return 0;}#endif/********************************************************************* ** LCD_On* LCD_Off** (Not supported in Simulation)*/void LCD_Off (void) {}void LCD_On (void) {}/********************************************************************* ** LCD_L0_SetLUTEntryvoid LCD_L0_SetLUTEntry(U8 Pos, LCD_COLOR color) {LCDSIM_SetLUTEntry(Pos, color, LCD_DISPLAY_INDEX);}/*********************************************************************** LCD_L0_Init*/int LCD_L0_Init(void) {return 0;}int LCD_L0_CheckInit(void) {return 0;}/*********************************************************************** LCD_L0_ReInit** Purpose:* This routine is supplied for compatibility and interchangability of * "C"-sources with embedded versions of the driver. It has no real* effect in the PC-version as there is simply no need to re-initialize * the LCD since it is just simulated anyhow.*/void LCD_L0_ReInit (void) {}unsigned LCD_L0_GetPixelIndex(int x, int y) {return LCDSIM_GetPixelIndex(x,y, LCD_DISPLAY_INDEX);}/*********************************************************************** LCD_L0_XorPixel** Purpose:* Inverts 1 pixel of the display.*/void LCD_L0_XorPixel(int x, int y) {XORPIXEL(x, y);}/*********************************************************************** LCD_L0_SetPixelIndex** Purpose:* Writes 1 pixel into the display.*/void LCD_L0_SetPixelIndex(int x, int y, int ColorIndex) {SETPIXEL(x, y, ColorIndex);}#elsevoid LCDWin_c(void);void LCDWin_c(void) { } /* avoid empty object files */#endif /* defined(WIN32) && defined(LCD_USE_WINSIM) */这个文件可能有点大,500多行,都是密密麻麻的代码,不过,我们要想使我们的uCgui能够使用,要修改的函数其实也就每几句.我先给大家讲解下这里面函数的关系:#if LCD_BITSPERPIXEL <= 8#define PIXELINDEX U8#else#define PIXELINDEX WORD#endif复制代码这里我们定义的是16位的像素点(在前面那三个配置文件里面),定义为word.#define SETPIXEL(x, y, c) LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDE X)#endif#define XORPIXEL(x, y) _XorPixel(x,y)复制代码这里定义的是显示点的函数,我们需要把所有LCDSIM_SetPixelIndex(x, y, c, LCD_DISPLAY_INDEX),都换成你的画点函数,比如我这里使用的是LCD_L0_SetPixelIndex(x轴坐标,y轴坐标,该点颜色);然后呢,就是修改LCD_L0_FillRect(int x0, int y0, int x1, int y1);这个是填充矩形函数,你可以直接把函数里面的东西清空,然后写上自己在底层硬件驱动的api,我的函数优化得体无完肤了,基本没有办法再拷贝过来,所以待会讲这函数的时候,直接跳过去.最后最重要的要修改的就是LCD_L0_Init(void);这函数里面可以直接填充你的初始化函数,好了,剩下基本就不需要修改了,其他的修改就留给优化了.下面我给大家详细讲解下每个函数的用途1/******************************************************************** *2*3* LCD_L0_SetPixelIndex4*/5void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {6/* 设定指定点颜色值 */7 }89/******************************************************************** *10*11* LCD_L0_GetPixelIndex12*/13 unsigned int LCD_L0_GetPixelIndex(int x, int y) {14/* 取得某点像素颜色值,并返回 */15 }1617/******************************************************************** *18*19* LCD_L0_XorPixel20*/21void LCD_L0_XorPixel(int x, int y) {22/* 反转像素函数 */23 }2425/******************************************************************** *26*27* LCD_L0_DrawHLine28*/29void LCD_L0_DrawHLine(int x0, int y, int x1) {30/* 绘制水平线函数 */31 }3233/******************************************************************** *34*35* LCD_L0_DrawVLine36*/37void LCD_L0_DrawVLine(int x, int y0, int y1) {38/* 绘制垂直线函数 */39 }41/******************************************************************** *42*43* LCD_L0_FillRect44*/45void LCD_L0_FillRect(int x0, int y0, int x1, int y1) {46/* 填充矩阵函数 */47 }4849/******************************************************************** *50*51* LCD_L0_DrawBitmap52*/53void LCD_L0_DrawBitmap(int x0, int y0,54int xsize, int ysize,55int BitsPerPixel,56int BytesPerLine,57const U8 GUI_UNI_PTR * pData, int Diff,58const LCD_PIXELINDEX* pTrans)59 {60/* 画位图函数 */61 }6263/******************************************************************** *64*65* LCD_L0_SetOrg66*/67void LCD_L0_SetOrg(int x, int y) {68/* 该函数保留 */69 }7071/******************************************************************** *72*73* LCD_On / LCD_Off74*/75void LCD_On (void) {76/* 开启LCD */77 }78void LCD_Off(void) {79/* 关闭LCD */8182/******************************************************************** *83*84* LCD_L0_Init85*/86int LCD_L0_Init(void) {87/* LCD初始化 */88 }8990/******************************************************************** *91*92* LCD_L0_SetLUTEntry93*/94void LCD_L0_SetLUTEntry(U8 Pos, LCD_COLOR Color) {95/* 修改 LCD 控制器的 LUT 的中的单个条目 */96 }9798#else99100void LCDNull_c(void);101void LCDNull_c(void) {} /* 请保持这个函数为空 */102103#endif复制代码移植讲到这边差不多就结束了,因为是凭着自己的感觉写的,所以可能很多东西讲的不是很清楚,有需要我精讲的可以联系我,我会陆续修改,接下来我们开始我们的优化之旅补充:优化篇这里的优化会介绍两种模式,GPIO口模拟程序,FSMC模块模式.FSMC模式只有在STM32大容量模式的主控才有的,优化起来效果确实很是最好的,因为当你根据液晶屏ic配置好fsmc的时候,液晶屏的寄存器和GRAM 就会被映射到系统的4G内存空间的某一块区域,我们往指定地址写数据或读数据,FSMC就会自动帮你把数据送到液晶屏控制器上面了,所以这里面我们省去了对GPIO管脚和接口的操作(...这个确实很强大,因为你可以花更多的时间来进行运算,每个点都是通过指令来产生的,产生指令也是需要时间的,同样,模拟IO口时序也是需要时间的,把这部分时间剩下来,是非常可观的),至于一些人不理解FSMC其实也不是很打紧啦,你就把GRAM和液晶屏寄存器想象成一个完整的外置SRAM就可以了,因为他们的时序都是同一个原理的,而FSMC就是会自动帮你模拟各种IO口操作,我把它简单的理解成(你写的io口操作程序,他用硬件来实现了).相信大家都有看到别人移植好的demo程序,里面最开始以来就是一个speedDEMO,这个是测试每秒钟可以通过计算可以画多少个点,里面包含了随即填充矩阵函数.分数越高,代表着你刷频也就是越快,当然,跟着我的脚步走,可以快到把刷这个字去掉(不严格意义上);在做优化的时候,我们得提前做好准备,因为优化更多代表着是结构性的破坏,可读性的疯狂下降,因为从最底层的函数开始一层一层封装上去,使得函数可以很容易的去理解调用,我们优化就是拆开这些函数调用,并把一些有关硬件层的驱动进行修改,对算法进行更新.举个函数调用的例子,填充矩阵:这个比较大家可看可不看,涉及到一些汇编的知识.略过对后面的理解没有问题.1void fill_Rect(int v, int h, int x, int y)2 {3for (i<v)4 {5for (j<h)6 {7 Darw_Point(a,b);8 }9 }10 }1112void Darw_Point(int x,int y)13 {14 Set_LCD_reg();15 Set_LCD_gram();16 }1718void Set_LCD_reg()19 {20/* 写入寄存器 */21 }2223void Set_LCD_gram()24 {25/* 写入显存 */26 }复制代码这是我随便写的一个函数,我们差不多都是这样子调用一个写点的函数把,通过计算可得,假设我们要绘制一个100*100的矩阵,那么就要调用10000次Darw_Point函数,10000次Set_LCD_reg函数,10000Set_LCD_gram()函数,而每次调用一个函数的时候,要包括如下过程:1.把要传递的参数压入堆栈中2.把上一层程序的返回地址压入堆栈中3.对程序的运行指针进行偏移操作,指向调用程序的入口地址4.执行程序时候如果有需要要进行堆栈保护5.执行程序完毕,堆栈要进行释放,还原给调用它的函数使用6.弹出返回地址7.返回,并继续执行上层程序.而真正的,我们执行程序的时候,嵌套了那么多层的调用,执行的只有一个寄存器赋值,所以系统更多时候是在疯狂的进行压栈和出栈活动,如果我们把这些时间都去掉,效率就是呈现几何倍数增长,这种是毋庸置疑的.出了通过对函数进行拆解,算法和硬件的结合也是非常重要的,像你画个矩形,一个通过点来填充,通过直线来填充,甚至,为什么你没有想到通过矩阵来填充呢?有时候想法就是这样,这在很多IC上是可以很轻松的实现的,前提是你得通读datasheet.具体的我通过函数来为大家进行一一讲解:这是优化后的填充点函数:/*********************************************************************已经最优化** LCD_L0_SetPixelIndex** Purpose:* Writes 1 pixel into the display.*/void LCD_L0_SetPixelIndex(int x, int y, int ColorIndex){/* 填充x轴坐标和y轴坐标 */*(__IO uint16_t *)(Bank4_LCD_C) = 0x0200;*(__IO uint16_t *)(Bank4_LCD_D) = y;*(__IO uint16_t *)(Bank4_LCD_C) = 0x0201;*(__IO uint16_t *)(Bank4_LCD_D) = 399 - x;/* 写显存前准备 */*(__IO uint16_t *)(Bank4_LCD_C) = 0x0202;/* 写入数据 */*(__IO uint16_t *)(Bank4_LCD_D) = ColorIndex;}复制代码与优化前的进行对比:这里的的数据全部改成对地址进行操作(BANk4_LCD_D和C都是被映射了的内存地址).模拟IO口可能会有差别大家在进行写函数的时候,对管脚进行配置都是直接调用库函数的setbit或者resetbit来进行的,我们可以直接查询库函数,对寄存器进行操作: void GPIO_SetBits ( GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)Sets the selected data port bits.参数:GPIOx,: where x can be (A..G) to select the GPIO peripheral.GPIO_Pin,: specifies the port bits to be written. This parameter can be any combination of GPIO_Pin_x where x can be (0..15).返回值:None在文件stm32f10x_gpio.c第358行定义。

基于STM32的emWin系统应用实例

基于STM32的emWin系统应用实例

基于STM32的emWin系统应用实例作者:祝玲钟涛来源:《中国新通信》2017年第12期【摘要】 emWin系统在嵌入式设备中主要使用方向是文本显示、实时数据显示、传递数据等;根据对emWin的二次开发和利用可以自定义很多控制组件或者子项目,源代码编写完成后的编译下载由于emWin系统第三方插件原因存在差异,从子项目的开发到产品的测试运用均值得关注。

【关键词】 emWin 二次开发项目应用一、应用前景此项目利用emWin系统与STM32单片机通信、人机交互、设计工程控制界面等。

最后,将所有的子项目全部合并成了一个完整的项目,其具备图形显示、输入输出交互、简易工具设计、数字控件等功能,能够满足基本生产环境需求。

二、emWin下载协议HMI设备是enWin系统的载体和体现,为了使用过程中达到方便、快捷、高效的目的,我们对emWin系统进行了再升级,升级后的emWin系统在源代码下载时相对于以往的串口下载方式在速度上提升了很大的空间。

经改进后的下载协议有以下两种方式:2.1 传统下载方式——串口联机下载此下载方式即利用PC机串口调试设备搜索HMI设备的在线情况以及当前设备的波特率;若正确获取通信数据PC机与HMI设备成功建立通信连接。

在此过程中,因为是循环发送联机指令,所以当emWin系统接收到正确的通信信息后,数据的最前面会有上一次的错误通信信息,因此第一条指令会被当作错误指令。

故在每次发送联机指令前先发送三个0XFF(空指令);此下载方式的缺点,因为利用串口通信,所以在下载速度上受到了绝对性的限制,例如当我们源代码中编译进了图片信息,下载时间会被图片的大小影响,图片越大下载时间越长。

2.2 升级后下载方式——SD卡脱机下载升级后的SD卡脱机下载大大节省了下载时间,同时也不依赖PC机,便于生产环境使用;其下载过程为:将源代码下放到emWin系统,emWin利用第三方插件对源代码进行特定编译,最后生成后缀名为.tft的编译文件,可以将此编译文件利用插件将其导出到本地,再装载进SD卡,这样利用装载有编译文件的SD卡就可以为任意一台emWin系统设备脱机下载程序,而且速度大大提高。

STM32平台的μC/GUI移植与图形界面设计

STM32平台的μC/GUI移植与图形界面设计

STM32平台的μC/GUI移植与图形界面设计罗富文;吴辉;康伟;杜文广【期刊名称】《单片机与嵌入式系统应用》【年(卷),期】2012(012)008【摘要】μC/GUI是一种专为嵌入式应用设计的通用图形接口软件。

本文详细介绍了μC/GUI的结构框架和基于STM32平台的μC/OS—Ⅱ上的μC/GUI移植过程,并在此基础上进行图形界面设计;阐述了μC/GUI的窗口管理机制,提出了实现μC/GUI中文小型字库的两种方法并采用存储设备解决了图形显示的闪烁问题。

%μC/GUI is a universal graphical interface software for the embedded application. The structural frame ofμC/GUI andμC/GUI transplant process inμC/OS-Ⅱ based on STM32 platform are introduced, and the graphical interface is designed, μC/GUI window man agement mechanism i s described, two methods are proposed to realizeμC/GUI Chinese small font, and flashing problem of graphical dis- play is solved using storage devices.【总页数】4页(P19-22)【作者】罗富文;吴辉;康伟;杜文广【作者单位】西安工程大学电子信息学院,西安710048;西安工程大学电子信息学院,西安710048;西安工程大学电子信息学院,西安710048;西安工程大学电子信息学院,西安710048【正文语种】中文【中图分类】TP274【相关文献】1.μC/GUI在STM32F103上的移植 [J], 杨洁雨;周泽满;徐海贤2.基于嵌入式STM32平台的μC/GUI人机交互界面设计 [J], 王宪伟;程广亮3.基于 STM32的μC/OS_II 与μC/GUI 整合移植与显示优化 [J], 杨立身;张安伟;王磊;刘康4.基于μC/GUI的嵌入式图形界面设计 [J], 刘滨;刘兵;赵艳华5.基于μC/GUI的嵌入式图形用户界面设计 [J], 冯智年;吴友宇因版权原因,仅展示原文概要,查看原文内容请购买。

uCOS-II在STM32上的移植步骤

uCOS-II在STM32上的移植步骤

uCOS-II在STM32上的移植步骤前言:说点废话,网上有很多关于uCOS-ii 移植的文章,好多都是千篇一律,理论性很强,分析了一大堆虚头巴脑的东西,真想问他们,你确定你分析的这些东西是需要你做的工作吗?实操性严重欠缺。

这方面我也走了很多弯路,下面就将自己的移植过程一步步的记录下来,也给大家做做参考。

首先,简单总结一下移植的大概过程:(1)去uC/OS-ii 官网下载你要移植芯片CPU 的相关案例,不一定完全对应,那就找相应系列吧。

(2)编程环境一般有两种,分别是IAR 和MDK,这个根据你自己的编程环境进行下载。

(3)本案例需要将uC/OS-II 移植到STM32F103ZET6 上,而我使用的编程环境是MDK,很遗憾,官网上提供的案例是基于IAR 的,所以要基于IAR 的案例进行更改。

(4)使用MDK 创建一个无操作系统的最简单程序,确保这个程序能够使用,这样做的目的是为了一步步的排查错误,假如无操作系统时,都有错误,移植过程中也肯定会有编译错误,那么在排查错误的时候也就增加了难度,不会写物操作系统的简单程序怎么办。

那就不要往下看了。

(5)移植的最大的改动主要有两部分,一个是一些头文件的增减,另外一个就是向量表中PendSV_Handler 和SysTick_Handler 的修改。

这里我要吐槽一下,网上说了一大堆关于什么OS_CPU.H 的更改还有各种函数的的分析,这都是扯淡。

这些根本就不用移植者去修改,官网提供的案例都已经提供了,除非你选择移植的CPU 是比较偏的,那么这些东西需要移植者自己去编写。

好了,下面就开始详细的记录怎么去移植。

一、创建一个无操作系统的简单裸板系统1.创建源文件工程文件夹,如下图所示:其中文件夹CMSIS 为内核的接口,包含的文件如下图文件夹STM32_StdPeriph 为固件驱动文件夹,这个把STM32 的固件全都添加进去即可。

文件夹User 为其他文件,如下图所示:文件夹Output 和。

UCGUI移植教程

UCGUI移植教程

UCGUI在STM32上移植教程1 说明l 开发板芯片型号STM32F103VET6l 板载液晶型号ILI9341l 所需准备资料UCGUI3.90源码源码l 一个工程模板一个工程模板为了节约时间,此处所用模板为野火M3工程模板(3.5.0)制作时间---2013-08-07 By NUAA---Kylin2 移植过程讲解2.1 首先打开工工程模板,页面如下,这个模板工程很简单2.2 在工程模板中新建两个文件夹2.2.1 命名为GUI与Mylib2.2.2 在GUI文件夹下添加以下内容l 上述图片为UCGUI3.90源码中的一些文件夹源码中的一些文件夹l 进入UCGUI3.90源码文件夹/Start,将Config文件夹原封不动的拷过来文件夹原封不动的拷过来l 进入UCGUI3.90源码文件夹/Start/GUI文件夹,将其中所有文件夹拷过来文件夹,将其中所有文件夹拷过来l 在GUI文件夹下新建GUI_X文件夹,进入UCGUI3.90源码文件夹/ Sample/ GUI_X文件夹中,如果带操作系统应该拷贝GUI_X_uCOS.c,如果不带操作系统拷贝GUI_X.c,在这里我们将将GUI_X.c拷贝到新建GUI_X文件夹。

文件夹。

2.2.3 各文件夹说明1) An Alias :9个C 文件,主要用于抗锯齿的显示效果。

文件,主要用于抗锯齿的显示效果。

2) ConvertColor :彩色显示的色彩转换支持。

:彩色显示的色彩转换支持。

3) ConvertMono :(b/w )和灰度显示的色彩转换支持。

)和灰度显示的色彩转换支持。

4) Core :核心文件,提供了GUI 基本的功能。

基本的功能。

5) Font :字库。

:字库。

6) JPEG :图片操作函数。

:图片操作函数。

7) LCDDriver :LCD 驱动程序驱动程序8) MenDev :Memorydevice 支持。

这个东西可用在很多情况下,这个东西可用在很多情况下,但最主要的功能是防止在但最主要的功能是防止在项目重叠时,防止屏幕的闪烁。

ucGUI--STM32--移植经验总结

ucGUI--STM32--移植经验总结

单片机交流QQ群:166578859电子邮箱:jitao_yang@ 如果没有找到ucGUI没有提供你所使用的LCD驱动,看完本文章,定有大收获。

本教程是将ucGUI移植到STM32单片机。

LCD驱动器为HX8347。

为了教程有更大的通用性,LCD驱动程序未采用ucGUI官方提供。

编译环境为5.4。

本教程可作为其它单片机、LCD、编译环境的参考。

不足之处,敬请指出QQ:309223638单片机交流QQ群:166578859电子邮箱:jitao_yang@1解压“ucGUI-V3-90a----非常好用.rar”这个版本的优点:需要改动的地方少;编译时不会由于在Linux环境下编辑源代码,然后又拿回IAR环境编译造成大量“Warning[Pa050]:……”;LCD底层驱动获取方便,不依赖于ucGUI官方驱动。

顺次打开“uCGUI-V3-90a→UCGUI390a→Start”。

将Start文件夹下的Config和GUI 文件夹复制的自己所建立工程文件夹。

然后打开IAR,在Workspace中添加Config和GUI文件夹内容。

添加完后,如下图所示。

其中“FWLib”是我的工程中所需要的,属于多余项。

然后右击工程,打开Options,选择左侧的“C/C++Compiler”。

然后在右侧选择Preprocessor。

在“Additional include directories”下填写工程中Config和GUI文件夹路径。

Ex:$PROJ_DIR$\..\gui$PROJ_DIR$\..\gui\AntiAlias$PROJ_DIR$\..\gui\ConvertColor单片机交流QQ群:166578859电子邮箱:jitao_yang@ $PROJ_DIR$\..\gui\COnvertMono$PROJ_DIR$\..\gui\core$PROJ_DIR$\..\gui\Font$PROJ_DIR$\..\gui\JPEG$PROJ_DIR$\..\gui\LCDDriver$PROJ_DIR$\..\gui\MemDev$PROJ_DIR$\..\gui\MultiLayer$PROJ_DIR$\..\gui\Touch$PROJ_DIR$\..\gui\Widget$PROJ_DIR$\..\gui\WM$PROJ_DIR$\..\Config截图2配置GUIConf.hPS:一下配置,配置为“1”,启用;配置为“0”,不启用#define GUI_OS(0)/*是否加载操作系统*/#define GUI_SUPPORT_TOUCH(0)/*是否启用触屏支持*/#define GUI_SUPPORT_UNICODE(1)/*是否启用混合型ASCII/UNICODE编码*/ #define GUI_DEFAULT_FONT&GUI_Font8x16/*字体大小配置,参见手册*/ #define GUI_ALLOC_SIZE500/*应用于GUI的动态内存字节配置,不建议低于500;也不要配置太高,导致内存溢出*//***********************************************************************Configuration of available packages*/#define GUI_WINSUPPORT0/*窗口管理数据包支持*/#define GUI_SUPPORT_MEMDEV0/*存储设备支持*/#define GUI_SUPPORT_AA1/*抗锯齿。

uCGUI移植到STM32总结

uCGUI移植到STM32总结

uCUI移植总结做了两个星期终于把gui搞通了,现将移植方法总结如下,仅供学习交流之用。

2014/8/23一、uCGUI移植步骤1、uCGUI及TFT驱动文件准备(1)将TFT驱动文件ili9320.h、ili9320.c 及其字体文件ili9320_font.h 复制至keil 工程模板的文件夹中;(2) 准备好uCGUI源文件(本例使用的版本3.90a),将START 文件夹下的GUI 文件夹全部复制到keil 工程模板的文件夹中;再将START 文件夹下的Config 文件夹复制至GUI 文件夹下;最后将Sample 文件夹下GUI_X 中的GUI_X.c 复制到Config 文件夹中。

最终文件结构如图1-1所示:图1-12、添加文件至工程,文件目录结构组如图2-2示:图2-1在添加文件时应注意uCGUI下除了gui_config 下需要添加所有的.h 头文件外其余所有均不需要添加头文件;图2-23、GUI配置(1)G UIConf.h配置:#define GUI_OS (0) /*编译多任务支持#define GUI_SUPPORT_TOUCH (0) /* 触屏支持*/#define GUI_SUPPORT_UNICODE (1) /*支持ASCII/UNICODE码*/ #define GUI_DEFAULT_FONT &GUI_Font6x8 /*初始化字体大小*/#define GUI_ALLOC_SIZE 5*1024 /*开辟动态空间大小*/图3-1注意:动态空间受芯片容量大小制约,不可开辟过大,否则报错图3-2(2) LCD 相关文件配置:LCDConfig.h 的配置#define LCD_XSIZE (320)#define LCD_YSIZE (240) /*x,y方向像素设置*/#define LCD_BITSPERPIXEL (16) /*像素位数*/#define LCD_CONTROLLER 9320 /*LCD驱动器型号*/图3-3继续修改第110行#define LCD_INIT_CONTROLLER() ili9320_Initializtion()并将其后的语句注释掉。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

emWin 5.22 (uCGUI) 图形用户接口移植实例——STM32
作者:Ach
日期:2013年12月29日
联系方式:ox000008@
1.概要
移植图形用户接口的好处是不言而喻的。

本文图文并茂地介绍了一个emWin 5.22(uCGUI)的移植实例。

文章具体分为emWin简介,硬件平台简介,开发环境及项目简介,移植过程以及总结几个部分。

2.emWin简介
emWin是一种高效的而图形用户界面,是我们能够摆脱处理器和显示控制器而更专注于GUI的设计。

这里借用STemWin的一幅图来说明emWin的作用和结构。

它通过LCD及GUI的配置来驱动底层硬件,而应用程序又是通过调用emWin来实现各种GUI。

5.22版的emWin带有许多常用的显示控制器的驱动(在参考手册Display Driver一章中有详细介绍),因此为我们移植带来了诸多方便。

emWin的更详细的内容可参照它的参考手册。

图1. emWin在项目中的结构
3.硬件平台简介
笔者使用的是一块以STM32F103VET6为核心的ARM开发板,没有外部的SRAM及Flash。

显示屏为2.8”320*240的彩色液晶屏,屏的驱动芯片为ILI9341(emWin 5.22带有它的驱动)。

屏与CPU 的连接方式为该ARM核心所特有的FSMC_SRAM方式,访问LCD内容时操作就如同读写SRAM一样方便。

如果你想使用其它硬件平台来移植emWin,本文亦有一定的参考价值。

希望本文能助你成功移植emWin。

图2. 硬件平台
4.开发环境简介
笔者所使用的开发软件为MDK-ARM 4.70。

项目模板使用的是STemWin库中的(可从ST官方下载)。

图3. 项目截图
如图,项目下面有3个文件夹,其中Appli存放的是应用层的程序,第二个文件夹就如文件名,存放了emWin5.22所有部件,第三个文件夹存放了一些STM32及其它的库。

具体见附件。

5.移植过程
有了MDK-ARM以及STemWin库,整个移植过程应该比较简单。

STemWin中有4个文件夹,第一个可以不用看了,Libraries中包含所有需要的库(其中包含emWin5.22),Project中存放工程文件,Utilities中是一些应用文件。

为了保持代码及工程结构的格式统一,我们尽量套用原有的格式。

下面开始一步步的移植工作。

5.1 项目配置
打开Project文件夹,看到众多STM32的开发板文件夹。

如果你有相应的板子,就不用修改直接用。

我使用的是STM32F103核心的板子,因此我选了STM3210E-EVAL为模板,取名TEST(自取)。

打开该文件夹,里面有2个文件夹,分别为RTOS和Standalone,RTOS是带操作系统的。

我们打开Standalone,其中有6个文件夹,分别为Config、Demo、EWARM、MDK-ARM、TrueSTUDIO及User,具体的不一一介绍了。

打开MDK-ARM,我们要的工程文件就在其中了。

打开工程,先点击如图左边红圈处编译一下,工程应该是没有错误的。

然后根据你所使用的硬
件开发环境点击右边红圈处配置一下项目。

点击Device标签设置器件,我应该选STM32F103VE。

点击Output标签,勾选左边红圈处,编译后会输出HEX文件,当然你也可以改一下右边红圈内的名字。

点击Debug标签,设置调试信息,选择你的调试工具即可,不详细介绍了。

点击Utilities标签,我的设置如图。

为了可以直接在项目中向开发板烧录程序,我们点Settings设置一下,我的设置如下图,其中添加了如图的片上Flash编程算法。

点击OK设置完毕。

5.2 程序修改
准备工作已经完成,接着要根据模板进行修改了。

看一下Appli中的main主程序,如下。

先看“BSP_Init();”,这是开发板的初始化程序,我们先把它注释掉,然后在后面加上下面的语句,因为需要用到CRC模块。

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
接着我们修改LCD和GUI配置文件。

先是LCDConf_stm3210e_eval.c,修改显示屏大小,我的不用改了。

#define XSIZE_PHYS 240
#define YSIZE_PHYS 320
修改接口寄存器地址,我的如下。

这里说明一下,我的是用FSMC_SRAM接口的,和官方开发板类似。

如果你用得是其它接口,在emWin参考手册Display drivers -> CPU / Display controller interface 中有对硬件接口的详细叙述,它吧接口分为直接和间接两种,我们用的嵌入式系统一般是间接的接口。

查找是否有我们所使用的显示芯片的驱动,然后参考手册进行相应的操作。

我使用的ILI9341驱动在GUIDRV_FLEXCOLOR中有。

// COG interface register addr.
//
#define LCD_BASE ((uint32_t)(0x60000000 | 0x00000000))
#define LCD_REG_ADDRESS (*(volatile U16*)LCD_BASE)
#define LCD_DATA_ADDRESS (*(volatile U16*)(LCD_BASE + 0x20000))
Local functions那一段我就不用改了。

Public functions中有两个接口函数LCD_X_Config和LCD_X_DisplayDriver。

LCD_X_Config,驱动为GUIDRV_FLEXCOLOR,颜色为16位GUICC_565转换方式。

pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0);
Set controller and operation mode,将一些显示驱动用的函数传递给PortAPI。

再通过函数GUIDRV_FlexColor_SetFunc进行设置,查看参考手册GUIDRV_FlexColor段,ILI9341 驱动在GUIDRV_FLEXCOLOR_F66709中,接口形式为GUIDRV_FLEXCOLOR_M16C0B16。

PortAPI.pfWrite16_A0 = LcdWriteReg;
PortAPI.pfWrite16_A1 = LcdWriteData;
PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple;
PortAPI.pfReadM16_A1 = LcdReadDataMultiple;
GUIDRV_FlexColor_SetFunc(pDevice,&PortAPI,GUIDRV_FLEXCOLOR_F66709,GUIDRV_FLEXCOLOR_M16C0B16);
最后一个函数LCD_X_DisplayDriver,把“STM3210E_LCD_Init();”改成你的初始化程序即可,当然,在前面要把需要的头文件包含进去。

至此,我们把LCD配置改完了。

GUIConf_stm3210e_eval.c,程序主要是为GUI分配可以的内存。

对于这里,我只能理解给它分配足够大的内存可以让现实更流畅。

由于我板上的内存有限,总共64KB,后面GUIDEMO还要用内存,所以分配16KB给它。

// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES (1024) * 16 // x KByte
接着,修改Appli中的GUIDEMO.h文件,看Configuration of modules to be used段,配置我们要运行的模块。

我们先试前面3个模块,其它都关掉(设为0)。

内存小的话不要开太多了,否则内存不够用。

至此,程序已经基本修改完毕,重新编译程序,修改错误之处直至编译通过,下载程序到开发板。

演示画面已经显示,但是,画面为什么停在那里呢?我们再回来看main中的“BSP_Init();”函数。

它里面包含了一个非常重要的东西,我们在函数名上点击右键,选择“Go To Definition Of ‘BSP_Init’”查看该函数的定义。

其中包含了“SysTick_Config(SystemCoreClock / 1000);”,即对SysTick的配置,它就像人的心跳一样,是系统运行的钟摆。

它被配置为1ms产生一个中断。

在stm32xxx.it中,有一个“SysTick_Handler”中断处理函数,“OS_TimeMS ++;”即实现了emWin 的运行。

我们把不需要的都注释掉,然后编译工程,下载到开发板。

至此,emWin已经能够在目标板上运行。

6.总结
移植emWin只是一个开始,还有更多的奥秘等待我们去探索,相信只要我们能够努力,一定能开发出漂亮的界面。

注:文中的项目较大,如有需要,邮me!同时欢迎交流指正。

完成时间2013年12月30日
Ach#。

相关文档
最新文档