本帖最后由 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函数也要屏蔽一些东西,如下 - void LCD_X_Config(void) {
2 M# U7 x' F3 U9 ^6 r k1 N% O - //, E! t. F$ F, q& \; c4 ^
- // Set display driver and color conversion* ~% @3 j; `7 S0 A& A, M a
- //* I: ^4 g/ }! @* W+ ^5 E2 f
- GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0);! l: k; R9 T/ T3 X" u+ u
- //1 @9 }8 q4 H% J9 N6 D
- // Display driver configuration, required for Lin-driver5 w% B* t! C" B
- //# c0 J5 B4 ?1 w- f. ]% G* j; P, F
- LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
" h, Q9 H# c6 l: G( b d$ T9 f1 T - LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
$ q U. e2 W/ m1 U2 H" D* E - //
: m K; ?' e% q - // Orientation
3 {3 N! O& r! I, j1 t - //, A7 u% X6 {4 S' R. v# U6 L
- // Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_Y;
4 v" S- u* q3 F7 f( d' T - // GUIDRV_FlexColor_Config(pDevice, &Config);
: K4 \" A% N/ r) f7 ` _. `9 {: z j8 Q( K - // //; x; G, H- x0 T# n( X5 [
- // // Set controller and operation mode1 K' I$ |3 b1 f% s9 Z! t
- // //3 Q/ r% I* `$ L
- // PortAPI.pfWrite16_A0 = LcdWriteReg;5 q/ p& _% g* z. W
- // PortAPI.pfWrite16_A1 = LcdWriteData;1 l" O! z: }/ g b- T2 b1 U
- // PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple;3 B) d! g4 y; f1 e' \8 a& s! s
- // PortAPI.pfReadM16_A1 = LcdReadDataMultiple;
6 m) z# f9 V7 T1 { - // GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66708, GUIDRV_FLEXCOLOR_M16C0B16);% |: [3 M# V4 n) i! e L: w0 X5 U
- }
复制代码 " 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 函数,在注释下面加上我们的打点函数 - GUI_USE_PARA(PixelIndex);
. c$ v* T3 r" F" `# ~) T - {
$ o0 G7 ]* I) W, X T/ r$ m - //- O7 {% H/ B1 U; B c
- // Write into hardware ... Adapt to your system4 j9 l2 T, H$ V# ?* W4 T
- //
. [( a5 Q! a8 I4 j, ~0 ~; f0 R - LCD_DrawPoint(x,y,PixelIndex);
! _5 x+ I |+ Y* h - }
复制代码 5 u$ f \8 D9 ^
再往下看_GetPixelIndex ,在注释下面加上读点函数 - GUI_USE_PARA(y);' T: o C0 e$ X: M
- {+ R2 k! _( _6 T" y" r9 \% O/ p
- //
& p7 E( F( T. x' a( \- D! a - // Write into hardware ... Adapt to your system
) Y" z9 f1 t% }! x8 j+ v) ?+ ] - //4 g$ C+ \% X. t2 f( }- ~% K( ~
- PixelIndex = LCD_ReadPoint(x,y);: z7 Z! O0 v7 `/ _& M- l, B' `
- PixelIndex = 0;
2 N3 q9 x7 N! O O - }
复制代码 7 t* B" S' J7 X G
再往下看_FillRect 函数,把else部分改成LCD_Fill,不然清屏太慢了 - else {; g8 C' C/ n& E* j( T
- // for (; y0 <= y1; y0++) {
1 ^/ ^6 t5 F/ G6 f" P( ]# s3 u - // for (x = x0; x <= x1; x++) {
8 ~/ P# S2 U) v# P: F) X# [1 N* [ - // _SetPixelIndex(pDevice, x, y0, PixelIndex);! f% S6 z% `( n; B2 X
- // }: Y' r) A N" L
- // }( I8 A8 W9 F/ m: V, E9 [
- LCD_Fill(x0,y0,x1,y1,LCD_COLORINDEX);
5 w2 D9 |) _5 f- q: ~, I& g9 ~ - }
复制代码
( 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 改为如下 - extern __IO int32_t OS_TimeMS;
% {1 i9 `, c& b1 x3 K8 X E. C7 D
3 p1 o' }! t2 c) e. L- void SysTick_Handler(void)
+ I* y$ ^- F- O0 G2 s - {& Y% o8 T9 F4 H& \* Z
- OS_TimeMS++;/ B" @3 B4 D/ Y% w$ U8 I3 r8 a
- if(OS_TimeMS%100 == 0)
. p, D% M: i- T1 O5 c - {- P1 H& L8 r# R
- LED1 = !LED1;//加个LED指示一下3 U, h7 h7 R# P% ^
- }7 @5 F/ J. X* E' `1 | N9 h
- }
复制代码 9 a6 V8 Q8 R @; M3 `! B
到这里移植就算是完成了,剩下的就是,写个mian函数测试一下了 - #include "Global.h"
" `0 n, u. { f/ a+ Q - #include "lcd.h" l. i. k" P4 g9 v" U. A
- #include "WM.h" u% e6 w& K* t G
- #include "GUI.h"; F, i" i: {, {9 Z, Q6 C; }; x# }- r
- #include "led.h"
b( R+ T! q9 Z8 Z - #include "usart.h"0 r4 d$ f. R8 Y: [2 C) o% U8 z) E
- #include "delay.h"& C) N7 F) Q4 Y
- #include "lcd9341.h"3 x+ J& f v0 ~' y
1 J% B9 z* R4 g; R' t I7 u. L# v- int main(void)
; L5 v& C' @" U4 t$ N G2 u+ z& N - {6 r8 E0 E9 s* ?4 G' \+ y8 G
- LED_Init();
7 a5 a2 P5 e* w% h$ h - USART1_init();
+ q; G. O; Y: u' O - # E7 M; }! }7 c$ b+ X+ l* Y
- SysTick_Config(SystemCoreClock / 1000);//要加上这句话,开启Systick中断
; T1 u7 @' b6 p# Z ~% Z
9 M' @: z Q g4 |+ @ @ x R- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE); //要加上这句话,打开CRC时钟! e9 p9 h8 a4 L; r0 T
- WM_SetCreateFlags(WM_CF_MEMDEV);//要加上这句话,允许存储器
5 L! ^/ |8 D! ^; w3 b - GUI_Init();//要加上这句话,Init
8 m; f; t" p2 K! T0 Y o: D7 h4 ` - GUI_Clear();
* s% V& u4 u( s9 {; ]$ L9 s - GUI_DispStringAt("Hello World!",30,120);) f( g9 B( x7 z) t+ e
) a* u' A" {; k- while(1);
& l3 e; \- D V0 W& I6 |, v% S - }
复制代码
' |0 @ Q. S% L' ~- K3 N
帖子太长不适合看,下篇帖子继续写第二种方法
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 @ |