本篇内容将简要分析STM32自带的DSP库文件,其用汇编语言编写,代码执行效率明显优于C语言,ST公司封装好了了库文件,我们不必看懂其汇编代码,只要会调用接口函数即可。 1,代码分析 首先我们需要在一个已经建立好的工程文件里添加如下编译路径: 工程需要添加的文件如下图: 0 b* F1 y- ^% ~6 ]% U1 Q) z/ K/ |
为了产生fft变换信号,我们可以自己产生个采样信号:使用三角函数生成采样点,供FFT计算,fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。8 f( h$ V/ p; v1 v4 e8 o
模拟采样数据,采样数据中包含3种频率正弦波:50Hz,2500Hz,2550Hz, lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)。
8 n1 n) j7 u8 y1 ]1 ] 其中dsp_asm_init()函数的作用是产生采样信号,实际工程应用中我们使用的是ADC采样的处理值。dsp_asm_test()函数的作用是进行FFT变换,并计算各次谐波幅值。具体代码参见下面:
6 K! O$ B( m; T) T4 o+ l- 1 /*
. y2 a) D3 N) Y - 2 *********************************************************************************************************8 p( G" x7 {2 c: V4 ^
- 3 * MICIRUM BOARD SUPPORT PACKAGE2 C: C4 n! b. Y" T" l: j8 a. u9 j
- 4 *+ S1 ?# j9 Q# C) U) K& `/ W
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL, d' F0 Y6 ~# Y5 T# Z: e9 M
- 6 *( E5 u) a4 R8 p1 v5 o
- 7 * All rights reserved. Protected by international copyright laws.
) m, M% ~* r$ v# K7 R, A" o - 8 * Knowledge of the source code may NOT be used to develop a similar product.+ m, D' T+ t) i) c
- 9 * Please help us continue to provide the Embedded community with the finest. t& t- {( B* G5 z2 @# N
- 10 * software available. Your honesty is greatly appreciated. X, V1 S) ^, _: }* T F
- 11 *********************************************************************************************************" t: I0 u/ \8 F4 j
- 12 */
6 x3 y" q0 L; w6 _ - 13 - s- ~, h; y; C) o$ |( J S9 {2 Y
- 14 /*6 t1 E0 W) ~7 ~! C
- 15 *********************************************************************************************************3 a6 {' C" ?' s# ]' C1 C
- 16 *; m: C3 Z* f" |5 N
- 17 * BOARD SUPPORT PACKAGE4 Z2 h" G7 }4 g# z8 h
- 18 *$ k! c& M7 S3 @/ s5 N' p! W" _; v
- 19 * ST Microelectronics STM327 |$ ~2 D+ I. x6 u' i9 u$ `
- 20 * with the
7 m( D+ d n) X% b" ^ - 21 * STM3210B-EVAL Evaluation Board# v# f0 d2 k& ?! d: s5 H2 f
- 22 *
5 a+ Y5 \" X3 o4 s - 23 * Filename : bsp.c
9 z+ |/ O2 E- P- l7 v - 24 * Version : V1.00* [' D: ]6 | i. k
- 25 * Programmer(s) : Brian Nagel7 z) L0 o) D: K& ~, B
- 26 *********************************************************************************************************
, J3 c1 `: ~1 T( z M! h$ b1 e7 G$ T - 27 *// l" a* S/ K4 b7 W
- 28 3 A- |! w8 h+ b1 k3 V: t
- 29 /*
/ `6 b n# B/ J& l# H( j! @7 y. T, r - 30 *********************************************************************************************************
+ v# J: B1 `+ N9 |4 T - 31 * INCLUDE FILES
! w% l" p( Z$ F) B; ]5 v0 g - 32 *********************************************************************************************************1 ~; l0 J- l0 d0 X
- 33 */
" k7 G; J' p0 P1 o& U; \ - 34 / I# X* k$ C. ?* I/ k" ^
- 35 #define DSP_ASM! u( p1 Q- ~( y# V8 q
- 36 #include "stm32f10x.h"7 ~6 t1 b+ J; u2 S7 e
- 37 #include "dsp_asm.h"
* C4 u3 b' t: Y2 n - 38 #include "stm32_dsp.h"
0 x9 m, R* I: n1 r5 ?& z - 39 #include "table_fft.h"
! }/ C* I7 {6 p. ~) C7 E' } - 40 #include <stdio.h>
" z! }! ]5 q% j: Z - 41 #include <math.h>) K+ q$ v( p$ B6 [2 y' L
- 42 % n5 Q$ d! Y2 O) j# L |7 M' o
- 43 , J6 ^8 L( X+ k
- 44 /*
, ~/ U# {# ~9 p5 H2 h9 K5 g5 [/ Z# N - 45 *********************************************************************************************************
: f; e( V, N# I' @6 X - 46 * LOCAL CONSTANTS
3 j# g2 `: K) @2 ]& [: c' a( Y, [ - 47 *********************************************************************************************************
3 Y2 S2 y* U3 w9 p$ a" a: Q: N( v5 f - 48 */
4 J8 `1 ]" [! S5 F - 49 #define PI2 6.28318530717959& r8 H; O3 m$ C j, r
- 50 #define NPT_1024 10246 X5 Z, \% t( u) @
- 51 //#define NPT_256 256+ k) Y: `2 I0 ~ j5 o
- 52 //#define NPT_1024 10248 p) r ? m, x: c {" Q# f
- 53 , W/ J6 ^5 x' o L
- 54 // N=64,Fs/N=50Hz,Max(Valid)=1600Hz
* \+ W$ L6 v* S3 o - 55 #ifdef NPT_64
8 \! }8 j R3 H - 56 #define NPT 648 a/ ^8 ?' j0 J- `! P+ _ B
- 57 #define Fs 3200
$ F0 t! c- Y0 S6 e7 O0 u - 58 #endif
2 D0 N* O8 [& G4 _6 ^: R( b1 U - 59
" ~) r# f' S* f! n. ^ - 60 // N=256,Fs/N=25Hz,Max(Valid)=3200Hz
% y' p( C' n7 H8 B9 X9 }0 { - 61 #ifdef NPT_256" n3 `6 {6 @& I- [
- 62 #define NPT 256
8 e9 F6 \" |3 f+ x. V! ] - 63 #define Fs 6400% Z( h: s( F+ n" y3 c
- 64 #endif" e2 Z& \) q3 i& d3 `
- 65 3 `# k3 N5 Y- A7 e
- 66 // N=1024,Fs/N=5Hz,Max(Valid)=2560Hz# \0 F; [7 o3 u* H" G: L
- 67 #ifdef NPT_1024
& U& z; s0 y/ E2 g; d3 G4 X! e - 68 #define NPT 1024
+ W# j% d) T/ { - 69 #define Fs 5120! n, p! H( m. E% w+ X- n3 B
- 70 #endif" O5 D/ \. W6 E' ]" x
- 71 5 q8 A' I1 D- z0 l
- 72
; a4 c, Z( V8 \5 @% g c! P - 73 /*: Z$ ]4 B3 U# g5 F* [3 s
- 74 ********************************************************************************************************** U& I8 V3 N$ S' Z3 n5 K& T; M, j! q
- 75 * LOCAL DATA TYPES
2 w' [' W, l/ K9 Z/ j. C - 76 *********************************************************************************************************
" O2 s% F$ H( H v! n' @ - 77 */
7 s- T( _+ Q; { - 78
/ N& j# _# \ E. a8 |( S, i - 79
* N3 L2 r& v$ V4 o& x( V - 80 /*# [ p8 q% m0 E( b9 l: M# U
- 81 *********************************************************************************************************
; r1 i" }" E; g' n0 D+ }% s - 82 * LOCAL TABLES
+ q1 x6 t/ p$ f - 83 *********************************************************************************************************; ~+ p6 ~8 c, o, e
- 84 */, Q' a7 g m3 q3 U) g4 @4 g
- 85 - h5 J: x4 C/ Y5 A% G- L% v7 o+ w
- 86
+ `: U, z0 J9 D4 F. W - 87 /*9 V- k4 D! e1 \$ o, g! z( b
- 88 *********************************************************************************************************
$ E- b& C" l( f. X% i n - 89 * LOCAL GLOBAL VARIABLES( Q; P; J! p8 V. Z2 ]
- 90 *********************************************************************************************************4 e" T9 N5 d9 R$ t
- 91 */5 d# Y4 j/ n/ G8 P& F
- 92 long lBUFIN[NPT]; /* Complex input vector */
# @& s2 w& l5 N( M1 |4 o" t2 \% } - 93 long lBUFOUT[NPT]; /* Complex output vector */, L$ Z" Q, |* Q. E. B
- 94 long lBUFMAG[NPT];/* Magnitude vector */- _" A8 j3 J f1 n) N& Q- D
- 95 /*! G& Q: q2 x+ p$ [7 O/ d! P' `
- 96 *********************************************************************************************************
. H! ?8 n( C3 N3 b6 o* n9 k - 97 * LOCAL FUNCTION PROTOTYPES6 F2 S+ u! K, ] |1 q, v$ L/ T
- 98 *********************************************************************************************************4 k. j# E) S. a6 D) \
- 99 */
7 Y B/ W3 l; E- D - 100 void dsp_asm_powerMag(void);
) i- h L# w7 y) C1 R8 w/ l0 h/ w - 101
1 F0 I6 N Z/ ]% l+ g; \; O9 p - 102 /*& S7 t- C( P A
- 103 *********************************************************************************************************% z, s; t) j( f, g. e. L& \
- 104 * LOCAL CONFIGURATION ERRORS+ C' d7 S( {4 |4 ?* E9 y' }
- 105 *********************************************************************************************************
1 m N' z! {8 P+ @: k/ }3 m/ W7 X - 106 */
8 Z& v G4 t; i l - 107
0 F' b: O$ ]9 q4 G - 108
9 G4 E3 F. S7 ]- c! L+ u8 |) c3 T! i - 109 /*
! ~, q7 K2 j I' M - 110 ******************************************************************************************************************************
5 N: ]( `. F2 P0 [1 S8 r+ w - 111 ******************************************************************************************************************************
2 D C: l, Y+ N6 z, d6 M( p - 112 ** Global Functions5 E7 B t8 {' x6 u' I) `
- 113 ******************************************************************************************************************************, A' Y: ~2 c. _; S4 u; ~: b: E
- 114 ******************************************************************************************************************************9 v' T/ Q3 C. o% b
- 115 */
" \& s& J4 I" B" L# l% Q4 Y) y( [ - 116 J+ [$ I3 R% M) |" W
- 117 void dsp_asm_init()
, q& c& ]. o+ c w) S4 l - 118 {& } f/ f: M0 r1 D
- 119 u16 i=0;
3 D1 N. X8 c; V - 120 float fx;
. l+ Q9 J5 h5 p- R V - 121 for(i=0;i<NPT;i++)
" u* ~5 O* o- E) m% M - 122 {
- a2 b# E9 p6 ~5 G* D. f4 b" K* p- N - 123 fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);: h& \" K2 j( U! r' ]
- 124 lBUFIN[i] = ((long)fx)<<16;
4 S) J8 G7 I8 V - 125 }
" L& d2 ]. a2 k% T+ c - 126 }
% I3 \0 s- Y( y - 127 $ [$ \6 E- F Q5 @
- 128 void dsp_asm_test() 6 U6 ]# d6 j0 [ w+ s+ @# q6 L
- 129 {
+ Y4 j! b4 \+ z% u - 130
" }: \( }5 _, M' N% ?' e, y5 x - 131 #ifdef NPT_64
+ L$ b5 D+ j" q: q& y - 132 cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);/ H; q7 P+ m. I! |- y* K+ P
- 133 #endif* i- A1 M1 V+ w- P
- 134
' m' ^& k( W2 h3 Y% F" \& e - 135 #ifdef NPT_256( ~$ Z B; j H+ p* L# {
- 136 cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
0 \5 m6 S" E: }7 R& b - 137 #endif
, m' d6 `$ s; F - 138
- P0 F1 r, y. h- B - 139 #ifdef NPT_1024+ O4 G' B2 U% P: G+ \! H1 s
- 140 cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);8 E. }3 `+ E# q9 I s3 T5 X
- 141 #endif" H; n- p4 y& ]+ e+ [) {/ x
- 142
3 d) ~2 L& _1 a - 143 // 计算幅值' v! |$ F- ~7 J
- 144 dsp_asm_powerMag();6 A3 u6 B6 k0 \0 c
- 145 + d- ]3 ^+ h; L
- 146 }5 w E7 J4 N2 h3 R/ X* u; I
- 147 + r. s, `) E3 w+ _. Q. J" A
- 148 void dsp_asm_powerMag(void)! B, d# f- g _; g2 G2 U* d7 g! W
- 149 { G7 O: w: Z- D$ D8 N) U7 a
- 150 s16 lX,lY;; L% X8 l! v) U) X
- 151 u32 i;
. J/ s3 j3 s9 Y! R( s" }& s! k: @( f - 152 for(i=0;i<NPT/2;i++)
" J0 U( B- s5 x) X" e5 T - 153 {
/ P4 _. F/ V" r1 _* k) E, ] - 154 lX = (lBUFOUT[i] << 16) >> 16;' m9 V2 Z' a) }, X r7 e6 v. Y4 ]9 E k
- 155 lY = (lBUFOUT[i] >> 16);
0 u' G. s' v/ Y2 O - 156 {
; b* M) z1 m0 a - 157 float X = NPT * ((float)lX) /32768;3 P. j3 t, e5 |" y- U1 N
- 158 float Y = NPT * ((float)lY) /32768;
% ^! Y1 G/ t6 g- ]1 u - 159 float Mag = sqrt(X*X + Y*Y)/NPT;
: u/ m6 T; R9 h: L. ~ - 160 lBUFMAG[i] = (u32)(Mag * 65536);: v! C3 t. t: A7 o: S& ^
- 161 }
# ^) ~' U1 G% v/ p: v3 x - 162 }
" o! b& |; [; W( v - 163 }
复制代码- 1 /*
. `* w1 d" [# ^; L6 S9 Y$ b) G$ U' ^ - 2 *********************************************************************************************************
0 O/ w( H3 i% Z( t - 3 * MICIRUM BOARD SUPPORT PACKAGE
) F4 z, _6 K7 D# ]/ |" J - 4 *3 n7 I, J+ I3 O! R0 N0 W
- 5 * (c) Copyright 2007; Micrium, Inc.; Weston, FL
, Q) c: S& I) ]8 G; W* x! k - 6 *" s0 u5 Q8 l8 M, J6 O, M4 ^7 d
- 7 * All rights reserved. Protected by international copyright laws.
8 R d4 `1 A ~; r1 b - 8 * Knowledge of the source code may NOT be used to develop a similar product.
) U) ^, U/ _7 M% G v - 9 * Please help us continue to provide the Embedded community with the finest6 f0 ~& m* e0 V+ P$ P/ B! ~$ ~# N7 o
- 10 * software available. Your honesty is greatly appreciated." @/ W1 S, M+ c. N6 B* z
- 11 *********************************************************************************************************1 W: p9 _0 A* P" M( C- A8 |. t
- 12 */9 b- J4 [* }! s+ M9 {
- 13 - e8 ]; I+ l) {/ r+ w) a
- 14 /*3 |3 y' ?/ Y* H$ |$ p
- 15 *********************************************************************************************************
+ J" r% Z, Q. d0 G3 j4 ~ - 16 *# n- q, b ~0 x6 M$ ?& v9 W
- 17 * BOARD SUPPORT PACKAGE# P7 Y8 A; E7 o1 `% R+ w% M2 n
- 18 * }- |% Q4 C) R# a, O7 M
- 19 * ST Microelectronics STM32
8 B! y0 F' f) e( y# j5 K1 S( C - 20 * with the
# k! h: |7 \( ^ - 21 * STM3210B-EVAL Evaluation Board4 ~: r3 S2 L2 L+ e2 `7 P
- 22 *
0 _+ v1 T3 K U* g1 T( q" \, [0 b - 23 * Filename : bsp.h
0 W7 t t4 b* U/ W6 M% a) h1 ~- H! s - 24 * Version : V1.000 k3 y6 Q H0 ~0 h
- 25 * Programmer(s) : Brian Nagel) y" I" n. ^! d. i# o
- 26 *********************************************************************************************************& |' T; G" J" O+ z! p# E$ E
- 27 */; J' D7 H4 J8 ~, H+ C. J
- 28
- H7 q/ L* Q, Y3 @ - 29 #ifndef __DSP_ASM_H__7 b" G3 @$ b" o+ I# ~
- 30 #define __DSP_ASM_H__
6 O" r/ l* |' J' p+ d# @1 ]: L - 31
P8 N9 \. R. X( Q - 32 /*
3 v7 {% R0 ~ N3 J/ w# J- G5 r" N, h - 33 *********************************************************************************************************. |; A+ k R/ Y5 t0 `
- 34 * EXTERNS
9 z2 R' }' D1 p4 V+ W2 l - 35 *********************************************************************************************************+ ` @9 h! I& l1 S" r h: V
- 36 */
+ `" G* [: @7 X$ i+ _ - 37
5 {: {+ N! z n- q/ G8 B5 o' ] - 38 #ifdef DSP_ASM. n: u4 ^ W6 a0 X
- 39 #define DSP_EXT+ s/ F! D6 x6 P
- 40 #else
" q& N" K& Z# s- j1 w% H* q - 41 #define DSP_EXT extern O+ r; a: m6 J6 L% j8 I" U
- 42 #endif/ m' j3 F- e d
- 43 ! d3 H7 n+ }5 u$ r0 C
- 44 /*
( G/ O- E; Z B - 45 *********************************************************************************************************4 V4 ]' m* C3 e" G& F3 |
- 46 * INCLUDE FILES
' j# q ]) O( f+ X# B - 47 *********************************************************************************************************: b) {( n7 a" z1 G9 t" _
- 48 */3 s# p. ?7 F1 G; J0 @& n
- 49 / K& r" S6 y; ?) y: O+ F! W
- 50 * q, Y' S# p- ^) D7 z h2 ]. `
- 51 ( A- n1 h q. e0 \
- 52
) G1 \) S. p# m2 l - 53 /*5 M2 ^: p" Z' M0 R! B8 }
- 54 *********************************************************************************************************
; f6 r3 b! U2 s" H% x4 {% Z - 55 * GLOBAL VARIABLES3 R; x8 e2 V( s: H: |9 P
- 56 *********************************************************************************************************) t+ ?5 a. @+ w/ d8 U
- 57 */
T3 g. r* n \& S& h8 \ - 58
) r. O9 m( ?4 }) f |: r$ n- w1 p - 59 4 ^7 ]3 B6 E; U$ h& Y
- 60 /*. @+ {$ F# ^0 c
- 61 *********************************************************************************************************
' Y$ N3 i4 Q% s3 S& ~ - 62 * MACRO'S6 y/ t3 y1 A/ a. @4 i
- 63 *********************************************************************************************************4 H# n) h ~# w% S& ?" ?. q
- 64 */! V% k8 f1 R7 Q) i& J2 G
- 65 3 m8 ?, |9 _8 z% R
- 66 1 W: ^; t& M; F6 [8 M& I4 r% f
- 67 /*
2 f- ?, J- |) T3 z. {2 c - 68 *********************************************************************************************************
! a9 n% ?7 \. X. A/ t - 69 * FUNCTION PROTOTYPES ~. v% p: R% y- D/ q# f% s8 a9 F
- 70 *********************************************************************************************************5 y1 l3 ?$ G+ I! x
- 71 */7 o. ^( `! @2 I# ~- K+ H
- 72
9 C1 [7 L5 t' ?, x5 d9 Y) P2 t - 73 void dsp_asm_test(void);
- j F! O" e# t$ d$ } - 74 void dsp_asm_init(void);3 [3 G+ B- G( Q: i
- 75
* `' t% i* c8 Y. q3 _ - 76 #endif /* End of module include. */
复制代码 ; \1 ^$ ~! s/ I& f3 Q8 _4 H& w3 U' c
着重分析下dsp_asm_powerMag()函数的作用,其函数就是求幅值,首先定义的的一个16位的有符号的数据IX 和IY 这两个只是中间变量,然后定义的i,是32位的无符号型。语句的目的是Mag = sqrt(X*X + Y*Y)/NPT。但直接这么写不符合DSP的计算习惯也就是不符合浮点运算的习惯。因此语句在for函数i写道 lX = (lBUFOUT << 16) >> 16 就是取32位的i的低16位数据,lY = (lBUFOUT >> 16);是取高16位数据。下面的两句% C; Y5 W F/ [4 c8 Z
float X = NPT * ((float)lX) /32768;
( K2 t- ?/ h. A4 O7 g float Y = NPT * ((float)lY) /32768
2 ]2 H; n+ b) Y) ]/ F* \; {. ^ 目的就是把数据浮点化,至于为什么是除以32768 。可以这么说,浮点化就好像10进制里面的科学计数法。32768=2的15次。除以32768也就是去除了浮点数后面的那个基数,只剩下前面的。比如1991 改写成1.991*10的三次幂,再除以10的三次方,只剩下1.991,便于余下的运算。至于最后一句要乘以65536是因为我们定义的数据和我们需要求得的数据都是无符号32位的,之前已经把32位的数据拆开又分别浮点化了又开了个根号,所以再把它变回来 只需要乘以2的16次,也就是65536.比如说问你什么时候生日,你说是19911030,然而DSP是不习惯这么干的,他需要把它拆开为1991和1030。再写成1.991x10的3次方和1.030x10的3次方。然后才能进行其他的运算。8 U* C5 Q3 y/ p6 k0 {5 O2 ?: `# |
这里是ST公司采用了DSP专用芯片(主要是指TI)的写法,也就是说尽管DSP的芯片类型很多,数据变量的定义也各有差异,但原理是一样的,最终还是要采用DSP习惯的运算方式。至于为什么一定要采用浮点运算,因为机器是傻子,然而TI公司的工程师是天才。 main函数中我们只需在while(1)前加上dsp_asm_init(); dsp_asm_test();即可。0 a% K! C* P0 G2 T# ~$ x
2,实验现象 注意FFT运算结果的对称性,也即256点的运算结果,只有前面128点的数据是有效可用的。 ① N=64,Fs/N=50Hz,Max(Valid)=1600Hz,64点FFt,采样率3200Hz,频率分辨率50Hz,测量最大有效频率1600Hz 64点FFT运算结果图(局部): 上图中,数组下标X对应的谐波频率为:N×Fs/64=N×3200/64=N*50Hz. lBUFMAG[1] 对应 50Hz谐波幅值。 上图中由于FFT分辨率50HZ,最大只能识别1600Hz谐波,导致结果中出现错误的数据。 ②N=256,Fs/N=25Hz,Max(Valid)=3200Hz,256点FFt,采样率6400Hz,频率分辨率25Hz,测量最大有效频率3200Hz. w+ W: \/ M: `0 y+ d- M6 M0 K: l! P
256点FFT运算结果图(局部): 上图中,数组下标X对应的谐波频率为:N×Fs/256=N×6400/256=N*25Hz. lBUFMAG[2] 对应 2×25 =50Hz谐波幅值 lBUFMAG[100] 对应 100×25=2500Hz谐波幅值 lBUFMAG[102] 对应 102×25=2550Hz谐波幅值 ③N=1024,Fs/N=5Hz,Max(Valid)=2560Hz,1024点FFt,采样率5120Hz,频率分辨率5Hz,测量最大有效频率2560Hz 1024点FFT运算结果图(局部): 上图中,数组下标X对应的谐波频率为:N×Fs/1024=N×5120/1024=N*5Hz. lBUFMAG[10] 对应 10×5 =50Hz谐波幅值 lBUFMAG[500] 对应 500×5=2500Hz谐波幅值 lBUFMAG[510] 对应 510×5=2550Hz谐波幅值 B+ ~$ M9 k& h+ `2 ]' P
总结:该工程中模拟信号源为:4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)。 信号为1个50Hz、1个2500Hz、1个2550Hz的正弦波混合信号,幅值为均为4000。
) e3 }- T4 u; k+ H7 n3 D/ J |