你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

移植STemwin的好贴子(转)

[复制链接]
ddllxxrr 发布时间:2018-5-6 10:34
本帖最后由 ddllxxrr 于 2018-5-6 10:56 编辑 $ c$ g& i  d& u) p2 f2 w3 G

9 [' ~4 P: X0 u* u% \6 C我按照网上的移植贴子移了一天也没有成功,总显示乱字符,今天看了这个贴子,一下子成功了,给后来者来个方便转一下:L' c4 B# ~* N: {" m" ]3 Y9 e
9 D. v+ ^6 U$ u5 R' G% R4 a/ b4 a

8 L+ r, _1 [5 K! a" l1 n原贴网址:3 b! A( w+ C0 k2 f
http://blog.csdn.net/wangyijieonline/article/details/76795084
% @" j$ Q* ?; ?  g5 M* X
( k$ I! {9 R% F* {( x' R: K8 @  O2 K9 b# {9 J

这几天在看原子哥的教程的时候,突然发现有个STemwin的教程,然后就想来捣鼓捣鼓,但没想到,原本以为很简单的移植却遇到困难重重,特立下此帖警示后人!!!

首先下载源码,构建工程什么的假设已经完成了,而且也已经有了一个可以正常显示的Demo,这是最基本的,如果这些都还没做好,那就需要先准备一下了。

然后有了一个正常显示的demo还不够,还必须要准备好这么几个函数,后面要用到。 ! f3 n+ y0 @" [5 B
1,LCD_DrawPoint(x,y,PixelIndex); //画点函数,注意有三个参数
# P" L6 {0 W. r2,LCD_ReadPoint(x,y);//读点的颜色,两个参数 0 x+ h4 j* G6 c0 h0 p
3,LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX);//清屏函数,不能用自带的,太慢了

其实这几个函数应该很好准备,如果你的LCD已经正常显示了,那么说明LCD_DrawPoint和LCD_Fill最起码已经可用,或者修改一下可用,readpoint需要着重的准备下。


正题开始了,理论上来说,移植STemwin应该是有两种方法,第一种是完全不用STemwin的接口,使用我们自己的,这就是上面准备的几个函数的用途,第二种方法是直接填充STemwin的画点等相关函数,当然这两种方法也可以同时移植但是最后用哪种方法是怎么选择呢,答案就是LCDConf_FlexColor_Template.c 中的LCD_X_Config函数中的GUI_DEVICE_CreateAndLink接口。
4 e- M- z6 I! H如果设置为

GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);
  • GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API, GUICC_M565, 0, 0);
    4 K' a; P- |' p& Z& L

则使用的是我们自己的接口 # T0 I. o' V, m2 f
如果是

GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0);
  • GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0);
    5 P; u; v6 ~6 o2 t' ?) K$ D- f$ l

则使用默认的填充接口。 3 y8 c$ f: T+ d; \( s7 X
注意了这个地方有个注意的点,就是GUICC_M565 和 GUICC_565 ,这两兄弟看起来很像,其实他们所表示的颜色是完全反相的。

我们先来说第一种移植方法(使用自己的接口): % k9 Y6 V$ A1 _6 Y. O
第一步:新建一个LCD_Conf.h文件,空文件即可,里面不需要有内容 8 W$ p. r# D& ^9 x' d( U
第二步:打开LCDConf_FlexColor_Template.c 屏蔽掉LCD_X_Config函数前面的四个函数,对了,这四个函数就是第二种方法需要填充的,这里先把话说清楚为什么不要了。而 LCD_X_Config函数也要屏蔽一些东西,如下

  1. void LCD_X_Config(void) {
    2 M# U7 x' F3 U9 ^6 r  k1 N% O
  2.     //, E! t. F$ F, q& \; c4 ^
  3.   // Set display driver and color conversion* ~% @3 j; `7 S0 A& A, M  a
  4.   //* I: ^4 g/ }! @* W+ ^5 E2 f
  5.   GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0);! l: k; R9 T/ T3 X" u+ u
  6.   //1 @9 }8 q4 H% J9 N6 D
  7.   // Display driver configuration, required for Lin-driver5 w% B* t! C" B
  8.   //# c0 J5 B4 ?1 w- f. ]% G* j; P, F
  9.   LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
    " h, Q9 H# c6 l: G( b  d$ T9 f1 T
  10.   LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
    $ q  U. e2 W/ m1 U2 H" D* E
  11.   //
    : m  K; ?' e% q
  12.   // Orientation
    3 {3 N! O& r! I, j1 t
  13.   //, A7 u% X6 {4 S' R. v# U6 L
  14. //  Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_Y;
    4 v" S- u* q3 F7 f( d' T
  15. //  GUIDRV_FlexColor_Config(pDevice, &Config);
    : K4 \" A% N/ r) f7 `  _. `9 {: z  j8 Q( K
  16. //  //; x; G, H- x0 T# n( X5 [
  17. //  // Set controller and operation mode1 K' I$ |3 b1 f% s9 Z! t
  18. //  //3 Q/ r% I* `$ L
  19. //  PortAPI.pfWrite16_A0  = LcdWriteReg;5 q/ p& _% g* z. W
  20. //  PortAPI.pfWrite16_A1  = LcdWriteData;1 l" O! z: }/ g  b- T2 b1 U
  21. //  PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple;3 B) d! g4 y; f1 e' \8 a& s! s
  22. //  PortAPI.pfReadM16_A1  = LcdReadDataMultiple;
    6 m) z# f9 V7 T1 {
  23. //  GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66708, GUIDRV_FLEXCOLOR_M16C0B16);% |: [3 M# V4 n) i! e  L: w0 X5 U
  24. }
复制代码
" j' c, o# B& P

屏蔽掉的是引用的函数,只留下三行。

下面还有个函数 LCD_X_DisplayDriver ,这个函数的作用,如官方所说

  这是显示驱动的回调函数。显示驱动在多个任务中要调用该函数。将一个命令和一个指向某个数据结构的指针传给回调程序。该命令告诉回调函数需要做什么。如果命令需要参数,则通过数据指针pData 传送。
  • 这是显示驱动的回调函数。显示驱动在多个任务中要调用该函数。将一个命令和一个指向某个数据结构的指针传给回调程序。该命令告诉回调函数需要做什么。如果命令需要参数,则通过数据指针pData 传送。
    $ b, s% O% N# l" L

我们用这个函数来做初始化的工作,在return 0前面写上你的LCDTFT_Init(),注意最好不要把你的函数写成LCDTFT_Init() ,因为STemwin自带了一个lcd.c lcd.h 预防冲突。

第二步,打开GUIDRV_Template.c 找到_SetPixelIndex 函数,在注释下面加上我们的打点函数

  1. GUI_USE_PARA(PixelIndex);
    . c$ v* T3 r" F" `# ~) T
  2. {
    $ o0 G7 ]* I) W, X  T/ r$ m
  3.       //- O7 {% H/ B1 U; B  c
  4.       // Write into hardware ... Adapt to your system4 j9 l2 T, H$ V# ?* W4 T
  5.       //
    . [( a5 Q! a8 I4 j, ~0 ~; f0 R
  6.             LCD_DrawPoint(x,y,PixelIndex);
    ! _5 x+ I  |+ Y* h
  7. }
复制代码
5 u$ f  \8 D9 ^

再往下看_GetPixelIndex ,在注释下面加上读点函数

  1. GUI_USE_PARA(y);' T: o  C0 e$ X: M
  2. {+ R2 k! _( _6 T" y" r9 \% O/ p
  3.   //
    & p7 E( F( T. x' a( \- D! a
  4.   // Write into hardware ... Adapt to your system
    ) Y" z9 f1 t% }! x8 j+ v) ?+ ]
  5.   //4 g$ C+ \% X. t2 f( }- ~% K( ~
  6.   PixelIndex = LCD_ReadPoint(x,y);: z7 Z! O0 v7 `/ _& M- l, B' `
  7.   PixelIndex = 0;
    2 N3 q9 x7 N! O  O
  8. }
复制代码
7 t* B" S' J7 X  G

再往下看_FillRect 函数,把else部分改成LCD_Fill,不然清屏太慢了

  1. else {; g8 C' C/ n& E* j( T
  2. //    for (; y0 <= y1; y0++) {
    1 ^/ ^6 t5 F/ G6 f" P( ]# s3 u
  3. //      for (x = x0; x <= x1; x++) {
    8 ~/ P# S2 U) v# P: F) X# [1 N* [
  4. //        _SetPixelIndex(pDevice, x, y0, PixelIndex);! f% S6 z% `( n; B2 X
  5. //      }: Y' r) A  N" L
  6. //    }( I8 A8 W9 F/ m: V, E9 [
  7.     LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX);
    5 w2 D9 |) _5 f- q: ~, I& g9 ~
  8.   }
复制代码

( e) C8 U9 J" v# d( o9 n

到此为止,第三步也结束了,也没有很难对不对。


更正:经实测发现这个清屏函数改了以后虽然刷屏速度上来了,但是会出现显示花屏的情况,所以说这个函数大家根据自己的情况修改。


第四步:打开 GUIConf.c 文件,找到GUI_NUMBYTES ,改成

#define GUI_NUMBYTES  1024 *40

这个是定义的Emwin所占的内存空间,如果太大的话,就会出现
. w9 d6 Y# z) fError: L6406E: No space in execution regions with .ANY selector matching lcd.o(.data). 4 V" o6 s& D: c: x3 p0 m" E& k; }- L
类似的错误。

第六步:打开stm32f4xx_it.c 找到SysTick_Handler 改为如下

  1. extern __IO int32_t OS_TimeMS;
    % {1 i9 `, c& b1 x3 K8 X  E. C7 D

  2. 3 p1 o' }! t2 c) e. L
  3. void SysTick_Handler(void)
    + I* y$ ^- F- O0 G2 s
  4. {& Y% o8 T9 F4 H& \* Z
  5.     OS_TimeMS++;/ B" @3 B4 D/ Y% w$ U8 I3 r8 a
  6.     if(OS_TimeMS%100 == 0)
    . p, D% M: i- T1 O5 c
  7.     {- P1 H& L8 r# R
  8.         LED1 = !LED1;//加个LED指示一下3 U, h7 h7 R# P% ^
  9.     }7 @5 F/ J. X* E' `1 |  N9 h
  10. }
复制代码
9 a6 V8 Q8 R  @; M3 `! B

到这里移植就算是完成了,剩下的就是,写个mian函数测试一下了

  1. #include "Global.h"
    " `0 n, u. {  f/ a+ Q
  2. #include "lcd.h"  l. i. k" P4 g9 v" U. A
  3. #include "WM.h"  u% e6 w& K* t  G
  4. #include "GUI.h"; F, i" i: {, {9 Z, Q6 C; }; x# }- r
  5. #include "led.h"
      b( R+ T! q9 Z8 Z
  6. #include "usart.h"0 r4 d$ f. R8 Y: [2 C) o% U8 z) E
  7. #include "delay.h"& C) N7 F) Q4 Y
  8. #include "lcd9341.h"3 x+ J& f  v0 ~' y

  9. 1 J% B9 z* R4 g; R' t  I7 u. L# v
  10. int main(void)
    ; L5 v& C' @" U4 t$ N  G2 u+ z& N
  11. {6 r8 E0 E9 s* ?4 G' \+ y8 G
  12.     LED_Init();
    7 a5 a2 P5 e* w% h$ h
  13.     USART1_init();
    + q; G. O; Y: u' O
  14. # E7 M; }! }7 c$ b+ X+ l* Y
  15.     SysTick_Config(SystemCoreClock / 1000);//要加上这句话,开启Systick中断
    ; T1 u7 @' b6 p# Z  ~% Z

  16. 9 M' @: z  Q  g4 |+ @  @  x  R
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE); //要加上这句话,打开CRC时钟! e9 p9 h8 a4 L; r0 T
  18.     WM_SetCreateFlags(WM_CF_MEMDEV);//要加上这句话,允许存储器
    5 L! ^/ |8 D! ^; w3 b
  19.     GUI_Init();//要加上这句话,Init
    8 m; f; t" p2 K! T0 Y  o: D7 h4 `
  20.     GUI_Clear();
    * s% V& u4 u( s9 {; ]$ L9 s
  21.     GUI_DispStringAt("Hello World!",30,120);) f( g9 B( x7 z) t+ e

  22. ) a* u' A" {; k
  23.     while(1);
    & l3 e; \- D  V0 W& I6 |, v% S
  24. }
复制代码

' |0 @  Q. S% L' ~- K3 N

20170806221143340.png

帖子太长不适合看,下篇帖子继续写第二种方法


  I. q2 d+ a0 s( T: Y
: ]6 P+ J$ o% T1 \8 U  q; z
( v. }1 O$ ^" L
6 e1 `* l) ^8 `( s1 @
赞 收藏 4 评论2 发布时间:2018-5-6 10:34

举报

2个回答
红旗飘扬 回答时间:2018-11-29 16:27:41
正在学习中
Kevin_G 回答时间:2019-5-18 11:43:43
正在学习

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版