OpenEdv-开源电子网

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

分享下移植STemWin5.22经验,欢迎拍砖指导,呵呵 ----> 附上战舰STM32工程

  [复制链接]

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-3-11 13:29:55 | 显示全部楼层 |阅读模式
据说很多人说emWin这个家伙界面很漂亮,所以移植来玩玩,呵呵,小有成绩,大神们见笑了。。。

1、
移植前如果你的LCD底层驱动什么的是“lcd.clcd.h”这样编写的,请改为其他的名字,比如什么的ili93xxlcd_tft等名字,至于原因,自己思考吧

相关截图我是参考自带的参考手册英文版的(STemWinLibrary522\Documentation文件夹下的文档),有误的地方还请批评指正。
2、下载官网上的那个STemWin5.22的例程下来,具体可以官网搜索下载http://www.st.com/web/en/catalog/tools/PF259225#
3、拷贝文件到你的工程里面(前提是所建的工程液晶部分调试通过才行),呵呵
4、解压压缩包,进入“...\stemwin\STemWin_Library_V1.1.2\Libraries”这个文件夹,你会看到下图中的东东


没错,就是这个家伙了,将它拷贝到你的工程里,我在工程里面建立了一个EMWIN的文件夹进行存放,大家想怎么放怎么放哈


5、STemWinLibrary522\Config文件夹中的GUIConf.cGUIConf.hLCDConf_FlexColor_Template.c添加进工程里,这步相信用过MDK或者Keil C51的都知道怎么操作的哈
6、选择lib库了,根据编译器类型ST的工程师已经分类好了,自己根据你的编译软件和芯片类型进行选择即可,我的MCU是STM32F103VET6的,MDK编译,所以我选择了
STemWinLibrary522\Lib文件夹中的STemWin522_CM3_Keil.lib这个。添加进工程之后的样子


黄色框框是我改后的LCD底层初始化函数的文件名字,大家就参考即可,红色框框就是增加STemWin的工程文件了。同样的头文件路径添加,自己看着办哈
7、开始你的剪刀手了,修改代码,哈哈

A、在工程中打开“GUIConf.c”文件,找到GUI_NUMBYTES这个宏定义,默认的数值是0x200000,将它改小一点,我改成了1024*50,其他值就视情况而定,具体干嘛的请看说明。

B、接下来的void GUI_X_Config(void)这个函数,主要是设置内存分配、字体等,视情况修改。

C、“GUIConf.h”文件里面主要定义是否支持OS、缺省字体大小等等。
8、
LCDConf_FlexColor_Template.c”这个文件改写。
A、
增加你的LCD底层驱动函数头文件,具体用到LCD接口的初始化函数不想添加也行,在这个文件中自己编写一下也可以的。

B、接下来改写LCD显示分辨率,视屏幕大小而定,因为我用的就是这个,所以保留不用修改,跳过

#define XSIZE_PHYS  240 // To be adapted to x-screen size

#define YSIZE_PHYS  320 // To be adapted to y-screen size

C、增加定义LCD寄存器、RAM操作地址(假如用FSMC控制,不同的块地址不一样),用其他控制方式的自己想想怎么搞哈

#define LCD_BASE (uint32_t)(0x60000000 | 0x0001fffe) //基地址

#define LCD_REG_ADDRESS  (*(volatile U16*)LCD_BASE) //寄存器地址

#define LCD_DATA_ADDRESS  (*(volatile U16*)(LCD_BASE + 2)) //RAM地址


D、填写操作函数内容,具体下面几个函数体

static void LcdWriteReg(U16 Data) //写寄存器

static void LcdWriteData(U16 Data) //写数据

static void LcdWriteDataMultiple(U16 * pData, int NumItems) //写入多组数据

static void LcdReadDataMultiple(U16 * pData, int NumItems) //读取多组数据

E、LCD底层初始化函数,在下面函数里面填上,具体位置不用说了吧,呵呵

int LCD_X_DisplayDriver()
F、
void LCD_X_Config(void)这个函数,根据你使用的液晶控制器型号而定,具体宏定义请看数据手册的相关介绍

_1、下面这个函数设置LCD控制器型号、颜色格式等
    
pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0);

_2、接下来的这个Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_Y;不需要的话可以将它注释掉(视你LCD初始化的时候对应寄存器的设置决定)

设置了LCD的显示方向什么的,类似于LCD数据手册中的字符显示方向设置。参考下图


_3
GUIDRV_FlexColor_SetFunc(pDevice, &ortAPI, GUIDRV_FLEXCOLOR_F66709GUIDRV_FLEXCOLOR_M16C0B16);

    这个函数设置了LCD控制器的数据宽度什么的,其中形参GUIDRV_FLEXCOLOR_F66709,驱动器型号,参考下图定义


形参GUIDRV_FLEXCOLOR_M16C0B16设定了LCD数据总线宽度,颜色参数等,参考下图


G、接着在这个函数int LCD_X_DisplayDriver()里面添加你提供的液晶接口的初始化函数调用,具体增加位置请看函数中的说明,呵


9、接下来就开始main函数文件的修改了
A、
添加头文件#include "GUI.h",集合了相关的API函数
B、
接着在void main()中打开CRC时钟,RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);具体为什么想不明白,可能其中用到STM32CRC计算功能吧
C、
接着初始化emwin了,调用GUI_Init();函数,完了之后,可以调用GUI里面提供的API函数进行你的相关操作了,我就写了下面两句,其他的视兴趣而增加,呵呵

    GUI_DispStringAt("Hello World!", 30, 200);
    
GUI_DispStringAt("Hello emWin!", 30, 216);

完成了点击编译,改错即可了,下载到板子上,结果就是下图这样,至于为什么你的LCD初始化函数里面设置的背景色是白色或者其他颜色,而这个显示是黑色的呢?这个问题大家就看着想清楚即可,呵呵


10、完成了这个就可以增加demo功能了。哈哈
11、
STemWin_Library_V1.1.2\Project\STM3210E-EVAL\Standalone中的Demo文件夹拷贝到工程中来,这里面我的MCUSTM32F103VET6的,不带操作系统的,所以我这里选择了STM3210E-EVAL\Standalone这个路径下的,至于带操作系统的,自己选择即可哈
12、
main函数文件中添加#include "GUIDEMO.h"头文件,接着在函数中增加SysTick_Config(SystemCoreClock / 1000);这个函数,我是利用这个SysTick定时器来做GUI的心跳的,所以加了这句,至于用定时器的方式的,请另行修改;接着增加demo的演示GUIDEMO_Main();这个函数。
13、
guidemo.h文件中找到下图这个家伙,这里是demo的开关哦,我这里打开了7个(将后面括号里的0 --> 1 就打开了,相反就关闭了,这个多此一说,哈哈),其他的自行demo,呵呵



14、
stm32f10x_it.c中断汇总文件中编写中断服务函数。

增加extern __IO int32_t OS_TimeMS;

编写SysTick_Handler中断服务函数,因为我用了这个做心跳,其他的自行处理

void SysTick_Handler(void)

{

OS_TimeMS++;

}

15、然后点击保存,再编译


红色框框里面,生成的代码还是有点大的,具体视你打开的demo多少有关估计。

触摸功能就暂时没加上,有空再说,呵呵

哈哈,至此就完成了STemWin5.22的移植了。高兴一下下,嘿嘿,心情无比激动,下载到板子上运行,哈哈看到界面了,爽



高兴之下就拍了个视频,有点大,1080P的,400多兆,看啥时候传上来给大伙们看看,呵呵

战舰板子的测试工程没弄,这个稍后奉上,我是用我自己的这个最小系统板子测试的http://www.openedv.com/posts/list/26648.htm

论坛上“745021926”这个坛友手上有我的这个板子,可以直接下载工程上去测试,呵呵


视屏分享:http://www.youku.com/playlist_show/id_22111265.html























emwin移植笔记.pdf

871.41 KB, 下载次数: 4489

STemWin5.22移植.zip

26.46 MB, 下载次数: 16284

STemWin5.22移植(战舰板子).zip

26.47 MB, 下载次数: 14706

现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

9

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2021-1-25
在线时间
6 小时
发表于 2021-1-25 17:53:39 | 显示全部楼层
感谢分享,生成的文件大小有点彪。
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2015-5-29
在线时间
14 小时
发表于 2020-11-19 09:15:27 | 显示全部楼层
谢谢分享,对我非常有帮助
MCU DIY
回复 支持 反对

使用道具 举报

51

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
561
金钱
561
注册时间
2011-4-11
在线时间
43 小时
发表于 2019-10-22 21:09:07 | 显示全部楼层
顶  好移植笔记
回复 支持 反对

使用道具 举报

1

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2013-1-2
在线时间
53 小时
发表于 2019-8-21 13:05:13 | 显示全部楼层
大赞楼主,好好学学了。
回复 支持 反对

使用道具 举报

1

主题

234

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3220
金钱
3220
注册时间
2015-4-19
在线时间
356 小时
发表于 2019-7-17 00:10:04 | 显示全部楼层

点赞,楼主5年前就搞出来了,学习一下,谢谢分享!
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-2-9 17:39:05 | 显示全部楼层
xyzjacky 发表于 2018-2-9 14:13
图标还在不断的增加,现在片内的已经吃紧了。所以将来肯定是要放在外面的。

将数据存到flash中,需要显示这个的时候就读取回来显示就是了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-2-9 14:13:03 | 显示全部楼层
八度空间 发表于 2018-2-9 10:25
图片数据表不大的话直接编译到片内就是了,没必要增加外部flash

图标还在不断的增加,现在片内的已经吃紧了。所以将来肯定是要放在外面的。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-2-9 10:25:16 | 显示全部楼层
xyzjacky 发表于 2018-2-8 17:59
另外求教一下八度哥哥,我现在的代码中用到的字体和图片的字模和图模数据,我得存到片外flash去,但是因 ...

图片数据表不大的话直接编译到片内就是了,没必要增加外部flash
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-2-8 17:59:12 | 显示全部楼层
八度空间 发表于 2018-2-3 11:52
GUI_DispDecShift()用这个函数试试

另外求教一下八度哥哥,我现在的代码中用到的字体和图片的字模和图模数据,我得存到片外flash去,但是因为数据量不大,而且系统在运行时只是读取,所以我不需要在片外flash上弄文件系统。

但我现在被卡在这里了,比如,我有一张BMP图片,图模数据用BmpCvtST.exe取好了,形成了一个C文件,这个C文件里面有这样几个部份:
a.  一个声明  extern GUI_CONST_STORAGE GUI_BITMAP bmArticle;
b. 一个数组  static GUI_CONST_STORAGE unsigned long _acArticle[] = {//数据略};
c. 一个跟图片相关的定义
GUI_CONST_STORAGE GUI_BITMAP bmArticle = {
  24, // xSize
  24, // ySize
  96, // BytesPerLine
  32, // BitsPerPixel
  (unsigned char *)_acArticle,  // Pointer to picture data
  NULL,  // Pointer to palette
  GUI_DRAW_BMP8888
};

我现在是仅把数组_acArticle[]存到片外 flash 中去,那么b项的_acArticle应该申明成什么呢?
我能想到的是把它定义成一个static GUI_CONST_STORAGE unsigned long _acArticle[100];这样的数组(假设原本的图模数据的大小就是100个),在每一个页面调用时,先从片外flash把数据读到_acArticle数组中,然后再使用这个数组。
反正编译器现在还没有报错。但是现在还只是设想的,代码还没有烧到硬件上去测试。
请问还有没有别的什么办法呢?
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-2-3 11:52:37 | 显示全部楼层
xyzjacky 发表于 2018-2-2 18:39
另外请教楼主一个问题,关于显示数值显示居中时,如何消除上一次的数据。情况是这样的,我用
GUI_SetTextA ...

GUI_DispDecShift()用这个函数试试
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-2-2 18:39:43 | 显示全部楼层
另外请教楼主一个问题,关于显示数值显示居中时,如何消除上一次的数据。情况是这样的,我用
GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
GUI_DispDecAt(7438,266,196,4);显示了一个千位数据7438。

这会儿新的数据来到,是617,就用以下方式来使617居中显示。
GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
GUI_DispDecAt(617,266,196,3);

可是问题来了,7438是一个4位数,617是一个3位数。7438的7就会残留一半在最前面,造成显示错误。
我在安福莱和正点原子教程上还没有找到如何解决这样的问题,所以请教楼主,也请教各位网友,这样的问题一般是怎么解决的,即如何实现位数变化的数值的居中显示。
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-2-2 18:39:17 | 显示全部楼层
另外请教楼主一个问题,关于显示数值显示居中时,如何消除上一次的数据。情况是这样的,我用
GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
GUI_DispDecAt(7438,266,196,4);显示了一个千位数据7438。

这会儿新的数据来到,是617,就用以下方式来使617居中显示。
GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
GUI_DispDecAt(617,266,196,3);

可是问题来了,7438是一个4位数,617是一个3位数。7438的7就会残留一半在最前面,造成显示错误。
我在安福莱和正点原子教程上还没有找到如何解决这样的问题,所以请教楼主,这样的问题一般是怎么解决的,即如何实现位数变化的数值的居中显示。
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-23 10:59:23 | 显示全部楼层
八度空间 发表于 2018-1-19 22:10
没这样操作过,你可以尝试以下,应该有改变背景图片的API

有,要用到窗口管理
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-19 22:10:16 | 显示全部楼层
xyzjacky 发表于 2018-1-19 21:51
求教八度哥,emwin里面,有什么方法可以实现一个窗口的背景色改变而不影响窗口中显示的内容。请注意,窗口 ...

没这样操作过,你可以尝试以下,应该有改变背景图片的API
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-19 21:51:00 | 显示全部楼层
求教八度哥,emwin里面,有什么方法可以实现一个窗口的背景色改变而不影响窗口中显示的内容。请注意,窗口中有我用底层驱动函数(GUI中函数)显示的东西。
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-18 10:01:06 | 显示全部楼层
八度空间 发表于 2018-1-18 08:57
写一个程序,通过串口将字库数据写入flash就可以了,论坛好像有个盘友做了,你搜索一下看看,参考来做

谢谢,了解了!
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-18 08:57:46 | 显示全部楼层
xyzjacky 发表于 2018-1-17 22:22
哦,我知道了,它这种字体是一个存在SD卡中的文件。但是我现在只有一个片外FLASH,硬件上没有SD卡接口, ...

写一个程序,通过串口将字库数据写入flash就可以了,论坛好像有个盘友做了,你搜索一下看看,参考来做
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-17 22:22:33 | 显示全部楼层
本帖最后由 xyzjacky 于 2018-1-17 22:25 编辑
八度空间 发表于 2018-1-17 22:03
哦,这个你就参照安福莱的来实验以下

哦,我知道了,它这种字体是一个存在SD卡中的文件。但是我现在只有一个片外FLASH,硬件上没有SD卡接口,那该怎么办呢?
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-17 22:03:24 | 显示全部楼层
xyzjacky 发表于 2018-1-17 22:01
手册里没有讲。因为TTF字库是SEGGER公司单独提供的。在安福莱的教程里有提到,只有一个显示效果,但是没 ...

哦,这个你就参照安福莱的来实验以下
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-17 22:01:19 | 显示全部楼层
八度空间 发表于 2018-1-17 21:57
没用过,可以查看以下手册看下有没相关的说明,这个不常用的吧

手册里没有讲。因为TTF字库是SEGGER公司单独提供的。在安福莱的教程里有提到,只有一个显示效果,但是没有讲具体的。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-17 21:57:03 | 显示全部楼层
xyzjacky 发表于 2018-1-17 21:42
请问,你知道TTF字体库中,哪一个C文件是米字形的字体吗?

没用过,可以查看以下手册看下有没相关的说明,这个不常用的吧
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-17 21:42:58 | 显示全部楼层
请问,你知道TTF字体库中,哪一个C文件是米字形的字体吗?
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-14 19:17:07 | 显示全部楼层
xyzjacky 发表于 2018-1-12 16:10
badu哥,估计你们接触emWin的日子也不少了,希望你们能讲解一下这个地方:

GUI_DEVICE_CreateAndLink( ...

这两个是显示驱动器的,具体可以查看自带的手册,显示驱动章节,里边介绍比较详细
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-12 16:10:23 | 显示全部楼层
八度空间 发表于 2018-1-12 13:31
我遇到的都是内存溢出

badu哥,估计你们接触emWin的日子也不少了,希望你们能讲解一下这个地方:

GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_565, 0, 0);       

pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0);

我的移植不成功的问题就来自此:
GUIDRV_FLEXCOLOR  和 GUIDRV_Template_API

因为我也是刚接触,讲不清楚,希望你和原子哥讲解一下。@正点原子
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-12 15:30:57 | 显示全部楼层
八度空间 发表于 2018-1-12 13:31
我遇到的都是内存溢出

我找到问题了。就一个地方出了问题。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-12 13:31:26 | 显示全部楼层
xyzjacky 发表于 2018-1-12 12:51
我昨天和今天在网上看到,很多网友移植emWin时,都遇到了死在GUI_init这里。
好几个网友的帖子,都是未 ...

我遇到的都是内存溢出
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-12 12:51:02 | 显示全部楼层
八度空间 发表于 2018-1-12 12:30
哦,那就要好好找找了

我昨天和今天在网上看到,很多网友移植emWin时,都遇到了死在GUI_init这里。
好几个网友的帖子,都是未解决。
所以我觉得,国内做STM32或者emWin教程这方面业务的,应该多多注意一下这里,进行归纳和总结性的举例。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-12 12:30:34 | 显示全部楼层
xyzjacky 发表于 2018-1-12 09:56
不多,可以说现在完全为一种初始态,我现在连GUI demo都没有加进去,仅仅是看移植能不能成功,能不能跑起来, ...

哦,那就要好好找找了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-12 09:56:06 | 显示全部楼层
本帖最后由 xyzjacky 于 2018-1-12 11:46 编辑
八度空间 发表于 2018-1-12 09:29
你开的模块多不多,多的话20K不够用的,简单的字符显示10K都够了

不多,可以说现在完全为一种初始态,我现在连GUI demo都没有加进去,仅仅是看移植能不能成功,能不能跑起来,先显示字符串,画个圆,画个框什么的,所以20K妥妥的够用。现在的工程里我自己写的文件里,也没有用到大数组。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-12 09:29:38 | 显示全部楼层
xyzjacky 发表于 2018-1-12 09:23
我现在的情况是死机在GUI_Init()这里,进入了HardFault handler中断.

LCD_wtREG((U8)Data)  看着是 ...

你开的模块多不多,多的话20K不够用的,简单的字符显示10K都够了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-12 09:23:24 | 显示全部楼层
本帖最后由 xyzjacky 于 2018-1-12 09:25 编辑
八度空间 发表于 2018-1-12 09:06
1、从你贴的代码看,你用的SPI传输是8bits数据位,改为16bits试过没,这样可以使用16比赛调色板
2、调用 ...

我现在的情况是死机在GUI_Init()这里,进入了HardFault handler中断.

LCD_wtREG((U8)Data)  看着是一个字节 , 但这个函数, 里面是发了两个字节,有一个空字节.
所以这里不用担心.

关于读点函数,现在都死在了GUI初始化,估计和LcdReadDataMultiple,是什么也没有关系.
在百度时,发现有好些网友都是说死在了GUI_Init()这里,根据他们的经验,我把GUI内存大小,堆栈大小都检查了一遍,CRC时钟也打开了,
但是结果还是死机的.
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-12 09:06:43 | 显示全部楼层
本帖最后由 八度空间 于 2018-1-12 09:11 编辑
xyzjacky 发表于 2018-1-11 19:04
从当前debug的情况看,是死机了。死在这里,void HardFault_Handler(void),也就是说堆栈溢出了可以看我 ...

1、从你贴的代码看,你用的SPI传输是8bits数据位,改为16bits试过没,这样可以使用16比赛调色板
2、调用GUI_Init()就司机了,说明还是内存的问题
3、这里
static void LcdWriteReg(U16 Data) {
  // ... TBD by user
        LCD_wtREG((U8)Data);                //写寄存器
}
传入的应该是16bit的,你发送两次试下
4、这个函数
static void LcdReadDataMultiple(U16 * pData, int NumItems) {
  //U8 msb=0 , lsb=0;
        while (NumItems--) {
    // ... TBD by user
                *pData++ = LCD_Read_16Data();        //读16位数据
  }
}
最好改为
static void LcdReadDataMultiple(U16 * pData, int NumItems) {
  //U8 msb=0 , lsb=0;
  *pData = LCD_Read_16Data();
        while (NumItems--) {
    // ... TBD by user
                *pData++ = LCD_Read_16Data();        //读16位数据
  }
}
5、如果你的是8bit输入,选择GUIDRV_FLEXCOLOR_M16C0B8这个调色板,如果16bit就用GUIDRV_FLEXCOLOR_M16C0B16这个调色板6、其他看着也没什么问题了,建议你SPI改为16bit传输,如果可以的话,或者你拆掉这个SPI转接电路,直接飞IO进行控制,这样方便很多
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-11 19:04:13 | 显示全部楼层
本帖最后由 xyzjacky 于 2018-1-11 19:08 编辑
八度空间 发表于 2018-1-11 17:19
不会把,显示字符串的代码贴一下看下

从当前debug的情况看,是死机了。死在这里,void HardFault_Handler(void),也就是说堆栈溢出了可以看我的main函数,就是最简单点几个初始化,并没有用到什么大的数组,为何就死机了呢。
继续查看,发现在GUI_Init就死掉了。
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-11 18:48:35 | 显示全部楼层
本帖最后由 xyzjacky 于 2018-1-11 18:56 编辑
八度空间 发表于 2018-1-11 17:19
不会把,显示字符串的代码贴一下看下

d.
int LCD_X_DisplayDriver()函数中没有添加我自己的LCD初始化函数,因为LCD底层驱动初始化函数,已在main函数中先于GUI_Init();调用了,这里不需要了。

e.
接下来就是按照你帖子中的第9步,开始main函数文件的修改了
1、添加头文件#include "GUI.h",集合了相关的API函数
2、接着在void main()中打开CRC时钟,RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);具体为什么想不明白,可能其中用到STM32的CRC计算功能吧
3、接着初始化emwin了,调用GUI_Init();函数,
4、接着添加以下三个函数
                GUI_SetBkColor(WHITE);
                GUI_SetColor(BLUE);
                GUI_Clear();

完成以上移植后,编译,没有任何报错和警告,

然后,又添加GUI_DispStringAt("Hello World!", 150, 30);   编译无错,下载。
下载后,无任何显示(即不是我设置的底色,也不是出现任何底色),就感觉屏幕是不受控制状态。有点类似于初始化没有做好时的,那种不受控的亮度、色彩。
我试过把这个参数设置成下面每一个,都是没有用的。
GUIDRV_FLEXCOLOR_M16C0B8
GUIDRV_FLEXCOLOR_M16C1B8
GUIDRV_FLEXCOLOR_M16C0B16
GUIDRV_FLEXCOLOR_M16C1B16

我的main()函数如下:
int  main()

        delay_init();                     //延时函数初始化         
        NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级         LED_Init();                             //LED端口初始化
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);        //开启CRC时钟        
        SPI1_idev_Init();  //初始化硬件SPI1

        LCD_odev_init();                        //初始化ili9341

        GUI_Init();
        GUI_SetBkColor(WHITE);
        GUI_SetColor(BLUE);
        GUI_Clear();
        GUI_DispStringAt("Hello World!", 150, 30);

        delay_ms(160);





回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-11 18:26:54 | 显示全部楼层
本帖最后由 xyzjacky 于 2018-1-11 18:38 编辑
八度空间 发表于 2018-1-11 17:19
不会把,显示字符串的代码贴一下看下

我是按照正点原子教程,和你的帖子进行的移植。以下是我的代码。
A.
首先是改  GUIConf.h  中的这一段代码:
#define GUI_NUM_LAYERS            2    // Maximum number of available layers        //最大显示层数--2层
#define GUI_OS                                           (0)        //不支持使用OS
#define GUI_SUPPORT_TOUCH       (0)  // Support touchscreen        //不使用触摸屏
#define GUI_DEFAULT_FONT         &GUI_Font6x8        //显示字体默认大小
#define GUI_SUPPORT_MOUSE             (0)    /* Support a mouse */  //不支持使用鼠标
#define GUI_WINSUPPORT                (1)    /* Use window manager */                //支持窗口管理器
#define GUI_SUPPORT_MEMDEV            (1)    /* Memory device package available */        //支持存储设备
#define GUI_SUPPORT_DEVICES           (1)    /* Enable use of device pointers */                //使用设备指针

B.
然后修改   GUIConf.c 中的缓存大小,及配置函数
#define GUI_NUMBYTES  (20*1024)                //设置emWIN内存大小,20K

void GUI_X_Config(void) {
  static U32 aMemory[GUI_NUMBYTES / 4];
  GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);
  GUI_SetDefaultFont(GUI_FONT_8X12_ASCII);        //设置显示字体大小
}


C.
再修改LCDConf_FlexColor_Template.c 中的代码
1. 先是宏定义
#define XSIZE_PHYS  320  // To be adapted to x-screen size                //长320
#define YSIZE_PHYS  240  // To be adapted to y-screen size                //宽240


2.再是那4个基本函数
static void LcdWriteReg(U16 Data) {
  // ... TBD by user
        LCD_wtREG((U8)Data);                //写寄存器
}


static void LcdWriteData(U16 Data) {
  // ... TBD by user
        LCD_wt16bitData(Data);        //写一个16位数据
}


static void LcdWriteDataMultiple(U16 * pData, int NumItems) {
  while (NumItems--) {
    // ... TBD by user
                LCD_wt16bitData(*pData++);                //连续写16位数据
  }
}


static void LcdReadDataMultiple(U16 * pData, int NumItems) {
  //U8 msb=0 , lsb=0;
        while (NumItems--) {
    // ... TBD by user
                *pData++ = LCD_Read_16Data();        //读16位数据
  }
}


3. LCD_X_Config函数的改写
void LCD_X_Config(void) {
  GUI_DEVICE * pDevice;
  CONFIG_FLEXCOLOR Config = {0};
  GUI_PORT_API PortAPI = {0};
       
  pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0);        //设置颜色格式

  LCD_SetSizeEx (0, lcddev.width , lcddev.height);
  LCD_SetVSizeEx(0, lcddev.width , lcddev.height);

//  Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_Y;
  GUIDRV_FlexColor_Config(pDevice, &Config);

  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);



回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-11 18:24:43 | 显示全部楼层
八度空间 发表于 2018-1-11 17:19
不会把,显示字符串的代码贴一下看下

那我先介绍一下我用的硬件吧。
单片机是STM32f103RC的,屏幕是2.8寸的液晶屏,采用横向显示,所以长320,宽240。驱动芯片是ILI9341,SPI接口的,其实质上是屏的生产厂家在9341外面加了一个16位并口转SPI的电路,所以只能使用SPI方式控制。这也就造成了移植起来让我如此难受,因为大多数资料是16bit并口,且是FSMC方式的。
当前我的SPI接口驱动完全没有问题,因为已经使用了好几个月了,字符、汉字、图片等显示都没有任何问题。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-11 17:19:19 | 显示全部楼层
xyzjacky 发表于 2018-1-11 17:11
按照你的代码,修改这几个函数,
tatic void LcdWriteReg(U16 Data) //写寄存器

不会把,显示字符串的代码贴一下看下
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-11 17:11:11 | 显示全部楼层
八度空间 发表于 2018-1-10 20:20
FSMC上面有个地址先Ax这个就是控制LCD的数据和命令的线,所以要弄好控制地址

按照你的代码,修改这几个函数,
tatic void LcdWriteReg(U16 Data) //写寄存器

static void LcdWriteData(U16 Data) //写数据

static void LcdWriteDataMultiple(U16 * pData, int NumItems) //写入多组数据

static void LcdReadDataMultiple(U16 * pData, int NumItems) //读取多组数据

还有点反应,但是不知道为何,字符串都打印不出来
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-11 17:08:46 | 显示全部楼层
八度空间 发表于 2018-1-10 20:20
FSMC上面有个地址先Ax这个就是控制LCD的数据和命令的线,所以要弄好控制地址

现在已经参考了正点原子开发板上的程序。按照修改  _SetPixelIndex(),_GetPixelIndex(),_FillRect()函数后的程序,无法使用,整个屏幕没有任何反应。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-10 20:20:31 | 显示全部楼层
xyzjacky 发表于 2018-1-10 14:23
哦,原来上面所谓的寄存器和RAM地址,是和FSMC相关的。


FSMC上面有个地址先Ax这个就是控制LCD的数据和命令的线,所以要弄好控制地址
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-10 14:23:50 | 显示全部楼层
八度空间 发表于 2018-1-9 20:34
1、LCD寄存器和RAM操作方式具体可以看下FSMC的操作与控制,将这部分看明白了就理解代码的写法了
2、读点 ...

哦,原来上面所谓的寄存器和RAM地址,是和FSMC相关的。
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-1-9 20:34:17 | 显示全部楼层
xyzjacky 发表于 2018-1-9 11:43
本人有以下几个疑问,请各位指教:
1.有关LCD的寄存器和RAM操作地址。

1、LCD寄存器和RAM操作方式具体可以看下FSMC的操作与控制,将这部分看明白了就理解代码的写法了
2、读点函数,具体我也忘记了,毕竟好久没接触了,记得读点函数有坐标点参数的
3、如果emwin有支持的屏幕驱动,那就可以直接使用自带的,当然也可以使用自己写的,两种方式都是可以的,看你的爱好了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

6

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
201
金钱
201
注册时间
2013-8-15
在线时间
44 小时
发表于 2018-1-9 11:43:14 | 显示全部楼层
本人有以下几个疑问,请各位指教:
1.有关LCD的寄存器和RAM操作地址。

楼主是这样写的:

增加定义LCD寄存器、RAM操作地址,
#define LCD_BASE (uint32_t)(0x60000000 | 0x0001fffe) //基地址
#define LCD_REG_ADDRESS  (*(volatile U16*)LCD_BASE) //寄存器地址
#define LCD_DATA_ADDRESS  (*(volatile U16*)(LCD_BASE + 2)) //RAM地址

看样子楼主用的是ILI9341的。这些地址是否是需要emWIN底层驱动代码中有?如果用的LCD的驱动芯片不被emWIN支持,岂不是就用不了了(知道怎么移植驱动,那就不存在这个问题)。

2.关于移植时,读当前像素点的颜色的函数:static void LcdReadDataMultiple(U16 * pData, int NumItems)
这个函数里的移植该怎么写呢?
比如,我现在的读点颜色的函数是这样的:
unsigned short int LCD_Read_Point(unsigned short int cx,unsigned short int cy)
{
        unsigned char r=0,g=0,b=0;
        LCD_set_windows(cx,cy,cx,cy);
        LCD_wtREG(0x2E);
       
        LCD_Read_Data();                //只需要执行一次空读取
        r = LCD_Read_Data();
        g = LCD_Read_Data();
        b = LCD_Read_Data();
       
        LCD_wtREG(0x2C);                //关键步骤,必须要有

        return (((r>>3)<<11)|((g>>2)<<5)|(b>>3));
}

首先,我们读点的函数中,是加入了所读像素点的坐标。由于使用了emWIN,那就由调用emWIN的函数决定读哪里坐标的颜色,是这样吗?我是不用关心的,即不需要LCD_set_windows这个函数?

第二,移植时,是否要把LCD_wtREG(0x2E);加入? 因为还没有在emWIN手册上看到有这一块的详细介绍,凭楼主和其他网友所给资料,emWIN既然支持ILI9341,那么emWIN函数要读取像素点颜色时,它应该已经做了发送0X2E的指令,是这样吗?
也就是说,只要在这个函数中static void LcdWriteReg(U16 Data),移植了我自己编写的、正确的写寄存器代码,那就能搞定读点,不需要我去关心有没有发0X2E指令,是吗?
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2017-4-12 21:20:37 | 显示全部楼层
尧子 发表于 2017-4-12 17:20
为什么7寸屏无法显示

不会吧,我没试过7寸屏幕,最大就4.3的了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2015-9-20
在线时间
30 小时
发表于 2017-4-12 17:20:48 | 显示全部楼层
为什么7寸屏无法显示
回复 支持 反对

使用道具 举报

8

主题

156

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1552
金钱
1552
注册时间
2016-11-21
在线时间
411 小时
发表于 2017-4-7 16:43:23 | 显示全部楼层
这样直接改上去,读点函数是不对的,所以光标和小海豚移动的时候会出现问题T-T
回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2016-12-8 08:53:32 | 显示全部楼层
heap设置大一点
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

19

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2015-12-6
在线时间
47 小时
发表于 2016-12-7 20:22:27 | 显示全部楼层
八度空间 发表于 2016-12-5 20:37
你emwin缓冲开多大?堆栈你设置多大?

这个我也不知道哪个是缓冲和堆栈:


#include "GUI.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES  1024*50  //0x200000

/*********************************************************************
*
*       Public code
*
**********************************************************************



Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
                                                  
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

                PRESERVE8
                THUMB


是这两个吗



回复 支持 反对

使用道具 举报

120

主题

7884

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2016-12-5 20:37:36 | 显示全部楼层
我是520老谢 发表于 2016-12-3 17:10
跟进程序进去看,发现有很多函数导致进入硬件错误

你emwin缓冲开多大?堆栈你设置多大?
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-5-5 03:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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