特别说明:完整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 V45.1.1 AppTaskStart—启动任务 启动任务用于硬件驱动的初始化,系统滴答时钟的初始化以及触摸扫描和按键扫描,代码如下: - /*
9 J7 t5 O! c k, F# q% Q - *********************************************************************************************************5 }3 B! W- n4 R7 }2 C. T* q" l2 ^
- * 函 数 名: AppTaskStart
# W, j2 {: b/ P5 ?" V. Y - * 功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器(在BSP_Init中实现)# Q1 @$ {% v+ O* R
- * 形 参: p_arg 是在创建该任务时传递的形参 u4 a) ~4 I! F" P! S
- * 返 回 值: 无
/ f2 E# c1 K) Y, F' @( Y - 优 先 级: 2& c( p$ K. s' B4 z! z+ u7 j
- *********************************************************************************************************$ P" [, U/ H o8 i
- */, O3 m0 S( l1 I6 V7 @
- static void AppTaskStart (void *p_arg)
5 d% D2 ^( \7 i0 [3 g3 c - {+ m; ~# k g+ [1 T o. x! J
- OS_ERR err;
, R9 r* G# }: i% k8 `3 G - uint8_t ucCount = 0;
" E5 G- Q2 S5 R. F) b - (void)p_arg;
) K; o! W2 z+ j' S - bsp_Init();, K3 f! @) y8 V3 Z# c, [
- CPU_Init(); g L6 W* s) e' F
- BSP_Tick_Init(); ( }8 A0 h B9 D7 ~3 |' v
-
5 L( d% R1 A& U; S+ |% d - #if OS_CFG_STAT_TASK_EN > 0u
( T' F4 W! V( ~3 c1 n2 T' R; a b' H - OSStatTaskCPUUsageInit(&err); ( k& A( d- G' |* e. g3 Q) x
- #endif
/ u% H: N: ]4 D0 z2 M3 U5 j -
5 K% {) l0 w+ t2 s2 B - #ifdef CPU_CFG_INT_DIS_MEAS_EN' D Z; a; g+ K
- CPU_IntDisMeasMaxCurReset();6 y+ C# K. ^0 g8 F9 H% Y$ j% e
- #endif
$ S) q2 ]! D6 U/ i+ F+ e -
" `) _0 Q8 I& Y% [# N. ^ - AppObjCreate(); * Q4 A0 q8 o4 K6 y) `1 J* p
- AppTaskCreate(); @1 y3 A p7 [7 s
- while (1)
" ^% O2 i" S- S. P9 a - { - G% e2 P( @3 `. K6 S& [: {2 }
- /* 1ms一次触摸扫描 */: I+ y- d6 n$ |4 Z# l& G; F+ ^
- TOUCH_Scan();
* g# h# ]# v# I$ ?8 D - /* 5ms一次按键检测 */- m' J8 j2 ]3 e, F# q
- ucCount++;
8 r5 N/ d' o4 Z/ o( k' ~ - if(ucCount == 5)
, }! H9 s; E6 n; O# Z - {4 D6 |+ n' T; g* x
- ucCount = 0;
' Y8 f) s% F c/ ^6 P7 T) U" j( s - bsp_KeyScan();, x/ g, q. ^( w* m! W
- }
9 u0 ]) q. o- z; _' m3 r7 C - BSP_OS_TimeDlyMs(1);
. H7 X; Y; B* a% C) [/ [+ U8 [( g - }. p+ J3 U" r% b e
- }
复制代码 6 y6 s2 {8 y& R: S6 w
45.1.2 AppTaskGUIUpdate—界面截图任务 界面截图任务主要用于界面的截图并将图片以BMP格式保存到SD卡中。 - /*) C, B+ S/ c4 X4 t( x! O
- *********************************************************************************************************
3 o- M8 l3 W& o+ } - * 函 数 名: AppTaskGUIUpdate5 \3 K+ V; r8 V3 I
- * 功能说明: 此任务主要实现截图功能.
. S% N$ s/ e% p4 c, E - * 形 参: p_arg 是在创建该任务时传递的形参
" G! f) [1 J8 }+ E: b3 Z1 O - * 返 回 值: 无
, w2 a! m9 Y; R - 优 先 级: 3
6 y6 r8 v; [4 m - *********************************************************************************************************1 e# v# V3 f5 u
- */: a$ V$ o1 J, P2 s( k% g- g
- static void AppTaskGUIUpdate(void *p_arg)6 P x3 I" J" q g4 B6 O' r
- {
# V; d6 X$ z7 E% n( c - OS_ERR err;
+ ?# x0 C1 v, I - uint8_t Pic_Name = 0;: h: C# }8 k; m9 N! I
- char buf[20];% A2 P' h1 H( E
- CPU_BOOLEAN SemFlag;
# n% i0 f+ T+ N - " e: m, ]) {( M9 z; Q
- (void)p_arg;5 x% x/ l+ A: c' e
- 5 a* `' j: J, R$ w/ W: O
- while(1)/ w U: N* a5 I
- {/ M$ o; r9 Z& L1 _# @, J' N# p
- SemFlag = BSP_OS_SemWait(&SEM_SYNCH, 0);' b. j7 g' M9 s% }- l3 _3 f
- if(SemFlag == DEF_OK)
, E) I6 z* _7 R7 ^ - {- W* o" V1 h6 _6 i- T% i; q
- sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
6 @) K# N4 ?3 z0 l/ A - OSSchedLock(&err);
8 I9 w$ V; ?7 u$ f - /* 如果SD卡中没有PicSave文件,会进行创建 */
E+ i5 B$ v5 G - result = f_mkdir("0:/PicSave");
5 T, `1 x; t- P - /* 创建截图 */
# c9 j t' T: n+ c2 n/ N - result = f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
7 H' C9 \( m! |6 R# K - /* 向SD卡绘制BMP图片 */3 m" j4 [$ E1 V" x. X; }
- GUI_BMP_Serialize(_WriteByte2File, &file);
" _" w# F2 n3 T$ i$ @0 P; T/ D' \ - /* 创建完成后关闭file */" S5 [ F; J. N
- result = f_close(&file);) H7 m) y X: i: k% D
- OSSchedUnlock(&err);
j0 }( V! i( Q; y1 E - Pic_Name++; 0 G6 F& o3 |8 _7 @8 V) K% U
- } % r- `+ m0 p, \
- }
r1 y5 n% z5 j - }
复制代码 ' _2 o# a1 w1 g' s' [% U. T. t2 S
45.1.3 AppTaskGUI—GUI任务 这个任务是示波器设计中最重要的任务,代码如下: - /*/ C. J6 b8 S4 S/ ^0 `
- *********************************************************************************************************6 [0 Y& O3 G' @0 P9 T. [
- * 函 数 名: AppTaskGUI& U t5 [* L$ ?6 |
- * 功能说明: GUI任务 1 u) T) I/ O7 B, `
- * 形 参:p_arg 是在创建该任务时传递的形参" L3 s5 \! R1 {! C
- * 返 回 值: 无# K4 J3 V" d6 J
- * 优 先 级:OS_CFG_PRIO_MAX - 4u) ?/ b0 b2 p' i
- ********************************************************************************************************** Q: h" s* w, R2 A4 D
- */& j: n6 _9 P/ ?$ ]) m- \0 p
- static void AppTaskGUI(void *p_arg)
% P \! |7 Z- B4 v - {+ R& y2 e' N `7 J1 M! m/ t
- (void)p_arg; /* 避免编译器告警 */
5 M( K7 H9 E; D% s/ H; U, r* N - while (1) * R! a7 z% I8 W ]0 b) d/ ~
- {% v& [- h& z. t/ U/ Z+ z( U
- MainTask();
1 N- R! W5 L8 [5 c. e - }+ J# C2 L9 ?( Z; R- h
- }
复制代码 & M$ S/ P$ m5 {! J
45.1.4 AppTaskGUIRefresh—Led闪烁任务 这个任务主要通过LED的闪烁来指示系统的运行,代码如下: - /*
7 ?& Q( ?9 q3 N! J8 a" z - *********************************************************************************************************/ Y6 N# V6 ^/ w- ]( y* L& ?
- * 函 数 名: AppTaskGUIRefresh
, t, k6 V5 o; H I7 u4 `* d( A - * 功能说明: Led闪烁任务,表示系统运行
& ?+ i* R! o( |* o2 d' Y4 }0 ^' W - * 形 参: p_arg 是在创建该任务时传递的形参
( X; A& T( ~& d( P: Y - * 返 回 值: 无
. m, A, T1 Z9 b+ q) s+ m3 u - * 优 先 级: OS_CFG_PRIO_MAX - 5u# x9 }: A1 w. h
- *********************************************************************************************************
% }+ M% ^! D/ q$ N# ~, R5 \0 T8 _ - */8 A/ T f$ e/ A
- static void AppTaskGUIRefresh(void *p_arg)5 c' G" h5 Y8 u v( t
- {( S9 K' c4 |/ ?5 u* h
- (void)p_arg; /* 避免编译器告警 */# h3 F: \0 `; F8 C
-
! ^' h) U/ @; w8 x; r; i - while (1) ! I6 J6 Q" C( J3 k6 B
- {
: w/ f( R( K% }7 I/ e) U - BSP_OS_TimeDlyMs(200); |# Y+ }% K$ V+ X9 F
- bsp_LedToggle(2);! I% C. b9 l& z: s, m6 r
- }
- `- \( K2 q! _- ~- i o/ h - }
复制代码
+ P0 ?8 y" f( k/ _( g45.1.5 其余任务 剩下的两个任务留着以后升级使用。 - /*
/ v* `5 h! v/ E, s - *********************************************************************************************************
7 ]! m4 o+ b8 i - * 函 数 名: AppTaskCom3 S% i/ @3 w: t7 o4 {) J
- * 功能说明: 留待以后使用
( K8 E& l1 z4 z* m3 W- B% C/ P - * 形 参:p_arg 是在创建该任务时传递的形参
" C4 k6 {. t9 }3 @& q- C/ R - * 返 回 值: 无
# B* J3 f& y! h1 D3 V1 `. A8 z g: X - 优 先 级:3: D( o5 n/ \& X" U" B! Y
- *********************************************************************************************************0 e# s4 s7 t2 J1 ^) q- I! g' W
- */
- @( Y6 K5 l/ D - static void AppTaskCOM(void *p_arg)
% F! p( `- x U8 S - {
1 r. `- X W5 r* u3 l: h6 O1 W8 G - (void)p_arg;
0 _5 F) |$ T' v! f7 J - + U0 L6 E5 b- E* Q4 F, p
- while(1)1 d* A% a& W* B; N" q
- {
/ k( j: X) l1 ~, c) r- j6 a$ o - /* 100s执行一次 */) Z; P @9 C% ^7 c& n
- BSP_OS_TimeDlyMs(1000000);* w% A* s! f2 k3 y
- } ; A1 L6 D7 o& w: M
- }
/ M* \ g+ U' d3 P5 Q -
! G4 x: X9 s+ C7 i$ S7 ^2 | - /*' F0 w$ m- l( T! R. h0 I3 g
- *********************************************************************************************************; R* o( h; ^; e# \, t
- * 函 数 名: AppTaskUserIF3 j0 d0 W3 b: h! ~0 c
- * 功能说明: 留待以后使用。" g7 {# H; p( K, R0 S2 b
- * 形 参: p_arg 是在创建该任务时传递的形参( g7 V! d- a% {& }" K
- * 返 回 值: 无( D- W3 G9 M- _
- 优 先 级: 22 i) r, J0 T+ E' B% F. ?( J
- *********************************************************************************************************
- c7 v6 H- X6 _0 J - */5 z6 Y* ?& M3 N" Z4 M8 K
- static void AppTaskUserIF(void *p_arg)9 R3 ~4 i2 r2 K
- {7 r; q1 Q( J- T, s
- (void)p_arg; /* 避免编译器报警 */3 } [# W" q; h' B, C
- ! ]% W( C/ ?2 C w
- while (1)
% j# R( x; I3 R( n - {
6 A; k! J' U( C7 O' h5 {# ~2 Q; z - /* 100s执行一次 */
! K6 B% j8 e" N# k2 x - BSP_OS_TimeDlyMs(1000000);
0 D% I6 [: f2 u! N) H2 z4 c - }+ a' N' Y4 V0 w
- }
复制代码 ) [! |2 [2 ]6 R& `+ u% W
|
& d0 W1 R5 H |/ L1 H0 D5 y! F# k% ]
45.2 示波器核心任务
45.2.1 MainTask.c—GUI主任务文件
45.2.2 MainTask.h—所有DSO相关文件的头文件
45.2.3 App_SysFunction.c—界面截图
4 P; b! c: B v m# |' K' l! P
45.2.5 DSO_MeasureDlg.c—测量对话框
45.2.6 DSO_InspectorDlg.c—对话框
45.2.7 DSO_AcquireDlg.c—对话框
45.2.8 DSO_TriggerDlg.c—对话框
45.2.9 DSO_MathDlg.c—Fir低通滤波器设置对话框
45.2.10 DSO_SettingsDlg.c—设置对话框
45.2.11 DSO_DacDlg.c—对话框
45.2.12 DSO_ReturnDlg.c—对话框
45.2.13 DSO_DrawBakFrame.c—绘制波形区的虚线方格
45.2.14 DSO_DrawCursorH.c—水平测量游标
45.2.15 DSO_DrawCursorV.c—垂直测量游标
45.2.16 DSO_AmplititudeWindow.c—幅值窗口
45.2.17 DSO_ScaleWindow.c—时基窗口
45.2.18 DSO_StatusWindow.c—测量值窗口
45.2.19 DSO_FirFilter_Step1KHz—Fir低通滤波45.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低通滤波
, O* Y) X4 C' d4 w& }/ f
示波器的框架设计就跟大家讲解这么多,后续后推出示波器的详细设计教程。有兴趣的可以直接看源码即可,源码注释已经比较详细。