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

【安富莱——DSP教程】第45章 示波器设计—系统框架

[复制链接]
baiyongbin2009 发布时间:2015-5-5 11:45
特别说明:完整45期数字信号处理教程,原创高性能示波器代码全开源地址:链接  O3 h" V9 r, o+ b5 q2 \/ j; W; Y
第45章 示波器设计—系统框架

( U$ k5 r+ h% A5 e+ q
    本章节主要是对示波器的系统框架做一个简单的介绍,后面会推出示波器的详细设计分析。示波器的的源码注释已经很详细,对框架有个了解之后看源码即可。
    45.1 ucos-iii任务分配
    45.2 示波器核心任务
    45.3 DAC实现方波的输出
    45.4 ADC实现数据的采集
    45.5 总结
) M, T9 f8 a& q, u  a. c7 T1 Q+ `* H$ Y7 x
45.1 uCOS-III任务分配
    主要创建了如下6个用户任务:
l AppTaskStart----启动任务
l AppTaskGUIUpdate---界面截图任务
l AppTaskCOM----留待以后升级使用
l AppTaskUserIF---留在以后升级使用
l AppTaskGUI------emWin任务
l AppTaskGUIRefresh---Led闪烁任务
下面主要对启动任务,界面截图任务,emWin任务,Led闪烁任务做一个介绍。

$ g+ c( z( ]- j0 T* M5 V
45.1.1 AppTaskStart—启动任务
    启动任务用于硬件驱动的初始化,系统滴答时钟的初始化以及触摸扫描和按键扫描,代码如下:
  1. /*
    9 J7 t5 O! c  k, F# q% Q
  2. *********************************************************************************************************5 }3 B! W- n4 R7 }2 C. T* q" l2 ^
  3. *        函 数 名: AppTaskStart
    # W, j2 {: b/ P5 ?" V. Y
  4. *        功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器(在BSP_Init中实现)# Q1 @$ {% v+ O* R
  5. *        形    参: p_arg 是在创建该任务时传递的形参  u4 a) ~4 I! F" P! S
  6. *        返 回 值: 无
    / f2 E# c1 K) Y, F' @( Y
  7. 优 先 级: 2& c( p$ K. s' B4 z! z+ u7 j
  8. *********************************************************************************************************$ P" [, U/ H  o8 i
  9. */, O3 m0 S( l1 I6 V7 @
  10. static  void  AppTaskStart (void *p_arg)
    5 d% D2 ^( \7 i0 [3 g3 c
  11. {+ m; ~# k  g+ [1 T  o. x! J
  12. OS_ERR   err;
    , R9 r* G# }: i% k8 `3 G
  13. uint8_t  ucCount = 0;
    " E5 G- Q2 S5 R. F) b
  14. (void)p_arg;
    ) K; o! W2 z+ j' S
  15.          bsp_Init();, K3 f! @) y8 V3 Z# c, [
  16.     CPU_Init();  g  L6 W* s) e' F
  17. BSP_Tick_Init();                        ( }8 A0 h  B9 D7 ~3 |' v

  18. 5 L( d% R1 A& U; S+ |% d
  19. #if OS_CFG_STAT_TASK_EN > 0u
    ( T' F4 W! V( ~3 c1 n2 T' R; a  b' H
  20.      OSStatTaskCPUUsageInit(&err);   ( k& A( d- G' |* e. g3 Q) x
  21. #endif
    / u% H: N: ]4 D0 z2 M3 U5 j

  22. 5 K% {) l0 w+ t2 s2 B
  23. #ifdef CPU_CFG_INT_DIS_MEAS_EN' D  Z; a; g+ K
  24.     CPU_IntDisMeasMaxCurReset();6 y+ C# K. ^0 g8 F9 H% Y$ j% e
  25. #endif
    $ S) q2 ]! D6 U/ i+ F+ e

  26. " `) _0 Q8 I& Y% [# N. ^
  27.     AppObjCreate();                                            * Q4 A0 q8 o4 K6 y) `1 J* p
  28.     AppTaskCreate();                                             @1 y3 A  p7 [7 s
  29.     while (1)
    " ^% O2 i" S- S. P9 a
  30. {                                         - G% e2 P( @3 `. K6 S& [: {2 }
  31. /* 1ms一次触摸扫描 */: I+ y- d6 n$ |4 Z# l& G; F+ ^
  32. TOUCH_Scan();
    * g# h# ]# v# I$ ?8 D
  33. /* 5ms一次按键检测 */- m' J8 j2 ]3 e, F# q
  34. ucCount++;
    8 r5 N/ d' o4 Z/ o( k' ~
  35. if(ucCount == 5)
    , }! H9 s; E6 n; O# Z
  36. {4 D6 |+ n' T; g* x
  37. ucCount = 0;
    ' Y8 f) s% F  c/ ^6 P7 T) U" j( s
  38. bsp_KeyScan();, x/ g, q. ^( w* m! W
  39. }
    9 u0 ]) q. o- z; _' m3 r7 C
  40. BSP_OS_TimeDlyMs(1);
    . H7 X; Y; B* a% C) [/ [+ U8 [( g
  41.     }. p+ J3 U" r% b  e
  42. }
复制代码
6 y6 s2 {8 y& R: S6 w
45.1.2 AppTaskGUIUpdate—界面截图任务
    界面截图任务主要用于界面的截图并将图片以BMP格式保存到SD卡中。
  1. /*) C, B+ S/ c4 X4 t( x! O
  2. *********************************************************************************************************
    3 o- M8 l3 W& o+ }
  3. *        函 数 名: AppTaskGUIUpdate5 \3 K+ V; r8 V3 I
  4. *        功能说明: 此任务主要实现截图功能.
    . S% N$ s/ e% p4 c, E
  5. *        形    参: p_arg 是在创建该任务时传递的形参
    " G! f) [1 J8 }+ E: b3 Z1 O
  6. *        返 回 值: 无
    , w2 a! m9 Y; R
  7. 优 先 级: 3
    6 y6 r8 v; [4 m
  8. *********************************************************************************************************1 e# v# V3 f5 u
  9. */: a$ V$ o1 J, P2 s( k% g- g
  10. static void AppTaskGUIUpdate(void *p_arg)6 P  x3 I" J" q  g4 B6 O' r
  11. {
    # V; d6 X$ z7 E% n( c
  12. OS_ERR      err;
    + ?# x0 C1 v, I
  13. uint8_t         Pic_Name = 0;: h: C# }8 k; m9 N! I
  14. char buf[20];% A2 P' h1 H( E
  15. CPU_BOOLEAN SemFlag;
    # n% i0 f+ T+ N
  16. " e: m, ]) {( M9 z; Q
  17. (void)p_arg;5 x% x/ l+ A: c' e
  18.   5 a* `' j: J, R$ w/ W: O
  19. while(1)/ w  U: N* a5 I
  20. {/ M$ o; r9 Z& L1 _# @, J' N# p
  21. SemFlag = BSP_OS_SemWait(&SEM_SYNCH, 0);' b. j7 g' M9 s% }- l3 _3 f
  22. if(SemFlag == DEF_OK)
    , E) I6 z* _7 R7 ^
  23. {- W* o" V1 h6 _6 i- T% i; q
  24. sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
    6 @) K# N4 ?3 z0 l/ A
  25. OSSchedLock(&err);
    8 I9 w$ V; ?7 u$ f
  26. /* 如果SD卡中没有PicSave文件,会进行创建 */
      E+ i5 B$ v5 G
  27. result = f_mkdir("0:/PicSave");
    5 T, `1 x; t- P
  28. /* 创建截图 */
    # c9 j  t' T: n+ c2 n/ N
  29. result = f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
    7 H' C9 \( m! |6 R# K
  30. /* 向SD卡绘制BMP图片 */3 m" j4 [$ E1 V" x. X; }
  31. GUI_BMP_Serialize(_WriteByte2File, &file);
    " _" w# F2 n3 T$ i$ @0 P; T/ D' \
  32. /* 创建完成后关闭file */" S5 [  F; J. N
  33.     result = f_close(&file);) H7 m) y  X: i: k% D
  34. OSSchedUnlock(&err);
      j0 }( V! i( Q; y1 E
  35. Pic_Name++; 0 G6 F& o3 |8 _7 @8 V) K% U
  36. }                                              % r- `+ m0 p, \
  37. }   
      r1 y5 n% z5 j
  38. }
复制代码
' _2 o# a1 w1 g' s' [% U. T. t2 S
45.1.3 AppTaskGUI—GUI任务
    这个任务是示波器设计中最重要的任务,代码如下:
  1. /*/ C. J6 b8 S4 S/ ^0 `
  2. *********************************************************************************************************6 [0 Y& O3 G' @0 P9 T. [
  3. *        函 数 名: AppTaskGUI& U  t5 [* L$ ?6 |
  4. *        功能说明: GUI任务                      1 u) T) I/ O7 B, `
  5. *        形    参:p_arg 是在创建该任务时传递的形参" L3 s5 \! R1 {! C
  6. *        返 回 值: 无# K4 J3 V" d6 J
  7. *   优 先 级:OS_CFG_PRIO_MAX - 4u) ?/ b0 b2 p' i
  8. ********************************************************************************************************** Q: h" s* w, R2 A4 D
  9. */& j: n6 _9 P/ ?$ ]) m- \0 p
  10. static void AppTaskGUI(void *p_arg)
    % P  \! |7 Z- B4 v
  11. {+ R& y2 e' N  `7 J1 M! m/ t
  12.     (void)p_arg;         /* 避免编译器告警 */
    5 M( K7 H9 E; D% s/ H; U, r* N
  13. while (1) * R! a7 z% I8 W  ]0 b) d/ ~
  14. {% v& [- h& z. t/ U/ Z+ z( U
  15. MainTask();         
    1 N- R! W5 L8 [5 c. e
  16. }+ J# C2 L9 ?( Z; R- h
  17. }
复制代码
& M$ S/ P$ m5 {! J
45.1.4 AppTaskGUIRefresh—Led闪烁任务
    这个任务主要通过LED的闪烁来指示系统的运行,代码如下:
  1. /*
    7 ?& Q( ?9 q3 N! J8 a" z
  2. *********************************************************************************************************/ Y6 N# V6 ^/ w- ]( y* L& ?
  3. *        函 数 名: AppTaskGUIRefresh
    , t, k6 V5 o; H  I7 u4 `* d( A
  4. *        功能说明: Led闪烁任务,表示系统运行                     
    & ?+ i* R! o( |* o2 d' Y4 }0 ^' W
  5. *        形    参: p_arg 是在创建该任务时传递的形参
    ( X; A& T( ~& d( P: Y
  6. *        返 回 值: 无
    . m, A, T1 Z9 b+ q) s+ m3 u
  7. *   优 先 级: OS_CFG_PRIO_MAX - 5u# x9 }: A1 w. h
  8. *********************************************************************************************************
    % }+ M% ^! D/ q$ N# ~, R5 \0 T8 _
  9. */8 A/ T  f$ e/ A
  10. static void AppTaskGUIRefresh(void *p_arg)5 c' G" h5 Y8 u  v( t
  11. {( S9 K' c4 |/ ?5 u* h
  12. (void)p_arg;         /* 避免编译器告警 */# h3 F: \0 `; F8 C
  13.   
    ! ^' h) U/ @; w8 x; r; i
  14. while (1) ! I6 J6 Q" C( J3 k6 B
  15. {
    : w/ f( R( K% }7 I/ e) U
  16.         BSP_OS_TimeDlyMs(200);   |# Y+ }% K$ V+ X9 F
  17. bsp_LedToggle(2);! I% C. b9 l& z: s, m6 r
  18.     }         
    - `- \( K2 q! _- ~- i  o/ h
  19. }
复制代码

+ P0 ?8 y" f( k/ _( g
45.1.5 其余任务
    剩下的两个任务留着以后升级使用。
  1. /*
    / v* `5 h! v/ E, s
  2. *********************************************************************************************************
    7 ]! m4 o+ b8 i
  3. *        函 数 名: AppTaskCom3 S% i/ @3 w: t7 o4 {) J
  4. *        功能说明: 留待以后使用
    ( K8 E& l1 z4 z* m3 W- B% C/ P
  5. *        形    参:p_arg 是在创建该任务时传递的形参
    " C4 k6 {. t9 }3 @& q- C/ R
  6. *        返 回 值: 无
    # B* J3 f& y! h1 D3 V1 `. A8 z  g: X
  7. 优 先 级:3: D( o5 n/ \& X" U" B! Y
  8. *********************************************************************************************************0 e# s4 s7 t2 J1 ^) q- I! g' W
  9. */
    - @( Y6 K5 l/ D
  10. static void AppTaskCOM(void *p_arg)
    % F! p( `- x  U8 S
  11. {
    1 r. `- X  W5 r* u3 l: h6 O1 W8 G
  12.    (void)p_arg;
    0 _5 F) |$ T' v! f7 J
  13. + U0 L6 E5 b- E* Q4 F, p
  14. while(1)1 d* A% a& W* B; N" q
  15. {
    / k( j: X) l1 ~, c) r- j6 a$ o
  16. /* 100s执行一次 */) Z; P  @9 C% ^7 c& n
  17. BSP_OS_TimeDlyMs(1000000);* w% A* s! f2 k3 y
  18. }                                                         ; A1 L6 D7 o& w: M
  19. }
    / M* \  g+ U' d3 P5 Q

  20. ! G4 x: X9 s+ C7 i$ S7 ^2 |
  21. /*' F0 w$ m- l( T! R. h0 I3 g
  22. *********************************************************************************************************; R* o( h; ^; e# \, t
  23. *        函 数 名: AppTaskUserIF3 j0 d0 W3 b: h! ~0 c
  24. *        功能说明: 留待以后使用。" g7 {# H; p( K, R0 S2 b
  25. *        形    参: p_arg 是在创建该任务时传递的形参( g7 V! d- a% {& }" K
  26. *        返 回 值: 无( D- W3 G9 M- _
  27. 优 先 级: 22 i) r, J0 T+ E' B% F. ?( J
  28. *********************************************************************************************************
    - c7 v6 H- X6 _0 J
  29. */5 z6 Y* ?& M3 N" Z4 M8 K
  30. static void AppTaskUserIF(void *p_arg)9 R3 ~4 i2 r2 K
  31. {7 r; q1 Q( J- T, s
  32. (void)p_arg;        /* 避免编译器报警 */3 }  [# W" q; h' B, C
  33. ! ]% W( C/ ?2 C  w
  34. while (1)
    % j# R( x; I3 R( n
  35. {   
    6 A; k! J' U( C7 O' h5 {# ~2 Q; z
  36. /* 100s执行一次 */
    ! K6 B% j8 e" N# k2 x
  37.         BSP_OS_TimeDlyMs(1000000);            
    0 D% I6 [: f2 u! N) H2 z4 c
  38. }+ a' N' Y4 V0 w
  39. }
复制代码
) [! |2 [2 ]6 R& `+ u% W
赞 收藏 评论12 发布时间:2015-5-5 11:45

举报

12个回答
stary666 回答时间:2015-5-5 13:49:22
沙发,支持原创
wu1169668869 回答时间:2015-5-5 23:43:18
学习一下 5.gif
MrJiu 回答时间:2015-5-6 10:08:10
mark一下.....值得学习..........
拼命三郎 回答时间:2015-5-6 10:58:12
ddddd.png
拼命三郎 回答时间:2015-5-6 10:58:35
xxxx.png
拼命三郎 回答时间:2015-5-6 10:59:16
stm (1).jpg
baiyongbin2009 回答时间:2015-5-6 11:26:32
本帖最后由 baiyongbin2009 于 2015-5-6 11:31 编辑
5 B7 [/ G/ }' k, t+ L! a& d0 W1 R5 H  |/ L1 H0 D5 y! F# k% ]
45.2 示波器核心任务
    emWin部分是示波器设计的核心任务,主要包括以下几个文件:
45.1.png
下面把这几个文件及其之间的关系做一个简单的说明。

" O" w) S* v" G
45.2.1 MainTask.c—GUI主任务文件
    这个文件是示波器代码的核心文件,这个文件里面几个函数的关系搞清楚了,示波器的整体设计也就搞清楚了。下面把这个文件里面的几个函数简单的梳理下:
l 函数void MainTask(void)
代码如下:
  1. /*
    ; t" m; q, }1 d8 A" K+ \- t& {. C+ d
  2. *********************************************************************************************************- f1 i( M* W6 x' D; \: H7 U  u
  3. *        函 数 名: MainTask5 N1 ?) N9 u/ N. I' V
  4. *        功能说明: GUI主函数
    % o* T7 J# h0 `; L' V4 ?2 I
  5. *        形    参:无      
    ! h( y8 z% j0 J2 e
  6. *        返 回 值: 无( c# m, O" e% h
  7. *********************************************************************************************************
    1 ^: u& y+ O- c5 {: l
  8. */; V- ?" J( A* f" Z& w9 N3 f
  9. void MainTask(void)
      m, `! i8 \6 J2 _! H8 h% y* n. h3 k5 s
  10. {
      N8 w0 ~$ Z+ Y1 s% U, |1 K9 s5 b
  11. /* 开启所有窗口使用内存设备 */. |$ O$ D2 e( B$ ?2 Y+ v+ y7 m
  12. WM_SetCreateFlags(WM_CF_MEMDEV);% B. q  V# q$ G% U
  13. GUI_Init();
    . J8 c0 D: X1 w9 E* T4 o3 Y) @  @/ I
  14. /* 设置皮肤色 *************************************************************/
    8 V; A! C' v# B% I) j
  15. PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);8 B0 }+ {" a# E% k0 R
  16. FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);* Y) Z! b% i5 R0 T( s  }, l
  17. PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);1 i4 T. X* |- L
  18. BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);5 C3 `, k% A$ |7 B# t" m
  19. CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
    2 K2 u, q# N9 O' ~# ~4 v* U- S  l
  20. DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);, ^2 P! _, b+ q7 V4 Y9 U% b2 H$ o0 P
  21. SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
    6 H3 n, ~2 b1 _  S, a$ D
  22. SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);$ r4 k0 _3 }  x: u, s6 j
  23. HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
    6 g/ M+ J- l3 a/ U- a& B5 |
  24. RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
    % g) ~3 p" j* c4 n6 X- O8 Y, h, h
  25. MULTIPAGE_SetDefaultSkin(MULTIPAGE_SKIN_FLEX);
    : k; L7 y& L$ a
  26. /*
    9 Q/ L, t3 [1 [7 c4 \$ i
  27. * 设置桌面窗口的回调函数5 R+ q- N' M7 ?4 G+ z& H/ v
  28. */& U1 C+ }( c4 y, m' [* @$ {, c; d
  29. WM_SetCallback(WM_HBKWIN, _cbBkWin);5 X, |+ R! l! W! q
  30. /* 初始化 DSO */# ?; @0 F( t# a: n! p
  31. DSO_Init(1);# K- @' f8 [' K4 }- |$ X2 ~+ g
  32. /* 波形显示和处理 */7 M  Y- X% v% v& I$ L* V2 {) ]/ `
  33. DSO_Graph();         
    3 P% m5 k& I/ m. {+ }
  34. }
复制代码
这个函数里面最主要的就是DSO_Init(1)函数和DSO_Graph()两个函数。
l 函数DSO_Graph
    这个函数是示波器的主函数,示波器任何函数都是通过这个函数直接或者间接的进行调用。这个函数
主要有两个功能,一个是ADC数据的处理并在TFT上显示出来,另一个是按键消息的处理,详细大家看代码即可,代码注释已经比较详细。
l 函数 _Draw
    这个函数通过函数GUI_MEMDEV_Draw进行调用的,主要是实现绘制波形和波形区的虚线方框。
l 函数 _cbBkWin
    桌面窗口的回调函数,主要是用于示波器界面右侧8个按钮的回调消息处理,用来打开8个按钮所对应的的对话框。

9 l% f$ Q( G0 O- C3 K6 q1 O
45.2.2 MainTask.h—所有DSO相关文件的头文件
    这个文件是所以DSO相关文件的头文件,方便各个文件进行调用,代码如下:
  1. /*
    ' s$ S/ q: o5 ?% P! K
  2. *********************************************************************************************************
    ) ?: [& J: N% J3 @
  3. *                                          . k- A7 m3 z( [+ W' _) }* Q
  4. *        模块名称 : GUI各个部分的总头文件. G- w* q( x3 V) a/ W: U
  5. *        文件名称 : MainTask.c8 k) F8 X( C! [- V# _
  6. *        版    本 : V1.03 r# m' r1 w% J
  7. *        说    明 : GUI界面主函数
    3 O: C# P* f2 Z3 F  F' f5 w8 Z
  8. *        修改记录 :
    : f2 j& ^8 o# R2 E: w" {- }4 N
  9. *         版本号    日期          作者        说明% _& i- v' Q3 }2 q) y
  10. *         v1.0    2015-01-05    Eric2013      首发
    4 O1 D; V  b! ]+ X9 C! l! b4 W
  11. *
    : _" U: \) R7 \) K) U) ?9 i9 z5 [; A
  12. *        Copyright (C), 2015-2016, 安富莱电子 www.armfly.com& A. @" E; N) N) _( X
  13. *
    " Y. X, T2 [9 x& w
  14. *********************************************************************************************************2 s' s6 t8 ^* k8 f$ M& m+ T9 P
  15. */( @5 v( k4 r7 X$ @5 S+ C& V

  16. 7 {- _# ~, C. [3 I/ D7 t4 U
  17. #ifndef __MainTask_H
    " }2 C, M5 n- U" P: c0 l
  18. #define __MainTask_H' d+ P$ T. B( `0 k9 r

  19. $ f3 H4 l, |, e6 m
  20. #include "stdlib.h"
    , X  N5 @  Z; e  P/ {& p
  21. #include "GUI.h"
    " j3 x/ y, B0 b$ A2 a5 {
  22. #include "DIALOG.h"2 t. d* s. B  j7 O+ I& w- D; Q# M
  23. #include "WM.h"" Q& Q; u! F) B4 f$ |% u% Z6 H
  24. #include "BUTTON.h"! K. K' T0 `% Z& o6 P: [' r
  25. #include "CHECKBOX.h"
    ! }: X/ v+ S! A# I# `! ]# i) a* A1 d& i
  26. #include "DROPDOWN.h"
    7 l7 t$ u" {2 o( |6 j
  27. #include "EDIT.h"; @/ b9 c: [6 i  s
  28. #include "FRAMEWIN.h"7 C6 a+ J* N- J: J
  29. #include "LISTBOX.h"
    8 J; F9 |9 ?% F/ D
  30. #include "MULTIEDIT.h"
    6 T5 X5 Y2 A) M* J0 T- T; y- Q) G
  31. #include "RADIO.h"1 B6 J  v' u9 _4 n2 J# z5 W
  32. #include "SLIDER.h"7 g% x0 W( w) @
  33. #include "TEXT.h"
    % [. H5 y# C: m) h. I
  34. #include "PROGBAR.h"
    " I& v( r* V/ R5 b1 D1 K: x
  35. #include "SCROLLBAR.h"
    ) @9 e8 }  u9 S4 q  t( |
  36. #include "LISTVIEW.h"
      J5 m' ?5 d/ n* r4 d% F
  37. #include "GRAPH.h"
    1 s. c# Z7 D; c4 T$ O) F
  38. #include "MENU.h"# x" k4 s" v/ W0 m& b: ]2 X
  39. #include "MULTIPAGE.h"; ~, H3 X) e# @
  40. #include "ICONVIEW.h", V7 I& r) A; |: e) X
  41. #include "TREEVIEW.h"$ v; A. a# o/ e9 r
  42. #include "MESSAGEBOX.h"
    2 e+ q% L& d) f' T; l3 `

  43. 3 s0 j" X, q) {5 y
  44. #include "ff.h"
    : {* z: N/ |& }) J6 H" K) _/ B
  45. #include "diskio.h"
    % {2 @) a3 K; l3 X: R; t  Z% c, ^
  46. + i8 q0 k- V8 T, n$ [1 S& L
  47. #include "arm_math.h"0 M" J/ e" j$ `3 x; L5 z
  48. #include "arm_const_structs.h"
    " a2 S$ G/ Y6 O' X2 b5 T/ F3 z
  49. / W3 n" U  |( p) q. {% x5 d  s% S
  50. /*! ?: i& G7 j0 M: U0 t& N1 E
  51. *********************************************************************************************************
    . W! h  F7 ^0 p2 }% Z2 d$ J
  52. *                                          宏定义0 _- I7 h, ]0 b2 }2 _; s
  53. *********************************************************************************************************
      m/ {9 a0 O4 z2 u1 q+ F
  54. */            
    + {3 I: A* E3 k5 @. W$ I& n
  55. #define LCD_YSIZE 480" d8 ]# [; @- h( l! `& u" W
  56. #define LCD_XSIZE 630
      R8 N# z1 y& G3 N2 i! _
  57. 4 }/ [2 F2 ~- F% c+ G! p
  58. /* 定义波形的显示界面区域 600*400 */
    ; }, C, ?4 ?8 w
  59. #define DSOSCREEN_STARTX     40     /* 波形显示的X起始位置 */( x4 G9 [" ^% r" P. c
  60. #define DSOSCREEN_STARTY     40            /* 波形显示的Y起始位置 */
    + R! K0 ~8 k* `, a% l6 I( W# n
  61. #define DSOSCREEN_ENDX      639     /* 波形显示的X结束位置 */
    , Q" d" u$ m0 S$ k. m! H" Z6 A
  62. #define DSOSCREEN_ENDY      439     /* 波形显示的Y结束位置 */. h: W0 H, k& f2 o3 ?& c4 _; n
  63. #define DSOSCREEN_LENGTH    600     /* 波形显示的Y结束位置 */( S9 v" _" h+ [7 o

  64. % m1 L  ^% a2 u+ a- x7 c' y1 C2 z
  65. #define ATT_COUNT                10      /* 定义支持的10种幅值单位 */  
    3 G2 p. _' `2 l2 M
  66. 3 J2 I. Q- [) ]2 j; @/ V0 q5 x
  67. #define TIME_COUNT                21      /* 定义支持的21种采样率 */
    7 `2 q1 G) S! l, O4 Y
  68. - K! e! e7 m4 [0 U
  69. #define WM_TextUpDate  WM_USER + 1  /* 自定义一个回调函数的消息,用于界面数据的更新 */) M9 ~7 {6 ?$ X& ?; D# H4 E
  70. & \) m; s' V: m- t0 J# t
  71. /*
    6 {3 _  \; L, c9 Z& ~0 m0 r7 F& K
  72. *********************************************************************************************************7 i4 }5 y, x. N( p# ?: l/ _
  73. *                                          变量
    1 g, T5 G1 W0 c/ Z1 w1 f( o, ]+ w9 ^
  74. *********************************************************************************************************4 T4 k- {- H: x5 O8 |$ b/ Q
  75. */
    0 {3 V9 R3 F, i4 C. @% [# m9 `1 j
  76. extern const char *g_AttText[];                  /* 10种幅度单位 */9 P" x' z) R( V; B, W
  77. extern const char *g_TimeTable[];                /* 采样率,从2Msps到1Ksps 对应的时基 */: @6 q0 T0 J  M5 Y
  78. extern const char *g_MeasureTable[];             /* 示波器当前实际支持的测量值 */3 O$ R9 Y  S# P# K5 s
  79. extern const uint16_t g_CursorUintTable[][2];    /* 测量游标数据显示格式 */
    0 H) F8 G) A5 v  A
  80. extern const uint16_t g_AttTable[ATT_COUNT][2];  /* 采样率衰减倍数表 */
    ; \, g+ K0 n6 m9 Y4 F: I

  81. 4 [$ c7 H: w2 `9 M
  82. extern GUI_RECT rClient;       /* 用于显示示波器的logo */
    4 Z5 i' E1 i: Z, I7 h
  83. extern GUI_RECT rRunMode;      /* 用于显示运行状态,运行和暂停 */- Y# ~- U0 x8 R: n) T7 `3 p- `
  84. extern GUI_RECT rTrigMode;     /* 用于显示触发模式,自动触发和正常触发 */
    1 P9 d% k; y& `. E- ?
  85. extern GUI_RECT rTrigValue;    /* 用于显示自动和正常的触发数组 */
      o5 ?+ C8 C; V9 D% m
  86. extern GUI_RECT rButState;     /* 当前按键需要调节的状态 */
    ( F$ N1 Q, d& D4 `
  87. extern GUI_RECT rRefPos;       /* 示波器最左侧波形参考的位置区域 */
    1 Y  x/ y0 S9 k* @3 r. B
  88. extern GUI_RECT rTrigPos;      /* 6KB数据查询  */4 y* p4 s0 n4 z7 W9 J! |' T' d

  89. 0 k% f* ~. M3 M) U3 W) o6 a
  90. extern const GUI_POINT aPointsTrigBrowser[3];  /* 6k数据中,波形显示的起始位置 */
    7 V- k# P1 H! |! D# b, e
  91. extern const GUI_POINT aPointsTrig[7];         /* 波形显示区右侧边上触发值箭头 */
    0 @# }2 G7 }9 T4 t  X% [) N' q' ?
  92. extern const GUI_POINT aPoints[5];             /* 波形显示区左侧边上波形显示的参考位置 */
    " X) {2 ^3 g& U' C7 ^0 L( k
  93. , X7 }" ~+ E- g1 T5 x: B' U9 C, Y
  94. extern uint8_t  g_ucLineStyle;  /* 默认是实线绘制波形 */
    - `% _9 J9 H) D) f% L
  95. extern int8_t  Ch1AmpId;        /* 从g_AttText中选择每个方格表示的幅值 */            - T7 ]) Y- E+ k/ _0 K$ j
  96. extern int8_t  TimeBaseId;      /* 选择相应采样率 */7 `% M* Y' {% A

  97. ; d1 d+ m( J# U- t5 m6 D
  98. extern uint8_t g_ucMeasureFlag[30];  /* 示波器支持的30种测量值标志 */
    9 f' t  c0 B) V8 B

  99. & B  f5 X2 Z3 b
  100. /* 存储平均值,峰峰值,频率,最小值和最大值的变量 */- a! m9 w  N- m# ]
  101. extern float32_t   g_WaveMean;
    4 s5 Z/ s5 X+ k* |; g* J
  102. extern float32_t   g_WavePkPk;
    3 }! ?7 p3 b7 F% [/ W. o
  103. extern float32_t   g_WaveFreq;, ?- g* p: ~$ d7 s7 [$ ~$ |4 Y
  104. extern float32_t   g_WaveMax;
    + z% J9 k. K1 e
  105. extern float32_t   g_WaveMin;
    - R6 |% H( I; {

  106. & G. @0 F2 }! h. }" x8 ]9 v
  107. /* 用于水平测量和垂直测量游标,下面是初始化的默认值 */
    ) \8 V% `4 A. ]! W0 S! o
  108. extern uint16_t g_usCursorStep;2 f% X+ c1 L, s. _& Q) L
  109. extern int16_t  g_sCursorHA;% ?8 K9 Y# U/ U
  110. extern int16_t  g_sCursorHB;5 t5 b. o  V8 U4 }; v* q
  111. extern int16_t  g_sCursorVA;
    # t' |) K+ z& B) [! I& ~; J, h
  112. extern int16_t  g_sCursorVB;
    & Q3 c8 e* c8 k/ \
  113. extern float32_t  g_WaveCursorA;
    ) Q# V" S$ P/ `+ A7 w6 _" i
  114. extern float32_t  g_WaveCursorB;: a$ ~! y, a' r) y( @
  115. 0 [/ |2 q2 C) Q, W! s; D( ?2 u
  116. extern uint8_t hWinRunStopFlag;  /* 0:表示运行,1:表示暂停 */
    ) K! ^8 Y: k  X! L& u4 C

  117. / Q7 Y& j+ s$ J$ ]
  118. extern uint16_t TriggerFlag;     /* 0:用于自动触发,1,2:用于普通触发 */3 W$ E, e9 E) C4 d; F! p* i4 T

  119. 6 w/ h5 v' ~  P2 a
  120. /* 用于水平测量和垂直测量游标 */5 s+ n6 U$ a7 }' M4 x
  121. extern uint16_t  g_usTriPos;    1 A* ]: t. [# W9 I8 |
  122. extern uint16_t  g_usTriStep;
    * ^  K: j. Q5 Q! ^5 y+ W
  123. extern int16_t   g_usCurTriPos;
    8 }# y7 k; l" T, R& R+ n2 @# [
  124. extern int16_t   g_usCurTriStep;4 Y  l7 F9 o* ]5 {+ @3 s
  125. extern float32_t g_ufTrigValue;
    # `( `  |1 _" X
  126. extern uint16_t  g_usTrigValue;  + a% d; z3 z' h9 e8 u0 v/ o
  127. extern uint32_t  g_ulTrigTimeLine;
    ' y2 G' t# n3 o' t0 P7 Q7 n. [
  128. 3 }$ N9 t4 V4 p( z7 S0 v. k* N
  129. $ j3 n# w& l3 g: \
  130. extern uint16_t  g_usRefPos;          /* 左侧的参考位置,默认开机后是中间位置 */
    - A7 P8 o0 [- w  n# w
  131. extern uint8_t hWinButStateFlag;      /* 8种按键功能状态 */
    8 v- r) M3 a5 E9 A0 x
  132. extern uint16_t g_usWaveBuf[1024*6];  /* 示波器缓存 */
    , D' o9 g) [8 g
  133. extern uint16_t g_usWaveBuf1[1024*6];* @9 Q, M3 g6 |! u! f, Y9 M0 h

  134. & d1 C7 S: b* W7 r, n/ j9 |2 S; @# Y+ {
  135. extern uint8_t hWinCoursorFlag;     /* 0:不显示测量窗口,1:显示测量窗口 */, `$ H. U8 G- B# A9 M, K; [, @' P' s
  136. extern uint8_t  g_ucFFTDispFlag;    /* FFT波形显示,0:表示显示,1:表示不显示 */0 p- L2 W* e1 j
  137. extern uint8_t  g_ucFirFlter_Step100KHz;   /* 0:表示不执行滤波,1:表示100KHz,2:表示200KHz,,以此类推 */
    & v4 K  }) \! b2 o. `9 G
  138. extern uint8_t  g_ucFirFlter_Step10KHz;    /* 0:表示不执行滤波,1:表示10KHz, 2:表示20KHz,,以此类推 */' G  X+ A; g; v' G4 l
  139. extern uint8_t  g_ucFirFlter_Step1KHz;     /* 0:表示不执行滤波,1:表示1KHz,  2:表示2KHz,,以此类推 */* O4 P/ `6 L! e- H1 H) n" G
  140. extern uint8_t  g_ucWaveRefreshFlag;       /* 0:表示不执行波形区域的刷新,1:表示执行波形区域的刷新 */. p4 N$ e+ O, S8 n8 w9 J; \
  141. /*/ |% q/ _" x; ~5 P' z% C
  142. *********************************************************************************************************% ?/ }7 M8 ?# Q/ U/ x
  143. *                                          fatfs
    / t  S. U6 ]) Y4 O5 r% w" r
  144. *********************************************************************************************************
    0 r; z+ G1 M9 f
  145. */! W+ n" x3 t& C0 z* ~" K- B* H! S
  146. /* 供外部文件调用的fatfs变量 */' c! n& j; W$ d" t; v+ t
  147. extern FRESULT result;
    + e1 \2 z9 E" S# [0 h8 W* X8 q$ B  ]
  148. extern FIL file;
    # o, b! C6 n6 l
  149. extern FILINFO finfo;9 {: \, d7 h) F; }, \; p6 A
  150. extern DIR DirInf;; E8 C  R! T7 J, U
  151. extern UINT bw;9 ]# }( G! Z: J2 }7 }5 }
  152. extern FATFS fs;
    & I. q- a- v( h& ^
  153. extern FATFS fs_nand;+ \) E4 R& F& @5 w
  154. extern FATFS fs_usb;
    ) L! p& h) o# I
  155. extern char *_acBuffer2;% K- f8 L& k  ~3 W

  156. 2 h& A9 w& w7 S
  157. /* BMP图片生成 */" Q! B3 ]4 m) J2 v' H5 o$ f: @
  158. extern void _WriteByte2File(U8 Data, void * p);
    & \: G% v6 ?  v) ~

  159. $ p  i. v+ F/ C& z% D
  160. /* 用于BMP图片的显示 */
    # ?' b- c, q$ D% U
  161. uint8_t  _ShowBMP(const char * sFilename); + k& K1 Q! ]. I' ]5 R
  162. , E5 K' q; t7 h, h' @: n1 c
  163. /*
    5 L/ |* G: v3 U5 D( z' J
  164. *********************************************************************************************************
    + D8 L+ t# I0 h: K7 [+ y+ k" Y
  165. *                                          窗口句柄* @. F) k2 }) d% o
  166. *********************************************************************************************************$ s4 `7 ~. `$ o3 }$ P. R
  167. */$ _7 \, \$ H4 W
  168. extern WM_HWIN hWinAmp;         /* 用于显示幅度的窗口 */( j, U. p) r5 E. Y% B
  169. extern WM_HWIN hWinStatus;      /* 用于显示频率,平均值,峰峰值,最大值等信息 */2 x: [, ?- O7 @1 s
  170. extern WM_HWIN hWinScale;       /* 用于显示采样率 */
    ' H' ?2 N( f6 E1 v  C

  171. 7 R' e; f4 G* }& A, F
  172. /* 8个按钮句柄 */6 z+ x1 W/ o" g( N  N$ T: d$ S
  173. extern BUTTON_Handle hButton0;
    - a+ j1 ^( |2 I8 N( \
  174. extern BUTTON_Handle hButton1;1 w! R; {  @* O+ C" E0 s+ P
  175. extern BUTTON_Handle hButton2;, w+ |) I8 n, N% c3 C
  176. extern BUTTON_Handle hButton3;
    7 ~! m: y3 S4 M0 t3 F+ H
  177. extern BUTTON_Handle hButton4;; B4 a+ H% h- C0 E
  178. extern BUTTON_Handle hButton5;! m/ W) ~) l4 W2 L, g( t( \
  179. extern BUTTON_Handle hButton6;
    # P% N6 I! q. @, S
  180. extern BUTTON_Handle hButton7;  H" x% d1 C) [, D$ D/ Y

  181. 1 j; Q2 ?% G) i! l. @3 u7 A* B
  182. /*
    9 U3 B3 e( _) V2 L8 ~9 U
  183. *********************************************************************************************************
    1 j4 C5 A/ B3 V/ [/ \
  184. *                                          供外部文件调用的函数: D; [4 e& Q9 V- @# d* x
  185. *********************************************************************************************************
    $ {4 ?- q0 ~' u: ^. ?( N9 w$ q
  186. */% s# h7 |8 a, T4 t& B
  187. /* 创建幅度,时基和状态窗口 */
    3 A5 f9 q5 U3 T9 @6 H: ^* }) `2 ^
  188. extern WM_HWIN CreateWindowAmplitude(void);
    0 K: U, |% t; v' C
  189. extern WM_HWIN CreateWindowScale(void);
      N$ |7 Y: {/ j7 N0 X% }
  190. extern WM_HWIN CreateWindowStatus(void);& k0 L) p+ g" H/ Y  P) B) {6 z

  191. " |8 N8 o! K& ?8 J. a+ q: u
  192. /* 示波器界面初始化 */
    1 Z" \7 N( h8 M* G5 B# _
  193. extern void DSO_Init(uint8_t ucCreateFlag);* Z. t8 l$ ], K4 u$ S: C2 E6 x* `
  194. % Z! @0 h# D7 t$ k1 D* m
  195. /* 按钮创建的对话框 */( p: m# C( ^2 x
  196. extern WM_HWIN DSO_CreateMeasureDlg(void);' e( d! i& ^2 u" B( Z
  197. extern WM_HWIN DSO_CreateInspectorDlg(void);0 Y5 \1 w6 i* D( a: L# k( M8 ^
  198. extern WM_HWIN DSO_CreateAcquireDlg(void);8 q7 w$ w* x. e, C; {4 ?$ t/ T  P) R
  199. extern WM_HWIN DSO_CreateTrigerDlg(void);% ]3 t9 P+ l. Y# `1 W+ e  U0 e: h
  200. extern WM_HWIN DSO_CreateMathDlg(void);) O3 V! w0 ?0 o5 ]
  201. extern WM_HWIN DSO_CreateSettingsDlg(void);8 G5 E) ^! R1 d+ F0 j
  202. extern WM_HWIN DSO_CreateDacDlg(void);3 f# g6 b3 o; A" K- @
  203. extern WM_HWIN DSO_CreateReturnDlg(void);
    & h0 h- Y6 Z' @0 Y2 Z+ m5 T: e
  204. 1 \7 {# U% c7 M1 E+ o4 b- B' w; c
  205. /* 示波器界面绘制 */
    9 k0 P" N- V7 L2 a8 n: h" K
  206. extern void DSO_DrawBakFrame(void);
    ! y' g& R' @5 F& b; K" f
  207. extern void DSO_DrawCursorH(void);0 B1 |' U  g9 j* p" {
  208. extern void DSO_DrawCursorV(void);) q+ a8 w7 B  @1 Y9 [. `2 w3 M% \' L% t

  209. 9 U( F0 Q8 Y5 Q, U1 x+ {
  210. /* Fir 滤波 */
    : t. w2 d* d# i
  211. extern void DSO_FirFilter_Step100KHz(void);7 A3 M+ m8 }  g9 [- m; D" [3 l
  212. extern void DSO_FirFilter_Step10KHz(void);
    . ?. b: p( a: Q7 w; z
  213. extern void DSO_FirFilter_Step1KHz(void);! S2 z6 Z8 ?' `: d+ _: ^
  214. #endif) D$ i3 q# C( f3 V

  215. / U2 V. o3 f  B9 |
  216. /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
复制代码

/ U6 e4 M. O( e( V
45.2.3 App_SysFunction.c—界面截图
这个文件主要是示波器界面截图。实现截图的主要函数如下:
  1. /*3 @. K& n/ I; {5 \% [+ _
  2. *********************************************************************************************************
    ' B( s4 Y9 Y6 G5 @; u" ~2 T
  3. *        函 数 名: _WriteByte2File(); p: b! f1 l2 G: x' s' L5 y
  4. *        功能说明: 写文件到SD卡或者其他存储介质
    # V3 s  u1 M* e; ?) y
  5. *        形    参:Data 要写的数据, p 指向FIL类型变量      # G4 @0 N8 H" {& C: l
  6. *        返 回 值: 无
    + d# V8 M# d, B. M! m& [6 e
  7. *********************************************************************************************************
    & M& N, X/ O- S7 j0 l) e: y
  8. */
    8 p/ Y. m, a$ N! K4 `
  9. void _WriteByte2File(U8 Data, void * p)
    $ U) Y; O4 ^1 L
  10. {/ S0 U# v) E; l+ i4 v# M. Y; l, i
  11. result = f_write (p, &Data, 1, &bw);
    0 d% ]. Z$ |) x+ i( A, j
  12. }
复制代码
这个函数是被emWin函数GUI_BMP_Serialize所调用。
' ]: Q- a4 ]! J; i. B
4 P; b! c: B  v  m# |' K' l! P
baiyongbin2009 回答时间:2015-5-6 11:27:31
45.2.4 DSO_Init.c—初始化
    这个文件里面的函数DSO_Init()主要是实现示波器整个界面的初始化,初始化内容如下:
  1. /*" L, U" A# [* l& a9 G! t2 G% T; _7 m
  2. *********************************************************************************************************, {* B6 _  K$ t% u( U4 Q* t% E
  3. *        函 数 名: DSO_Init
    % _/ V2 K0 L8 w5 P
  4. *        功能说明: 示波器主界面初始化8 l( e3 O8 [" [1 ?2 i* j2 C) ]
  5. *        形 参:ucCreateFlag 1:表示需要创建按键和窗口等。& U* Z- U5 S; l; ?  k
  6. * 0:不需要创建。
    7 p4 _6 \. ~4 ^
  7. *        返 回 值: 无
    9 T2 j/ o- F7 U4 z
  8. *********************************************************************************************************
    - ^# s+ G2 Y4 ~, Z# w6 B4 L
  9. */
    " Z9 u, d6 y, @! Z4 m; N& N$ j
  10. void DSO_Init(uint8_t ucCreateFlag)
    & ^& T7 M) r* ]; H, _
  11. {! t; o6 y, X( @. Y6 l& }, V
  12. char buf[10];
    2 o" u4 Z; R1 l0 z8 k( Y( }
  13. uint32_t ulTrigPos;
    8 A7 e! K( \  _. J5 T
  14. /* 第1步:刷新背景*********************************************************************/3 L( M& I0 E0 d9 w8 {1 K1 W% X3 ^
  15. GUI_SetBkColor(0x905040);
    ' A- w8 H7 M2 _$ I2 I( O8 a
  16. GUI_Clear();# n6 }% L+ N6 V) s
  17. /* 第2步:显示基本的信息***************************************************************/
    1 w9 ^0 \: h1 o/ b
  18. GUI_SetColor(GUI_WHITE);
    # Y, R' I( @  e0 s4 l
  19. GUI_SetFont(&GUI_Font8x16x1x2);$ Z$ H+ j$ j. J) D2 c$ X9 D
  20. GUI_DispStringInRect("Eric2013", &rClient, GUI_TA_HCENTER | GUI_TA_VCENTER);
    ) D$ M! M. W0 Y1 q2 V
  21. /* 按键K2 :设置波形显示运行或暂停 */
    + f  ]' W, U# J0 W+ r6 S( Z
  22. if(hWinRunStopFlag == 0)
    9 a' d3 H4 j/ R
  23. {* {3 K; W) D( e) K2 i, S1 Q' Q+ G( J
  24. GUI_DispStringInRect("Run", &rRunMode, GUI_TA_HCENTER | GUI_TA_VCENTER);; X' R% d) U& J' m8 s
  25. }/ `% |3 Q- Q9 C- x  ^
  26. else
    6 N: Q) o- x2 W) i
  27. {
      ]4 N% e( ~/ `! `3 A) N- `
  28. GUI_DispStringInRect("Stop", &rRunMode, GUI_TA_HCENTER | GUI_TA_VCENTER);9 v. \4 u0 k. @- _0 v2 z. C
  29. }* @9 B( A) C0 o  ?
  30. /* 按键K3 :设置普通触发方式或自动触发 */
    & b& D' I  C' ~; M2 x( |. g) d% k4 i
  31. if(TriggerFlag == 0)" Y, T: C2 n* L  M
  32. {* y2 G7 |9 C% E# u) {8 Z7 T
  33. GUI_DispStringInRect("Auto", &rTrigMode, GUI_TA_HCENTER | GUI_TA_VCENTER);/ @1 y5 l+ H8 p! m0 G$ q" H
  34. }8 E# t2 L' ~9 ?' q( n. r
  35. else
    * a* ~/ W' d% h; t# s" O
  36. {3 y* n0 I- I8 v
  37. GUI_DispStringInRect("Trig", &rTrigMode, GUI_TA_HCENTER | GUI_TA_VCENTER);! X$ n- `" F( V' V1 _
  38. }: X) ^9 g* b$ X* n. ~9 B9 B/ V
  39. /* 第3步:显示自动触发的触发电压**********************************************************/
    $ q* s6 W- t+ z% Q$ F6 t
  40. g_ufTrigValue = 240 - g_usTriPos;; o8 Z6 J$ ^3 `6 q0 [& O
  41. g_ufTrigValue = g_ufTrigValue * g_AttTable[Ch1AmpId][1] / 50000;
    ! ?/ D3 a" b$ @% _
  42. sprintf(buf, "%5.3fV", g_ufTrigValue);
    1 w8 y, c6 G0 ]0 P
  43. GUI_DispStringInRect(buf, &rTrigValue, GUI_TA_HCENTER | GUI_TA_VCENTER);
    4 u& f& F- c, e( I
  44. /* 显示上升沿触发的标志 */" @; \9 j: I3 N' Q# t) K; n
  45. GUI_DrawHLine(rTrigValue.y1-10, rTrigValue.x0+10, rTrigValue.x0 + 19);. u& s9 e* @' h0 b  @, F
  46. GUI_DrawLine(rTrigValue.x0 + 19, rTrigValue.y1-10, rTrigValue.x0+30, rTrigValue.y0+8);5 w8 P+ l! q- t& k& A; r+ n
  47. GUI_DrawHLine(rTrigValue.y0+8, rTrigValue.x0+31, rTrigValue.x0 + 41);
    * z4 ]: h( R1 x0 S/ |
  48. /* 第4步:设置摇杆按键的调节状态,并将其显示出来******************************************/
    , ~# c- }1 s4 C0 f
  49. if(hWinButStateFlag == 0)
    6 Y( h! Q$ |1 O
  50. {) V2 |7 J  v- `
  51. GUI_DispStringInRect("ChangeSampleFreq", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);, G- k% n' L4 U$ g6 U  ^' g, n; G
  52. }2 b; o8 ^1 c* s* {0 Q/ n( i
  53. else if(hWinButStateFlag == 1)
    " t) b1 p: s" h9 F- N5 h
  54. {, U6 }. Y) P# }: p6 y
  55. GUI_DispStringInRect("ChangeAmplitude", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);/ `9 ~/ w* Z3 Y- i& S  a
  56. }" f  O$ ^0 u9 B. u! _6 J/ P
  57. else if(hWinButStateFlag == 2)) q7 d3 Z+ }1 w  r2 Y" }
  58. {
    & I: Y4 I1 Q  Q. w
  59. GUI_DispStringInRect("ChangeRefPos", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);
    4 P8 m, ~) F! t* [; z+ U6 [7 [$ l
  60. }) G8 }  o& }( j
  61. else if(hWinButStateFlag == 3)- A4 S5 U/ R5 c- U! `& b
  62. {
    " j+ I& Z! J! i- \5 d
  63. GUI_DispStringInRect("ChangeCursorVA", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);9 ^" J; s& ^, x. w5 s
  64. }7 ^" E9 Q3 F# {( ^* B. K6 o& K
  65. else if(hWinButStateFlag == 4)
    9 e% m  p9 i! w- I3 i, V, f
  66. {
    % Z* P. w$ Z$ F1 ?, P! M
  67. GUI_DispStringInRect("ChangeCursorVB", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);
    * @% }( Z0 e/ ]" x
  68. }
    / `* r6 h+ h. D2 d* ^2 i9 ]
  69. else if(hWinButStateFlag == 5)! }! R, G% u7 X' Y5 ^
  70. {
    3 ~" k! L. `$ V+ c/ \( R* P5 t
  71. GUI_DispStringInRect("ChangeCursorHA", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);
      O. @+ [) `; g4 v" n8 f
  72. }7 O( s# a4 ?* d3 `2 T
  73. else if(hWinButStateFlag == 6)
    : C9 ]( w; L8 T" k2 I5 L( b
  74. {/ q& x1 T4 ~8 k5 k
  75. GUI_DispStringInRect("ChangeCursorHB", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);
    ! t0 `9 i7 p8 ~& g" m% X3 H. i
  76. }9 X7 B) {/ h2 x# g: p1 I" T
  77. else if(hWinButStateFlag == 7)$ V* m" @2 k) ]0 T  h2 F- l  m/ s
  78. {7 v4 I* L* Z( q+ S) a8 \
  79. GUI_DispStringInRect("ChangeTrigger", &rButState, GUI_TA_HCENTER | GUI_TA_VCENTER);
    , f. T, _0 T2 Q- s+ G- ?
  80. }
    / R7 q, }0 u$ H: U: Q3 j
  81. /* 第5步:实现波形的放缩***************************************************************/
    1 j* p$ v& @% i& v
  82. GUI_SetBkColor(GUI_BLACK);+ O9 Y5 ^. f& U% W2 j4 Z. S
  83. GUI_ClearRect(210, 6, 470, 33);
    * f' f6 ]" y, e& y/ l! t6 l
  84. GUI_SetColor(GUI_YELLOW);
    3 d$ c; @5 d4 |. g( {
  85. GUI_DrawHLine(20,220, 220+239);
    3 f* O# ~  ^9 o9 o9 I
  86. GUI_DrawHLine(21,220, 220+239);
    # t. S; k3 X+ P0 `& e
  87. GUI_SetColor(0x0040f0);1 R; A  t' j1 M. ]" a
  88. /* 自动触发模式 */" E( V2 K: N- p& ?
  89. if(TriggerFlag == 0)4 i  ?3 H: O6 j  u4 h
  90. {
    3 k& v1 [( m/ k3 x
  91. ulTrigPos = (g_usCurTriStep + g_usCurTriPos) * 240;
    9 u" m. g: n+ J$ v' E
  92. }
    $ b# e% E$ P& e& I1 S2 H* v
  93. /* 普通触发模式 */- [6 c' n$ w" q7 Z, I
  94. else) g7 i- O5 i' t# D/ Q+ A
  95. {
    % g9 a8 o4 N6 y6 {
  96. ulTrigPos = (2772 + g_usCurTriStep)*240;0 _& [" C6 d* b& N7 k. q1 g* |
  97. }( m' @" Z6 O! W) t' A
  98. /* 根据上面求得数据的触发位置来更新屏上的触发图标位置 */
    5 ~- Z, ^+ A1 P1 [
  99. ulTrigPos = ulTrigPos / 6144;; N" O( \, `0 n' u
  100. GUI_FillPolygon(&aPointsTrigBrowser[0], GUI_COUNTOF(aPointsTrigBrowser), ulTrigPos+220, 13);2 h- ]4 w( v7 d3 k9 ^% R  P' v
  101. /* 记录专门的触发位置 */6 L- ^4 L. g  ^# b% T
  102. GUI_SetColor(GUI_RED);2 F# u3 r0 q# S+ q, L9 y- U
  103. GUI_DrawPixel(326, 20);
    1 R4 V; t1 R/ }% V' k
  104. GUI_DrawPixel(326, 21);
    ' |" T8 a) s- u) [& Y# g! I
  105. GUI_DrawPixel(327, 20);
    3 }: |& O( h+ R& n
  106. GUI_DrawPixel(327, 21);% b' l8 s; `* w
  107. GUI_DrawPixel(328, 20);7 S' [: C5 L% B* N& y' t% C
  108. GUI_DrawPixel(328, 21);! K3 t# Q. L+ c! g; w' p7 y
  109. GUI_DrawPixel(329, 20);
    ! _+ {& t2 {* Y2 L) o
  110. GUI_DrawPixel(329, 21);
    / c. c, M4 R+ C9 B; r
  111. GUI_DrawPixel(330, 20);
    7 n+ g, ~; j, I+ `  p% P( R' I
  112. GUI_DrawPixel(330, 21);
    6 x; R# s" Z) O& I

  113. ( |- D* \8 T( q: f; e+ O
  114. /* 第6步:波形显示区的边框*************************************************************/
    - t' `3 p! j; _
  115. GUI_SetColor(0XEBCD9E);
    1 u0 R  H! ?% P4 m
  116. GUI_DrawRect(DSOSCREEN_STARTX - 1, /* Upper left X-position. */
    , R% h& O  ]7 n
  117. DSOSCREEN_STARTY - 1, /* Upper left Y-position. */
    : I$ k$ b' }- w! ~" g
  118. DSOSCREEN_ENDX + 1, /* Lower right X-position. */0 {$ x! K- _9 `) F
  119. DSOSCREEN_ENDY + 1); /* Lower right Y-position. */
    2 y/ P3 {9 |% P- \! T; U' a
  120. 1 y; f; U% P: g, }
  121. GUI_SetColor(0XB37F63);
    ; l* K2 Z" G5 v0 i0 {
  122. GUI_DrawRect(DSOSCREEN_STARTX - 2, /* Upper left X-position. */- ^1 }- ~8 d. P. d
  123. DSOSCREEN_STARTY - 2, /* Upper left Y-position. */
    1 U2 F$ ^( B9 H
  124. DSOSCREEN_ENDX + 2, /* Lower right X-position. */5 C" V' x& c* U3 J5 s+ x, T
  125. DSOSCREEN_ENDY + 2); /* Lower right Y-position. */& U" [; ]9 t. [/ |; N
  126. " T) \. j3 ~" ]% H
  127. /* 根据需要是否需要重新创建按键和窗口 */: {7 A3 [0 F' j, P- }' _/ X$ y0 X
  128. if(ucCreateFlag == 1)* d6 I' s( \  a$ x" _: H
  129. {
    ' A  @. `# {' G4 B
  130. /* 第7步:创建状态窗口*************************************************************/
    ) z' y! W3 v, q, l
  131. hWinAmp = CreateWindowAmplitude();
    3 n2 s# w+ d& [4 {( X. [
  132. hWinStatus = CreateWindowStatus();) {4 m% X$ N( S  o1 D+ S* X4 O
  133. hWinScale = CreateWindowScale();9 ?- |" u# L+ i! M' J. A  j) |
  134. /* * h' D/ O) `  O; c- M& o% Q
  135. * 创建定时器,其功能是经过指定周期后,向指定窗口发送消息。5 \! _* K3 F) \3 {2 V
  136. * 该定时器与指定窗口相关联。 1 T( M% }1 ?: m+ z! R8 G
  137. */2 S+ i6 A$ J; G+ B! f7 k! S
  138. WM_CreateTimer(hWinStatus, /* 接受信息的窗口的句柄 */
    , j" _$ X3 ?/ z7 j0 Q+ _+ P
  139. 0, /* 用户定义的Id。如果不对同一窗口使用多个定时器,此值可以设置为零。 */9 M& D, |$ S/ y0 x3 ^
  140. 500, /* 周期,此周期过后指定窗口应收到消息*/
    & r. l# V1 B6 o5 @/ e
  141. 0);         /* 留待将来使用,应为0 */
    / i# L5 B' ?% ~- Y4 p/ G+ ^' b

  142. % h% D3 g( q5 F" t
  143. /* 第6步:创建需要的按钮*************************************************************/
    - n8 v; W! h* d& C# S
  144. hButton0 = BUTTON_Create(670, 40, 100, 45, GUI_ID_BUTTON0, WM_CF_SHOW);
    ( _" u" [9 k  S0 p" @5 J0 h
  145. BUTTON_SetText(hButton0, "Measure");$ v3 M0 b) L/ l: V% q
  146. BUTTON_SetFont(hButton0, &GUI_Font20B_ASCII);5 s/ M' Q$ H0 I7 q2 L% _

  147. , o2 a% n0 F, Z: B; P
  148. hButton1 = BUTTON_Create(670, 90, 100, 45, GUI_ID_BUTTON1, WM_CF_SHOW);4 I/ R+ ]. F; H) e' C5 M
  149. BUTTON_SetText(hButton1, "Inspector");
    6 p, b; y+ e' {6 F# T
  150. BUTTON_SetFont(hButton1, &GUI_Font20B_ASCII);
    / T- [% V' {. c( `$ K# t$ g9 @

  151. & ?1 k/ v( J) i5 g# w
  152. hButton2 = BUTTON_Create(670, 140, 100, 45, GUI_ID_BUTTON2, WM_CF_SHOW);! c0 l$ F: ^5 c
  153. BUTTON_SetText(hButton2, "Acquire");! p: G! g4 \% g1 }( |
  154. BUTTON_SetFont(hButton2, &GUI_Font20B_ASCII);
    # W! U& {( x; z' q$ v+ B/ C
  155. hButton3 = BUTTON_Create(670, 190, 100, 45, GUI_ID_BUTTON3, WM_CF_SHOW);' C3 v5 o/ @' K3 s+ J6 A$ Q
  156. BUTTON_SetText(hButton3, "Trigger");; |* {! H1 Q& ~, l. K
  157. BUTTON_SetFont(hButton3, &GUI_Font20B_ASCII);
    6 U! c( k% u0 e8 C
  158. % N# j( X3 K+ g; z
  159. hButton4 = BUTTON_Create(670, 240, 100, 45, GUI_ID_BUTTON4, WM_CF_SHOW);
    . U" J6 k; H& J4 P
  160. BUTTON_SetText(hButton4, "Math");
    . Z3 e3 v+ E% ~/ n
  161. BUTTON_SetFont(hButton4, &GUI_Font20B_ASCII);% @3 d5 q+ K& H4 B) e
  162. hButton5 = BUTTON_Create(670, 290, 100, 45, GUI_ID_BUTTON5, WM_CF_SHOW);
    ) x3 a6 I4 }" x$ v! ^- T/ H. d
  163. BUTTON_SetText(hButton5, "Settings");
    - g9 `% ~5 ~* K
  164. BUTTON_SetFont(hButton5, &GUI_Font20B_ASCII);  q4 D% |7 S* C6 u* n
  165. 5 ~" i$ e5 ]: q5 ^* q+ d' K
  166. hButton6 = BUTTON_Create(670, 340, 100, 45, GUI_ID_BUTTON6, WM_CF_SHOW);0 H% v! t- \: V* j4 G+ S
  167. BUTTON_SetText(hButton6, "DAC");
    & t. n% M# o( O4 x5 G9 @
  168. BUTTON_SetFont(hButton6, &GUI_Font20B_ASCII);0 ^5 ~- ^; J$ n8 l5 o
  169. hButton7 = BUTTON_Create(670, 390, 100, 45, GUI_ID_BUTTON7, WM_CF_SHOW);! h* g& z- c; t! B% m
  170. BUTTON_SetText(hButton7, "Return");9 d6 N0 U* m* R& Z) V
  171. BUTTON_SetFont(hButton7, &GUI_Font20B_ASCII);% L  B( c. Y3 Z1 l) w
  172. }
    # }4 ~: k3 |9 a( B. j+ i$ W. b
  173. /* 第8步:显示参考坐标*************************************************************/  a6 ^* O- j. c% R  |+ n' `
  174. GUI_SetColor(GUI_YELLOW);
    4 v4 O: B5 c( F( g$ E% t! ~
  175. GUI_FillPolygon(&aPoints[0], GUI_COUNTOF(aPoints), 5, g_usRefPos);. L/ \4 c5 p: X& O/ ]- \
  176. GUI_SetColor(GUI_BLACK);$ Z8 g5 J& a* @! s" U
  177. GUI_SetFont(&GUI_Font24_ASCII);
    - F  q  I# b2 K2 b( y0 u( G
  178. GUI_SetTextMode(GUI_TEXTMODE_TRANS);( n2 J" F+ \/ ^) I" k5 S
  179. GUI_DispCharAt('1', 10, g_usRefPos - 10);; D6 D; ]" c) P
  180. }
复制代码

& N0 w+ |6 E5 {+ K5 v
baiyongbin2009 回答时间:2015-5-6 11:29:31
本帖最后由 baiyongbin2009 于 2015-5-6 11:30 编辑 ; q# k2 [8 f: q3 g5 {+ j

" `4 c" A. h1 R1 u& J45.2.5 DSO_MeasureDlg.c—测量对话框
    这个文件主要用创建如下对话框:
45.2.png
  f" R6 V% _3 q# C2 R4 a
45.2.6 DSO_InspectorDlg.c—对话框
    这个文件主要用创建如下对话框,此文件实现的对话框还未开发,留待以后升级使用:
45.3.png

, }& k" o  [, n0 T7 W# J, \
45.2.7 DSO_AcquireDlg.c—对话框
    这个文件主要用创建如下对话框,此文件实现的对话框还未开发,留待以后升级使用:
45.4.png
0 X- V) K3 q4 s3 [0 w
45.2.8 DSO_TriggerDlg.c—对话框
    这个文件主要用创建如下对话框,此文件实现的对话框还未开发,留待以后升级使用:
45.5.png
3 K2 e- V7 A( p. H& }: z& [8 o
45.2.9 DSO_MathDlg.c—Fir低通滤波器设置对话框
    这个文件主要用于Fir低通滤波器的截止频率配置,创建对话框如下:
45.6.png
6 h! }7 g1 W8 _" C: o4 I$ w8 t3 p
45.2.10 DSO_SettingsDlg.c—设置对话框
    这个文件主要用于设置对话框的创建。
45.7.png
/ {+ I4 N1 j9 J: T
45.2.11 DSO_DacDlg.c—对话框
    这个文件主要用创建如下对话框,此文件实现的对话框还未开发,留待以后升级使用:
45.8.png
. V0 y( x; F' c: I! e, Z1 A
45.2.12 DSO_ReturnDlg.c—对话框
    这个文件主要用创建如下对话框,此文件实现的对话框还未开发,留待以后升级使用:
45.9.png
  C" A" N3 {( h  ?: d
45.2.13 DSO_DrawBakFrame.c—绘制波形区的虚线方格
    这个文件用于创建如下虚线方格(不包括波形显示):
45.10.png

9 a) N% Q" i- L7 ~5 e
45.2.14 DSO_DrawCursorH.c—水平测量游标
    这个文件用于创建如下水平测量游标:
45.11.png
; p& B! x& g# F* m
45.2.15 DSO_DrawCursorV.c—垂直测量游标
    这个文件用于创建如下垂直测量游标:
45.12.png
  N3 z4 G' w0 F: j6 B1 }( x

45.2.16 DSO_AmplititudeWindow.c—幅值窗口
    这个文件用于创建如下窗口:
45.13.png

1 t% \+ v: Q9 y8 r2 r

45.2.17 DSO_ScaleWindow.c—时基窗口
    这个文件用于创建如下窗口:
45.14.png

  o9 \  p  h* V+ R8 |$ q

45.2.18 DSO_StatusWindow.c—测量值窗口
    这个文件用于创建如下窗口:
45.15.png
* d( q8 n( m3 p" y) P

45.2.19 DSO_FirFilter_Step1KHz—Fir低通滤波
% L: R7 z6 a8 V  v6 A4 {: F

1 Q; Y, b0 Z, E; S5 v45.2.20 DSO_FirFilter_Step10KHz—Fir低通滤波$ E/ i. i) e, d  ?5 q- Z/ O0 Y
  y/ W0 ~& q4 w- a" P1 Z+ V+ g6 \
45.2.21 DSO_FirFilter_Step100KHz—Fir低通滤波
    上面的三项主要用于Fir低通滤波器的实现。

0 f! Q& F+ [) c* r1 z, O* Y) X4 C' d4 w& }/ f
baiyongbin2009 回答时间:2015-5-6 11:32:42
45.3 DAC实现方波的输出
    DAC输出方波的配置要注意初始化的顺序,顺序错误了,方波是无法输出的,还有就是不用的MDK优化等级,DAC配置时的顺序也不一样,这个应该是DAC库的一个bug。
  1. /*
    ' Q. m* C% b' H+ c: Z
  2. *********************************************************************************************************
    9 x" r- k" h6 [7 U3 D7 F7 W, ^
  3. *        函 数 名: bsp_InitDAC! c" s. R  T; W7 A( H1 M6 H
  4. *        功能说明: DAC初始化
    ( U" u( q& c0 x. N
  5. *        形    参: 无0 H5 F5 m5 x: U% G7 C
  6. *        返 回 值: 无9 M. A4 n; _; h+ |
  7. *********************************************************************************************************
    4 c6 P1 }. W8 ]& K" I0 H- x7 C
  8. */
    % o2 u0 @; B* G. r& X
  9. void bsp_InitDAC(void)
    4 s- L; v$ I+ V- w2 g; q
  10. {   
    & Z, X) O  A% a8 X' r" f
  11.     uint8_t i;1 P4 v* w" T, J+ C. n$ K/ m

  12. ( c9 K  O# ^4 Y! _# m1 W
  13. /* 用缓存放一个周期的方波 */: V9 v2 x* S# z
  14. for(i =0; i < 32; i++)1 f5 V9 ?1 x$ t2 {8 M
  15. {
    8 x. q6 O8 i7 r" P. L# L
  16. g_usWaveBuff[i] = 0;9 t+ Q! p7 S& D
  17. }% Z5 I8 |3 t- J. Y7 o* i
  18. for(i =0; i < 32; i++)0 F0 q" @' E2 y3 R  {/ U
  19. {
    + M: Z- Z: [# D: d
  20. g_usWaveBuff[i+32] = 2048;( ^- Y( t7 j' y7 L2 {/ i
  21. }
    & o# [4 C" V! ?" ^# b) R7 L& k$ ?9 {, z
  22. /* MDK优化等级为1的时候,DAC初始化顺序,不同的优化等级,
    8 U" }( Y" K' A
  23.    不同的输出顺序容易操作DAC无法输出波形。
    / [+ f# @  d1 d$ L; v/ n; V1 \; x1 i/ A4 V
  24.    这个问题要引起大家的特别注意!!。; L8 v0 x2 ^4 G/ Y; f
  25. */) W+ i$ z6 w, y0 [6 v5 m
  26. DAC_Ch1_WaveConfig();5 w# Z( l5 p3 Y1 t# q% v- l
  27. DAC_GPIOConfig();
    3 T. y( y' F; Q& J
  28.     TIM6_Config();
    , h' p0 a4 j) d- m% t! i
  29. }
复制代码
- _) Q- P' j$ Y' g- S& D/ T
baiyongbin2009 回答时间:2015-5-6 11:35:12
45.4  ADC实现数据的采集
    ADC的驱动主要注意两个问题,一个是ADC数据采集的关闭或者开启一定要保证同步,要不会出现采集数据的混乱,还有就是由于没有使用官方的3ADC快速交替采样,官方的快速交替采用使用定时器触发采集出的数据效果不好,抖动较大(特别是使用定时改变不同的采样频率时) 。现在采用的每个ADC都是用定时器单独的触发,并把触发数据分开,分成三等分,每个时刻实现一个ADC的触发。
  1. /*
    - ]1 |% ~; G" ]+ _% r8 S# }
  2. *********************************************************************************************************
    4 @' M4 h5 m  a8 M0 [2 _
  3. *        函 数 名: TIM1_Config
    " c" U! ~, G3 V8 }
  4. *        功能说明: 配置定时器1,用于触发ADC1,ADC2和ADC3。
    7 a( ]2 E% }- h6 t; \
  5. *             当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。4 _% Q7 P. ]2 X* t% J, h6 ?
  6. *        形    参: 无! l5 m. u, `$ `
  7. *        返 回 值: 无3 ~. A+ O" X5 B, B
  8. *********************************************************************************************************
    / H+ M. Z/ B6 D
  9. */& I6 k/ H' r% v# _
  10. static void TIM1_Config(void)0 R2 P4 Z3 T: ]$ @
  11. {! k" s2 g4 O" E% E3 Q( ~$ L
  12.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    9 C' ?3 w7 f0 R- ^- L( B5 U5 h
  13.     TIM_OCInitTypeDef  TIM_OCInitStructure;& Q" L- H/ R' Q0 L
  14.     8 O8 q2 p) w" k6 \" ?9 i
  15. /* 使能定时器1 */
    5 H# o1 I/ b) b  n% w; @& y
  16.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);' h0 S% f6 Z& `2 b$ S
  17.    
    " C( T1 N, u# n2 r' X5 D
  18. /* 先禁能再配置 */
    2 f, Q' y$ }. O( f% M! @# {
  19.     TIM_Cmd(TIM1, DISABLE);
    8 ~$ a" x9 |7 i& ^$ b: r
  20.     /*
    & [3 |, W$ j! D( C9 M- m/ E' A
  21.      ********************************************************************************  Q/ N, i) a2 e% _; D
  22.     system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:. `9 {9 U: O: g& u% _) s
  23. * P( _+ k- {0 w& m& V
  24.     HCLK = SYSCLK / 1     (AHB1Periph)0 Q7 {: d% C. e: g2 J  f. ~2 R: _
  25.     PCLK2 = HCLK / 2      (APB2Periph)5 @# i* S9 A) }* _1 A
  26.     PCLK1 = HCLK / 4      (APB1Periph)* d: @+ O4 A7 e3 e* X
  27. 0 p/ x* Y6 S" x5 B) f% h. F
  28.     因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
    ' z3 p" }" {/ }. z
  29.     因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;' b5 A" F9 j; Y4 E( H

  30. * v" O  y* F- f2 ^1 s0 M, a- a4 f
  31.     APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14# s, |9 n, Z- o& S
  32.     APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM117 S7 j% p% g! H/ T! T0 h+ f9 ?$ m
  33.           8 M3 U9 q/ f2 F( N
  34.     TIM1 更新周期是 = TIM1CLK / (TIM_Period + 1)/(TIM_Prescaler + 1)
    0 X! b) i+ N& i' I
  35.     ********************************************************************************
    $ D5 @$ H/ Y- ]) k
  36.     */
    ) i0 x7 \5 n& s6 E% I. X, s- b
  37.     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);            //初始化定时器1的寄存器为复位值+ G9 C# x8 x6 E! Z- u+ q' z
  38.     TIM_TimeBaseStructure.TIM_Period =  168000000/g_SampleFreqTable[TimeBaseId][0] - 1;    TIM_TimeBaseStructure.TIM_Prescaler = g_SampleFreqTable[TimeBaseId][1]-1;    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;                        //CR1->CKD时间分割值
    7 J; x, c! @+ ]2 x
  39.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     //CR1->CMS[1:0]和DIR定时器模式 向上计数/ ^* \& U# Y$ E7 \- L' E6 X& N* P
  40.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    % R6 W1 Q' O+ C0 W4 y
  41. ! f% O4 R1 Y  x5 N
  42.     /**************ADC1的触发***********************************************/1 r0 `! h. T& i! i4 E5 Q: J- E5 @
  43.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;      //CCER 输出使能         
    7 R8 E, s) _5 y, G1 Q1 V, ?) z. P( [
  44.     TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period/3;    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;               //CCER输出极性设置
    ) N2 d+ r4 Y  o
  45.     TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    , v4 F# j/ I$ i& y$ R
  46. /**************ADC2的触发***********************************************/
    . l7 t8 V+ |9 ~/ \* c; d& k6 P
  47. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           
    7 M  u; |9 ^3 K. C1 U3 \
  48.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     
    " G+ a2 e0 s/ k0 z. F% H' F
  49.     TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period*2/3;6 y! p; p2 V$ W
  50.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;              
    + }( P) @( N+ f% r4 x; ~" v+ {
  51.     TIM_OC2Init(TIM1, &TIM_OCInitStructure);( @( ^2 d3 ?2 R1 V% |
  52. /**************ADC3的触发***********************************************/. E' r; t4 R1 M% v+ C
  53. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            5 |; I9 ~. Y- }$ f9 K2 v. Y
  54.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     
    % \+ ?8 m4 G2 ~4 O# ]' f
  55.     TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period-1;
    / S% d$ V7 {& B
  56.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;              ; `, h8 N$ U" S  y# g# W6 T7 S
  57.     TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    * i: K: a$ N( z5 Z: B8 I/ D0 M* I
  58.     //TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);         //CMR2 设置预装载使能  更新事件产生时写入有效  g% |, b1 m# q
  59.     //TIM_ARRPreloadConfig(TIM1, ENABLE);                              //CR1  设置ARR自动重装 更新事件产生时写入有效
    : g& L" {3 R. t+ J
  60.     TIM_Cmd(TIM1, ENABLE);* e* x' E; e7 P" D3 j: E( d
  61.     /* 使能PWM输出 */
    9 h& ]; J/ Z& F9 X/ \$ L
  62.     TIM_CtrlPWMOutputs(TIM1, ENABLE);  
    . K6 }3 M' E  O! R
  63. }
复制代码
下面是DMA的开启和关闭,一定要保证按照如下的顺序进行,且这些函数不能省略一个,要不重新开启DMA数据将无法再次传输。
  1. /*
    , R, e9 Q1 z  G0 h! O
  2. *********************************************************************************************************
    4 ^' q1 ~. \: ?1 K
  3. *        函 数 名: DMA_Open
    * X7 X) u1 n+ F0 q* {, J
  4. *        功能说明: 使能ADC1,ADC2,ADC3的DMA2 U( D+ @  v- q* i0 w
  5. *        形    参: 无6 P, V" O7 n- Z8 G
  6. *        返 回 值: 无
    9 A- e2 J: a1 _+ O2 h
  7. *********************************************************************************************************
    9 ~+ f' T6 g. l9 c& u6 O9 r+ x
  8. */
    . p* v' K2 Z1 C. ~+ P: W6 Y/ j
  9. void ADC_DMA_Open(void)2 \$ Q/ j2 b* a' l9 X
  10. {
    ; k! [8 [1 S- @  o8 @% i! h
  11.     DMA_InitTypeDef       DMA_InitStructure;
    7 B0 ]! W- g* N1 y( q3 e8 j# J
  12. 2 b2 [3 @( h( r& a: Z
  13. /* DMA2 Stream1 channel1 配置用于ADC3 **************************************/8 v8 Y7 r4 i1 g8 R) `$ Q" w
  14.     DMA_DeInit(DMA2_Stream1);
    ) j7 H' ?# K  Q5 V. U* D
  15. DMA_InitStructure.DMA_Channel = DMA_Channel_2;  
    ; Q$ O. A/ Y# P, c
  16. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;2 C! D9 c" n3 d4 Z% M5 b* x5 S0 s
  17. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;- \7 O2 p! ?. P
  18. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    - U0 T- }% l- p" G2 ~6 M
  19. DMA_InitStructure.DMA_BufferSize = 1024*10;, k  ]7 J# F# o- E; f* |  p+ d& ^
  20. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    ! X$ P" b9 b0 A. D2 {, O
  21. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    3 n2 a2 U. q& ^
  22. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    , v' R$ P. c1 G7 X: z$ N
  23. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
    # ^+ i8 E; `: p9 a# t( v# G
  24. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    6 }3 ?2 c* h) Q/ X( e6 e
  25. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    % Q4 A) q. @1 P/ R6 J, X( [: x
  26. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
    $ `. @, v/ I% n/ G  o: b) ]
  27. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;+ p8 E5 u) D7 v' }& y4 X
  28. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    8 Z4 a, c$ s1 g& B
  29. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;6 h; |: P  E1 u: `4 Y6 N
  30. DMA_Init(DMA2_Stream1, &DMA_InitStructure);; f* E1 ^' M4 X) N2 V
  31.     DMA_Cmd(DMA2_Stream1, ENABLE);  d) G6 Y! R+ ?  ]$ k; w
  32. /* DMA2 Stream2 channel1 配置用于ADC2 **************************************/
    6 p! ~5 W% Y$ C, ^3 C4 y
  33.     DMA_DeInit(DMA2_Stream2);  /* 在DMA的DMA_Mode_Normal模式,一定要使用这个函数,循环模式可以不用 */
    ; Z( ~* _8 ^& x% e8 y
  34. DMA_InitStructure.DMA_Channel = DMA_Channel_1;  $ E( M; w9 o: R$ Q# Y! i9 x) S5 c
  35. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC2_DR_ADDRESS;+ L% E5 r6 [8 t/ }* A, H
  36. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC2ConvertedValue;: s2 }8 [4 }; U
  37. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;* m3 }' L0 ^" X- ~- S( Q
  38. DMA_InitStructure.DMA_BufferSize = 1024*10;
      M1 h/ D" D- H  S% G4 g- z! M
  39. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    # R: a% f8 H. t6 E! }, ?. d+ }
  40. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;8 w" F/ e0 M5 m! _+ H/ C( N4 u6 _1 m
  41. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;4 {4 f$ _0 ]/ Q) z9 Y" a6 g+ G7 u
  42. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;# O. g/ @7 }$ K6 u& w9 O
  43. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
      n3 b5 ^, x* U: K! C# a# N
  44. DMA_InitStructure.DMA_Priority = DMA_Priority_High;% G' L; R) u1 s- E, x% B3 i
  45. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         % i- A9 m5 H' N6 @/ R  Q, c. a& @+ e/ ~
  46. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;6 w# H# b9 l1 j  `, Y
  47. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    # m6 B3 Z; c, H
  48. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    2 e$ O6 w/ M2 d
  49. DMA_Init(DMA2_Stream2, &DMA_InitStructure);9 \' D1 H- y9 M7 g
  50.     DMA_Cmd(DMA2_Stream2, ENABLE);
    , m1 d. Q1 |& P7 M; E
  51. /* DMA2 Stream0 channel0 配置用于ADC1 **************************************/
    - c" x0 r9 ]+ x! @0 [( D
  52.     DMA_DeInit(DMA2_Stream0);
    2 z3 U0 R% u# v5 R
  53. DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
    0 `! R- x0 i0 Q2 l' @" Z/ C0 v( x
  54. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
    # ]* V' p6 q0 z% @0 W! z
  55. DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
    " X2 ?: ~2 ^3 x) G
  56. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    & q, C+ h3 r" q" o
  57. DMA_InitStructure.DMA_BufferSize = 1024*10;
    / ~6 o9 f6 I. f9 Y
  58. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    5 _, t! H9 W4 E4 h5 R
  59. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    7 c& A5 g9 x+ j
  60. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    7 p& W. b1 i2 l$ C2 y9 [
  61. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;" k; X0 A( O2 L8 K5 e# I( S! ~
  62. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;& ~( c$ `+ J, A  N4 A- T& x
  63. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    ( |9 s! |* e( |8 |% ?  `9 b
  64. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
    % S% D8 l( j6 y
  65. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    8 |' X) x# }& h2 I* ?
  66. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;- k; E, G7 g4 @3 z
  67. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;3 w2 N* N( n, j) G* U0 A
  68. DMA_Init(DMA2_Stream0, &DMA_InitStructure);
    ! V9 r/ E  z  _6 P6 U" L
  69.     DMA_Cmd(DMA2_Stream0, ENABLE);; u6 q  W$ H, }- B  x3 X
  70. , h) A! j+ ?' Y# n; L
  71. ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
    $ a2 U- \2 [/ [8 C* B: ]- D

  72. 7 r6 R; \% F" a$ i8 H* V% J7 c
  73. /* 使能 ADC3 --------------------------------------------------------------*/
    % l4 O( z. K5 q' n' {0 E) t
  74. ADC_Cmd(ADC3, ENABLE);$ X% o$ [: q8 s1 c3 `+ O
  75. ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
    8 A. V* G8 n; E1 ]& u4 ~- {

  76. ! _% y+ o. A8 J0 X9 S3 U
  77. /* 使能 ADC2 --------------------------------------------------------------*/- f0 [3 J9 W! V  m3 Q' B7 q; t
  78. ADC_Cmd(ADC2, ENABLE);  y0 `( v; I! H/ H+ t2 _
  79. ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);+ K- ~) Z5 h8 Y) c& ~$ I9 e

  80. 2 j9 \2 J. C: Y2 c9 _( b
  81. /* 使能 ADC1 --------------------------------------------------------------*/
    : Q  I! q- c. T# G# k
  82. ADC_Cmd(ADC1, ENABLE);
    & a5 I0 |0 A) O: C8 S$ ?7 S, h

  83. 5 F+ J  |, m9 i- t: |) D6 u4 j* Y
  84. /**定时器配置,一定要重新的初始化从而保证同时触发 **/& s8 s+ `8 L& G8 g1 K
  85. TIM1_Config();
    $ F- d; P# ]* c* R

  86. + e& r# V! b/ d) Y3 r5 Q
  87. /* 只有在普通触发模式在启动TIM8的计时功能 */9 B- T- @5 e( V# r' O2 [# z5 \
  88. if(TriggerFlag != 0)1 @! V4 f: M5 |* ^( p# V6 u
  89. {+ M2 w* c0 x" I7 t' x: E' O
  90. Time8Recorder();- }, P, u6 [* t8 ?
  91. }
    6 d4 L2 g! v/ \( @2 M6 G
  92. }
    3 C* c7 L: l9 c4 n+ {* g; |

  93.   h5 d) O" b7 g/ p" N2 U
  94. /*$ r( v" h- y/ Y/ |
  95. *********************************************************************************************************' J( A( H* T: [' `* w8 W6 ]$ V+ t
  96. *        函 数 名: DMA_Close+ R. G* F- Y% Q/ {2 y( w! n' V
  97. *        功能说明: 关闭ADC1,ADC2,ADC3及其DMA7 E7 r: f% B- @0 e' t
  98. *        形    参: 无7 D4 I5 i( o4 S( Z6 R. o
  99. *        返 回 值: 无
    . B1 K2 i+ }$ h  {: k
  100. *********************************************************************************************************
    9 S6 ]- X& A2 B' ^" n% r* _1 S
  101. */
    0 T$ q" ^* q, U0 x& x
  102. void ADC_DMA_Close()0 n9 \0 E% u1 p
  103. {
    & T& _# A1 ~' |7 e
  104. TIM_Cmd(TIM1, DISABLE);  w' _$ G* u( f5 K* K3 M
  105. DMA_Cmd(DMA2_Stream1, DISABLE);" [, l1 I1 Q" _) z1 k# ]# a4 W
  106. DMA_Cmd(DMA2_Stream0, DISABLE);
    ; v1 c! ~& I6 @( }5 v7 g
  107. DMA_Cmd(DMA2_Stream2, DISABLE);1 l0 E) v+ D1 X( r) i9 F
  108. /* 禁止 ADC1 ---------------------------------------------------------------------*/
    ; o8 V' e" S5 Y8 |) D6 A0 I' z
  109. ADC_Cmd(ADC1, DISABLE);3 I* o$ j1 G* _: J$ m

  110.   ^. D+ t& {2 G' a
  111. /* 禁止 ADC2 ---------------------------------------------------------------------*/; X0 }$ ~! E' e0 ]8 w
  112. ADC_Cmd(ADC2, DISABLE);% V3 H. d/ _( H
  113. /* 禁止 ADC3 ---------------------------------------------------------------------*/
    % W) w( p5 k% N8 z/ C; s4 F% ?- m
  114. ADC_Cmd(ADC3, DISABLE);$ v) Z+ e# [# Z0 O
  115. }
复制代码

1 _( R( D& U% S% K" C
baiyongbin2009 回答时间:2015-5-6 11:35:32
45.5总结
  l* {4 C5 J$ a7 |4 y/ P: k4 H. S3 N示波器的框架设计就跟大家讲解这么多,后续后推出示波器的详细设计教程。有兴趣的可以直接看源码即可,源码注释已经比较详细。
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版