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

【安富莱STemWin教程】第30章 指针输入设备(摇杆)

[复制链接]
baiyongbin2009 发布时间:2015-2-12 14:42
本帖最后由 baiyongbin2009 于 2015-2-12 14:43 编辑
8 h; J: ~2 D; V" \1 U/ e" R7 V3 W" g8 D' x9 s( {
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接* T: }/ z& J: a
第30章 指针输入设备(摇杆)
' A/ G1 H' J: Z" j% }+ K
    本期教程主要跟大家讲解指针输入设备,指针输入设备包括触摸屏、鼠标或游戏操纵杆。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_GetState()
返回PID的当前状态。
GUI_PID_StoreState()
存储PID的当前状态。
    上面两个函数的参数都是GUI_PID_STATE * pState。GUI_PID_STATE结构的定义如下:
typedef struct
{
    int x, y;
    U8 Pressed;
    U8 Layer;
} GUI_PID_STATE;
各个参数表示的意义如下:
30.1.png
30.3 五向摇杆操作游标
    下面给大家演示一下通过开发板上面带的五向摇杆来操作屏幕上的游标。五向摇杆的驱动请看安富莱STM32-V5开发板_用户手册的第20章:按键FIFO教程。五项摇杆操作游标的程序主要分为两部分:
  Ø 摇杆任务
  Ø STemWin主任务
摇杆任务的程序:
  1. /*+ b' {1 T& ?* q1 o7 K) R
  2. *********************************************************************************************************$ `6 a! f8 J: C+ m, g# ^
  3. *        函 数 名: AppTaskUserIF
    4 p; M8 y4 b  S, k, V
  4. *        功能说明: 此函数主要用于得到按键的键值。6 u, |  Y2 J2 j+ z& u
  5. *        形    参:p_arg 是在创建该任务时传递的形参
    1 p1 G" U( a" V$ }! ?; N# [4 i
  6. *        返 回 值: 无4 H/ ]  k6 e7 g
  7. 优 先 级:2* w, j0 N' e1 v. e9 Z7 |5 ~2 i
  8. *********************************************************************************************************
    ( G6 B+ ~- G8 C+ D
  9. */
    - K' P# D% e7 u1 a' S2 p
  10. ' ]8 V, A6 b$ T1 i* s
  11. static void AppTaskUserIF(void *p_arg)
    % m+ X2 @) D/ R% R7 ]* V, {% C
  12. {4 P& l" q7 }/ ~  ^/ H' X
  13. uint8_t uKeyCode;
    ) p7 {- \- `8 A) B6 Y! o% |: I7 N/ T  h
  14. int16_t  TimeAcc = 10;      /* 动态的加速数值  */
    ! k$ o0 y' w) M/ y& a
  15. GUI_PID_STATE State;(1)
    , z4 s" X8 S# @- E
  16. int16_t  Max;' z% b4 f9 z+ n$ W; C" B( }

  17. 2 a2 O2 I0 Y( p) u% K
  18. (void)p_arg;                       /* 避免编译器报警 */
    / K. V9 A: V& G5 I1 J
  19. : H) D7 c) J9 W, a
  20. while (1)
    - n( s) d  a; f+ J$ L
  21. {     F8 c" s: D. a8 `$ G
  22. bsp_KeyScan();
    $ f* |. R* n1 b7 m# g
  23. uKeyCode = bsp_GetKey();; x/ s# G! [2 o6 f1 j" Q6 l$ [6 b3 O
  24. if(uKeyCode != KEY_NONE)
    7 T' j* T* E" w" {4 ^
  25. {( g* P0 }7 g! ]
  26. if(uKeyCode == KEY_1_DOWN)
    1 B- K* D. v  y( ~4 S6 x- M0 O
  27. {' u/ N1 K' B5 z
  28. BSP_OS_SemPost(&SEM_SYNCH);5 z, t! K; @/ o( H0 N& u- n6 n
  29. }
    ! q0 I; f" f. P) V7 ?
  30. . x* q5 b# X% M
  31. /* 计算得到新的坐标值 */
    ; G# {% }% K, u( o
  32. GUI_PID_GetState(&State);(2)
      O5 @( W+ ^+ Z! p" @8 a1 n
  33. if (uKeyCode == JOY_DOWN_L) (3)7 y; ?: J5 F, r  m3 M
  34. {
    ) {$ P9 D; l& j+ X  o9 c" e1 l* d
  35. State.x -= TimeAcc;
    - t4 e$ V/ i4 d* \9 j3 z
  36. }; S+ s& e9 a# F
  37. if (uKeyCode == JOY_DOWN_R)  (4)
      Q% F- _% Y7 O6 B; Q! y
  38. {( [" A: @6 N! m+ A# ~1 o5 Z" S
  39. State.x += TimeAcc;
    # Q7 K4 \( H2 n. p7 |
  40. }  e/ [' X0 f  Z5 l4 `
  41. if (uKeyCode == JOY_DOWN_U)    (5)" {: @6 n0 b% n
  42. {
    - u" [7 K0 `2 B* @+ ~% l; o- x
  43. State.y -= TimeAcc;
    4 L( X0 h& ^/ c" v; u
  44. }* W  o0 N2 e( S& ?. y
  45. if (uKeyCode == JOY_DOWN_D) (6)7 F! K! v1 k7 Z0 h( ]# v/ n4 k- ?
  46. {
    ' V1 S" ]* X; H" U# o) [+ d* d+ ^
  47. State.y += TimeAcc;
    2 x. _2 y5 M% G7 w) P; a0 m4 O
  48.     }) V& }5 k! G! u& n/ F) f
  49. /* 确定坐标还在屏幕的范围内 */                                                        (7)
    7 X: G( u5 ]$ |3 V! D5 C
  50. if (State.x < 0)
    ! ]) j2 e* Z* v  @9 y0 i3 l
  51. {; \) ?; ?+ F) t; f- e
  52. State.x = 0;/ C, f6 Q2 v9 E0 n: B- Y, [
  53. }% d2 ]) `- w4 g& ?
  54. if (State.y < 0) % V& v2 m! R7 X3 p
  55. {
    9 O3 o# b; T  I& p
  56. State.y = 0;
    ) G6 v$ D& c/ f, Z9 q
  57. }
    7 u7 t" }; P- c
  58. Max = LCD_GetXSize() - 1;
    9 Z( V5 W( f4 ~$ f; [
  59. if (State.x >= Max)
    ( {5 V- B: B( c2 o9 e4 D" p
  60. {
    ( X% I" H1 \% I' F+ c
  61. State.x = Max;) p) P1 y4 C8 A; o4 v0 {' Q, d$ i1 }
  62. }
    0 b3 n# w$ W# m0 f  t/ m* X
  63. Max = LCD_GetYSize() - 1;
    / V) j7 Y- P# D0 Z
  64. if (State.y > Max) $ A) E5 S" L9 m
  65. {% k& B4 l) F# F- x; q6 t
  66. State.y = Max;
    / ?6 i' y- @- l1 t! ~* h
  67. }7 k' G, B' N/ ^7 a% W7 J: K
  68. / E7 M! i& `0 B& z' F7 s0 u8 e/ [
  69. State.Pressed = (uKeyCode == JOY_DOWN_OK ) ? 1: 0;(8), p" k+ G0 K/ ]( J7 q8 g
  70. GUI_PID_StoreState(&State);         (9)
    " R2 v% R8 u8 ]% \4 e
  71.         }
    8 x- \, I; {; n! m" w1 s
  72.         BSP_OS_TimeDlyMs(10);
    : [! \% v+ \- v+ W- Y* j' u. w0 {5 M
  73. }) P, q  h8 o( I* q/ A: e' ?# r4 G
  74. }
复制代码
1. 定义一个GUI_PID_STATE类型的变量。
2. 获取当前游标所在的位置。
3. 如果是摇杆左键按下,将游标向左移动10个像素。
4. 如果是摇杆右键按下,将游标向右移动10个像素。
5. 如果是摇杆上键按下,将游标向上移动10个像素。
6. 如果是摇杆下键按下,将游标向下移动10个像素。
7. 防止摇杆移动的游标超出屏幕范围。
8. 如果是摇杆OK键按下,将使能按下状态。
9. 存储PID的当前状态。
STemWin主任务程序如下:
  1. #include "includes.h"
    : N9 Z0 p0 _& Z+ _
  2. #include "MainTask.h"
    ; s  V2 j; ~% Z. }+ C7 G3 N( J

  3. + L+ o. |5 V) R: c5 d6 l. g# O3 n- b; h
  4. 9 {. j$ G9 S& k7 T: p6 @
  5. int i;
    . ^) O( o) \: H8 V% @
  6. char acText[] = "www.armfly.com  www.armfly.taobao.com Eric2013";
    - O( F; C+ @5 e2 H$ q. T) |4 N5 s
  7. GUI_RECT Rect = {10, 10, 59, 59};, Y5 N8 N+ x9 x0 F
  8. GUI_WRAPMODE aWm[] = {GUI_WRAPMODE_NONE,
    ) I3 ?6 F2 |/ u" {. p3 m  O) g  V
  9.                       GUI_WRAPMODE_CHAR,
    9 J0 e& y7 m5 m% ]# N" _7 P
  10.                       GUI_WRAPMODE_WORD};
    9 Y2 A" g# l5 A8 L
  11. /*( `, C2 ~1 `8 j: b
  12. *********************************************************************************************************
    / _2 M6 ~) w+ Q8 R  M; s+ f  M
  13. *        函 数 名: MainTask
    * X* r5 W1 w- n+ }/ D
  14. *        功能说明: GUI主函数
    4 J. _  _& |( b
  15. *        形    参:无& C  ?! T4 w9 p
  16. *        返 回 值: 无
    : u- H; [& B! Q& ]# B9 _. s
  17. *********************************************************************************************************
    0 }5 w& [* V2 y" {  f8 {4 w; y/ }
  18. */
    ' L% R0 ?" k0 I: L- H3 v- z
  19. void MainTask(void) * Y/ W% c' H% q# v- F- c
  20. {
    ' w& C# b( s$ I) j, [: V1 C+ \6 q
  21.     GUI_Init();0 \0 C, r- a# p8 b( [% p
  22. GUI_CURSOR_Show();& }- S( K8 R0 S  r6 e
  23.     GUI_SetTextMode(GUI_TM_TRANS);, a; N, r4 _% h2 K
  24.     for (i = 0; i < 3; i++)
    - t! L# g  P7 m4 S
  25.     {, N4 I6 ^1 ~) ?- M, [+ }
  26.         GUI_SetColor(GUI_BLUE);( G8 m( p* Y  B" D
  27.         GUI_FillRectEx(&Rect);
    ; E5 Z) I7 i% e+ C6 A, a# `
  28.         GUI_SetColor(GUI_WHITE);
    - K1 y% k' x. e  E- ?
  29.         GUI_DispStringInRectWrap(acText, &Rect, GUI_TA_LEFT, aWm[i]);
    ; S4 N7 u% U* b% w" z
  30.         Rect.x0 += 60;3 w( Y, Q& Y8 J
  31.         Rect.x1 += 60;( q. G, N7 f5 a6 G2 W* Q* A, z$ i
  32.     }" u6 `6 L0 k6 J) q; w0 j. V1 C
  33.     while (1)
    0 ?& O/ i/ c" F5 ]9 H' v
  34.     {
    . x5 V% E2 V, j6 g! c! ^5 Q
  35.         GUI_Delay(10);
    7 L- [/ C3 N4 e; w& _7 z
  36.     }
    2 I1 U* _; b4 K  w3 E
  37. }
复制代码
主程序比较的简单,只是显示一个比较简单的画面,大家可以在这个界面上操作游标。界面效果如下:
30.2.png
30.4 总结
    本期教程就跟大家讲这么多,整体来说内容比较的简单,触摸和鼠标会在后面的教程中再跟大家详细的讲述。

. W6 P" i4 r- {) C
赞 收藏 评论4 发布时间:2015-2-12 14:42

举报

4个回答
wyxy163@126.com 回答时间:2015-2-12 14:58:50
提示: 作者被禁止或删除 内容自动屏蔽
lkl0305 回答时间:2015-2-12 16:57:31
多谢分享!!
w小菜才 回答时间:2015-2-12 21:30:40
学习。。。。。
feel-376797 回答时间:2015-2-13 07:15:02
谢谢分享
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版