本帖最后由 baiyongbin2009 于 2015-2-12 14:43 编辑
5 t" v" E! y# U) r$ R$ Q( [2 h7 b5 a0 s
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接3 r8 Q& x' j- d& a* z& F J: D
第30章 指针输入设备(摇杆)
1 Q8 O/ _- i0 \6 l 本期教程主要跟大家讲解指针输入设备,指针输入设备包括触摸屏、鼠标或游戏操纵杆。STemWin基础版包括模拟触摸屏的驱动、PS2鼠标驱动和示例游戏操纵杆驱动。只要有适当的驱动,也可以使用其他类型的触摸屏和鼠标设备。本期教程要讲的是指针输入设备中的摇杆,触摸屏和鼠标会在后面有专门的教程。 30. 1 描述 30. 2 指针输入设备(API) 30. 3 五向摇杆操作游标 30. 4 总结 30.1 描述 指针输入设备指鼠标、触摸屏、游戏操纵杆等设备。单个应用中可以使用多个指针输入设备,以支持鼠标/触摸屏/游戏操纵杆的同时使用。一般地,指针输入设备(PID)驱动所做的是在检测到事件(如移动鼠标或者按下触摸屏等)时调用GUI_PID_StoreState()程序。窗口管理器负责对PID事件作出正确反应;如果未使用窗口管理器,则由应用负责对PID事件作出反应。 30.2 指针输入设备(API) 下表按字母顺序列出了指针输入设备程序。详细描述如下。 注:该API由PID驱动使用;如果使用emWin自带的PID驱动,则代码中无需调用这些程序。 上面两个函数的参数都是GUI_PID_STATE * pState。GUI_PID_STATE结构的定义如下: typedef struct { int x, y; U8 Pressed; U8 Layer; } GUI_PID_STATE; 各个参数表示的意义如下: 30.3 五向摇杆操作游标 下面给大家演示一下通过开发板上面带的五向摇杆来操作屏幕上的游标。五向摇杆的驱动请看安富莱STM32-V5开发板_用户手册的第20章:按键FIFO教程。五项摇杆操作游标的程序主要分为两部分: Ø 摇杆任务 Ø STemWin主任务 摇杆任务的程序: - /*
' l k# m/ S5 L2 b8 g - *********************************************************************************************************
) g. F3 |& l& k3 l, }6 t - * 函 数 名: AppTaskUserIF2 d: K. l, e5 M9 a& H
- * 功能说明: 此函数主要用于得到按键的键值。, F: n$ I+ Y) J& Q! ]- O
- * 形 参:p_arg 是在创建该任务时传递的形参
* t8 ?7 K" h! \. \ - * 返 回 值: 无 f) P$ p) Z' I. y4 J
- 优 先 级:2
6 j7 v0 V8 ?6 T1 R* {; l F - *********************************************************************************************************
7 T2 ?# l6 \4 L% G - */% l3 T- @+ m" p2 t" m9 x
-
3 o! Y3 D% c* S" p, m - static void AppTaskUserIF(void *p_arg)% Q& l9 @7 L, l& E4 r3 G4 Q
- {4 q' t1 I. w! x! L% \. p R0 I1 v
- uint8_t uKeyCode;
8 r+ @) b/ `& o# u$ V - int16_t TimeAcc = 10; /* 动态的加速数值 */' C7 D! U( z+ t+ P5 J
- GUI_PID_STATE State;(1)
8 g5 l- C8 L+ T8 n& q/ H - int16_t Max;
/ K) l7 I2 K1 i2 ?- p" B4 F -
8 L+ f8 t+ J6 W7 T9 ~ - (void)p_arg; /* 避免编译器报警 */
: a; j. r( b) h -
& |" a) Z+ g2 q9 L* Z/ t/ @ - while (1)
0 g' D: ]( |4 p6 y8 l, j - { 0 G% S( w, j' ]7 e
- bsp_KeyScan();
; i& }( c4 \. I5 _ - uKeyCode = bsp_GetKey();5 M6 |8 Z5 N: G# w
- if(uKeyCode != KEY_NONE)
2 d) k* F4 I/ b. Q - {, [1 v4 i0 H7 `' r# w
- if(uKeyCode == KEY_1_DOWN) B4 s/ r0 r; b' y3 N
- {4 h" G- D3 B' N8 v: H% N
- BSP_OS_SemPost(&SEM_SYNCH);! X S$ c/ H1 A" I) C w
- }3 a1 [2 n( U3 V. O8 d
- 6 j% L/ S, {/ B8 v3 I
- /* 计算得到新的坐标值 */
$ b( x' U% {# n2 O- f! L n - GUI_PID_GetState(&State);(2)
/ n$ G" N( F6 h1 U9 Q - if (uKeyCode == JOY_DOWN_L) (3)9 Z( p& z4 B/ b, ]
- {. \: e0 p) S0 o+ \. k
- State.x -= TimeAcc;; |8 }* t) @2 m% c* c
- }. k' Q) T/ q; w9 K8 ?
- if (uKeyCode == JOY_DOWN_R) (4) u2 D* i3 H) R( \
- {5 O$ F/ S6 D8 \
- State.x += TimeAcc;: D2 o7 m6 o9 ^% S# |: { ~
- }7 \, M) H7 p8 ] C
- if (uKeyCode == JOY_DOWN_U) (5)) c8 q4 n! i$ k+ d! G; h
- {# v, w/ M! `9 p, w$ Q
- State.y -= TimeAcc;: k% |+ B0 ^: q2 g; U
- }
% v( P7 u5 k2 ]* t$ N. L8 o$ Y - if (uKeyCode == JOY_DOWN_D) (6)
a$ m3 y: O7 F/ L" B - {3 \) u* `" K; c) X& }& n5 Q/ z
- State.y += TimeAcc;) U( ~- Q$ K8 O$ W% j
- }+ g& S9 E' O k g4 Y
- /* 确定坐标还在屏幕的范围内 */ (7)
* v7 i. t- S1 ~ - if (State.x < 0) ( p1 t* i, F0 r" N
- {
* G9 g' V$ F: u: ]4 l - State.x = 0;
: ]* z) {' W# B8 w- q* I. I - }
; A( D% a# C# l/ ?* A, W - if (State.y < 0) % c# N3 o% o S2 u% ~6 x
- {
" [! T. p. k1 ^4 z$ d - State.y = 0;
& y. b: E) S* `+ ~# U7 e8 |% E - }
T0 ^$ _* m/ g2 X# y7 _4 e. L - Max = LCD_GetXSize() - 1;
+ X. ~* l7 C5 N5 c9 x - if (State.x >= Max) / L# N# k1 q9 B! v& ?. j
- {3 a9 t& Y2 _6 H! H- }
- State.x = Max;
5 o" E+ }! P& l* F - }! l* i* ?! ?! W& z; Q0 e" b
- Max = LCD_GetYSize() - 1;; U5 N- i7 P2 X7 q) I0 `
- if (State.y > Max)
* @1 f9 V' o5 L( s0 x6 ?" x - {
u6 h1 b6 m( t; t" Q - State.y = Max;
. Z+ C p2 ?4 X - }
3 `5 o% t: ?, t - 8 ]" u4 x2 O7 r4 W, _4 K& O
- State.Pressed = (uKeyCode == JOY_DOWN_OK ) ? 1: 0;(8) J4 v$ h3 {: ~( U" X7 b
- GUI_PID_StoreState(&State); (9)" B0 W2 y8 J4 E
- }' q' ?- ]. }, B1 @: e
- BSP_OS_TimeDlyMs(10);* j9 W3 E% N. ~/ t
- }
4 B7 {% `0 `- h - }
复制代码1. 定义一个GUI_PID_STATE类型的变量。 2. 获取当前游标所在的位置。 3. 如果是摇杆左键按下,将游标向左移动10个像素。 4. 如果是摇杆右键按下,将游标向右移动10个像素。 5. 如果是摇杆上键按下,将游标向上移动10个像素。 6. 如果是摇杆下键按下,将游标向下移动10个像素。 7. 防止摇杆移动的游标超出屏幕范围。 8. 如果是摇杆OK键按下,将使能按下状态。 9. 存储PID的当前状态。 STemWin主任务程序如下: - #include "includes.h"; ~' t$ m" N9 o
- #include "MainTask.h"+ j6 j, U* `& B: D
-
n* D! A. ~# E, h; | j/ r - + ^ ~) B# ?8 Q8 p' w- S U
- int i;
7 H1 F1 n+ k. [% M% G$ @ - char acText[] = "www.armfly.com www.armfly.taobao.com Eric2013";4 ^5 l) S6 ^7 x( i
- GUI_RECT Rect = {10, 10, 59, 59};
& w( y1 d4 Y! \6 l - GUI_WRAPMODE aWm[] = {GUI_WRAPMODE_NONE,
8 N" {7 X y+ m3 \ - GUI_WRAPMODE_CHAR,
$ G Y4 g; @) x+ N - GUI_WRAPMODE_WORD};# B$ K/ W, y& r) z3 d3 N
- /*# o- `3 v+ U @! S j/ ]" W# b4 B
- *********************************************************************************************************
" d8 O v9 i0 e. o1 M - * 函 数 名: MainTask
7 p1 m n; y% C; i/ V - * 功能说明: GUI主函数1 g' {4 G' w3 L* ^0 `: w0 A
- * 形 参:无
$ l* F( v; T0 l! K - * 返 回 值: 无
, H' h! M: U* T% ?2 | - *********************************************************************************************************
% }4 e' }5 Y& y* Y5 X - */
" _' n( \/ v3 M7 i - void MainTask(void)
6 k7 ]- Z+ ]- w4 O4 ]6 D- [, v - {
( r& Z, F0 f1 g! ? - GUI_Init();
8 J4 e, n* ^# Q7 b0 u f* ^ - GUI_CURSOR_Show();: I4 ]4 E7 [* d2 [: I
- GUI_SetTextMode(GUI_TM_TRANS);
) f! j5 L8 B8 Y; n - for (i = 0; i < 3; i++)
2 ?0 v7 W0 f v* A3 C - {
- L W, z6 n8 i( d - GUI_SetColor(GUI_BLUE);
; d9 f5 c: i) @0 b* N - GUI_FillRectEx(&Rect);; r, k* ]9 w0 a& G5 T7 {, }6 l
- GUI_SetColor(GUI_WHITE);
* q" ~+ `" b3 r" a - GUI_DispStringInRectWrap(acText, &Rect, GUI_TA_LEFT, aWm[i]);/ p4 [3 `# s- T- s9 C/ n
- Rect.x0 += 60;7 v0 W$ p( ?, J2 g5 Z7 a: V; A
- Rect.x1 += 60;
# V$ T+ U: [. t6 m - }9 P ^! @8 C$ m. m+ L& }
- while (1)
% d6 q/ V0 t# o - {9 Z# U9 c9 ]. P8 Z; L+ S" M; d
- GUI_Delay(10);
( d, ^' C" ]3 E, x0 K - }- R' ]6 D# d( I$ |( e+ n1 O
- }
复制代码主程序比较的简单,只是显示一个比较简单的画面,大家可以在这个界面上操作游标。界面效果如下: 30.4 总结 本期教程就跟大家讲这么多,整体来说内容比较的简单,触摸和鼠标会在后面的教程中再跟大家详细的讲述。 1 c( X+ W6 P$ o) O' A0 j
|