| 
 | 
	
    
 
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册  
 
x
 
音乐频谱(stc12系列) 
8 o5 w' i2 a  y$ F4 F. c5 \( F# f 
 
: K7 Y$ o0 @% L% U" M原理图是用proteus画的,所以没有Vcc和Gnd标识 
. J; M# ^8 }/ r  ]信号输入端的电阻、电容是抗干扰用的,大小请根据电路的实际情况做改动9 T% G7 S3 e8 l. A3 x+ R, S 
 
; H' _: B& z+ u2 W9 Y6 y程序如下: 
, }; V, k) S) u" b1 g6 u) Z. B: t- @% V& I 
 
* W* o+ J+ J8 o4 w2 Y2 M6 n3 @#include<stc12c5a.h>' w  p+ p8 [1 n3 ? 
#include<intrins.h> 
" h6 @3 _$ P6 r6 @  j4 s//#include"basic.h" 
6 s! N: ^' }0 G/ ^0 ^* l) u" ltypedef unsigned char uint8; 
# P. J5 s0 @  E* {5 e" b, e4 Btypedef unsigned int uint16;+ }" q; l2 R  e% m/ k% g- Y; Y2 P- D 
#define ADC_FLAG    (1<<4)    /*ADC_中断标志*/1 @$ i4 Q6 L8 y: p1 P0 O# D 
/*放大128倍后的sin整数表(128)*/         
; i& \6 e, E- b0 }4 t& _code char SIN_TAB[128]={0,6,12,18,24,30,36,42,48,54,59,65,70,75,80,85,89,94,98,102, 1 P7 c1 w0 Y: | 
                        105,108,112,114,117,119,121,123,124,125,126,126,126,126,126, 
8 e" a3 g; S. V8 o# ~                                                125,124,123,121,119,117,114,112,108,105,102,98,94,89,85,80,75,' o) w* d  \4 r/ b- K 
                                                70,65,59,54,48,42,36,30,24,18,12,6,0,-6,-12,-18,-24,-30,-36,-42,( J5 {2 y$ D' |% O 
                                                -48,-54,-59,-65,-70,-75,-80,-85,-89,-94,-98,-102,-105,-108,-112, 
$ l1 s, ]0 T/ l. _) t5 p                                                -114,-117,-119,-121,-123,-124,-125,-126,-126,-126,-126,-126,-125, 
" }- a2 ]; e! ~/ h8 k( ^2 E6 c                                                -124,-123,-121,-119,-117,-114,-112,-108,-105,-102,-98,-94,-89,-85, 
, i% y% y6 P* d, |+ m                                                -80,-75,-70,-65,-59,-54,-48,-42,-36,-30,-24,-18,-12,-67 {4 k& v% g6 U$ h 
                                           }; 
9 n, [0 J% O7 U: {& h3 X- Z! O- B2 K. M$ w( s# r9 y 
 
0 L7 j" l' y6 P* C/*放大128倍后的cos整数表(128)*/) z( D, A9 p: I$ L. E0 N% P" h 
code char COS_TAB[128]={127,126,126,125,124,123,121,119,117,114,112,108,105,102,98,94,  
8 s- j9 V4 I1 S: K                        89,85,80,75,70,65,59,54,48,42,36,30,24,18,12,6,0,-6,-12,-18,-24,4 O3 Z/ P: n+ m0 h% T 
                                                -30,-36,-42,-48,-54,-59,-65,-70,-75,-80,-85,-89,-94,-98,-102,6 [( A, _7 j1 {' X8 z 
                                                -105,-108,-112,-114,-117,-119,-121,-123,-124,-125,-126,-126,-126, 
3 u+ {" l2 ]6 p: Q/ v6 ^! ~                                                -126,-126,-125,-124,-123,-121,-119,-117,-114,-112,-108,-105,-102, 
# F/ r  g5 B+ j" a                                                -98,-94,-89,-85,-80,-75,-70,-65,-59,-54,-48,-42,-36,-30,-24,-18, 
' v8 p1 E3 ]! }3 {0 }                                                -12,-6,0,6,12,18,24,30,36,42,48,54,59,65,70,75,80,85,89,94,98,102,3 d  s2 i8 |/ o4 @) ^ 
                                                105,108,112,114,117,119,121,123,124,125,126,126$ C" u. [  k9 [5 b) M3 Y* h3 K* I- C4 A 
                                           }; 
( p" V' z1 X. [) F( Y 
4 ?" b5 A( S, ~$ F9 x2 T8 X6 X 
; z4 N& f& `2 T' K/*采样存储序列表*/5 [2 n. [( A5 _/ l5 S, B 
code char LIST_TAB[128] = {0,64,32,96,16,80,48,112,8,72,40,104,24,88,56,120,4,68,36,100,20,84,52,116,1 H: a/ T4 b' O  S3 H 
                           12,76,44,108,28,92,60,124,2,66,34,98,18,82,50,114,10,74,42,106,26,90,58,. m  ^( p8 D. j; Z% j 
                                                   122,6,70,38,102,22,86,54,118,14,78,46,110,30,94,62,126,1,65,33,97,17,81,49,+ J" L* r/ u/ Z6 I8 {" k# f( n; x 
                                                   113,9,73,41,105,25,89,57,121,5,69,37,101,21,85,53,117,13,77,45,109,29,93,61,: D2 Q" k2 X: v) O" a4 a% i0 ^ 
                                                   125,3,67,35,99,19,83,51,115,11,75,43,107,27,91,59,123,7,71,39,103,23,87,55, 
) t: o- Z4 a8 o; D                                                   119,15,79,47,111,31,95,63,1274 I0 E5 f& v; f* F. [ 
                                                  }; 
8 R- ^/ ~3 ~. L; a% T7 l# z1 B& e8 j' d( Q9 Q) b% Q 
 
: x2 C$ f, j. ?0 K; b; _% O' i/*分级量化表*/$ |& Z, ?) B6 @ 
uint8 QTY_TAB[] = {0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; 
! K! x- o8 p1 X& ouint8 ADC_Count=0; 
! R4 ?  S' @& O! |uint8 i,j,k,b,p,anum;         
+ b7 F; J: m( }# J! H- [, Ruint16 xdata Fft_Real[128];  
# C9 l, P6 O% E" ~) y/ s9 Q/ |uint16 xdata Fft_Image[128];               // fft的虚部  
  s( U, f) p7 `$ U  x6 luint8 xdata LED_TAB[16];                                //记录红色柱状 
4 }0 t7 _3 k( y( v0 @1 M2 ]& ], ]6 Y  M/ N! b7 c7 L4 h 
) m/ {+ v+ j7 o( n 
/******************************************************************** 
6 H8 f( {9 J) S/ W3 S8 T  _% ^* 名称 : FFT 
& W) q0 N+ ^4 A9 N0 h, R1 a* j* 功能 : 碟型运算转换 
7 a2 ~% s" w0 }, M- H* 输入 : 无 
' v4 q8 e8 ?" W9 c* v' G, z- g0 C# ~$ ]* 输出 : 读出的值 
! x2 P, ?2 b  \& i7 s' a. q***********************************************************************/, q3 [0 n, F9 ^& F) H) v 
void FFT()//基2fft5 c" @: u2 Z* ^& `7 f0 z 
{                  
8 z; n6 Q# Y3 C) g& K; [: j, o, k# Q        uint16 Temp_Real,Temp_Imag,temp;                // 中间临时变量 
2 ~9 d- m4 `! r* `        uint16 TEMP1 = 0,max=0;' d( i4 r* E( U; ], I; D1 w 
        for( i=1; i<=7; i++)                            /* for(1) */' J/ }& P6 ~* B# ?' { 
        {  
( Q! O% x6 k# W6 T( `                b=1; 
! y$ R, L9 u7 n1 T' ?                b <<=(i-1);                                 //碟式运算,用于计算隔多少行计算例如 第一极 1和2行计算 
  A2 ~# `! ~: M- h; ~# f; f5 F& L9 u                for( j=0; j<=b-1; j++)                      /* for (2) */- A& j5 ~+ {! t8 o 
                { 9 X: I6 x, I, \4 u5 ?; n3 x 
                        p=1; 
  z% T& Y3 X! N* K                        p <<= (7-i);            3 m. G5 x0 ~. @ 
                        p = p*j; 
4 O0 {" K4 g5 s" r" g                        for( k=j; k<128; k=k+2*b)               /* for (3)  */ 
2 F+ |7 F, y0 S/ U' v                        { , J- d0 c, I% R# R7 h! O/ S1 ? 
                                Temp_Real=Fft_Real[k]; 
3 K3 h( m/ N% O                                Temp_Imag=Fft_Image[k]; 
5 d* ?5 C* U$ ~. M# Y                                temp=Fft_Real[k+b];7 a/ V8 }- U+ c4 A, h. T 
                                Fft_Real[k]=Fft_Real[k]+((Fft_Real[k+b]*COS_TAB[p])>>7)+((Fft_Image[k+b]*SIN_TAB[p])>>7); 
6 _) Z" m; m% B" Y; ~                                Fft_Image[k]=Fft_Image[k]-((Fft_Real[k+b]*SIN_TAB[p])>>7)+((Fft_Image[k+b]*COS_TAB[p])>>7); 
! }4 T$ R- ?% ?( z( c+ v8 k                                Fft_Real[k+b]=Temp_Real-((Fft_Real[k+b]*COS_TAB[p])>>7)-((Fft_Image[k+b]*SIN_TAB[p])>>7);) X8 L& _& F; z$ I; R. y, J 
                                Fft_Image[k+b]=Temp_Imag+((temp*SIN_TAB[p])>>7)-((Fft_Image[k+b]*COS_TAB[p])>>7);          // 移位.防止溢出. 结果已经是本值的 1/64               * ]) e% }) w) n. t$ Q 
                                Fft_Real[k] >>= 1;             ) p' N% |: C3 e 
                                Fft_Image[k] >>= 1; 0 G9 e: b' ]# x 
                                Fft_Real[k+b] >>= 1;                 . b$ o+ Q) K6 _9 L; G" t 
                                Fft_Image[k+b] >>= 1;                                                      5 e& R! M4 h' g1 u 
                        }      
9 T5 D; ~* v6 s8 X2 {                }  
- a* W$ E8 H( Y) H  I, U  `        }  
) Q0 O$ E4 I* o8 r8 n" n         
, v2 x3 L( f! d8 T" R        for(j=0;j<16;j++)//16分频                                                                                         % S, y) x# o1 e& q7 N 
        {                                                                                                                                                           
% D) x9 n4 ]' {, X5 L                TEMP1=((((Fft_Real[j+1]* Fft_Real[j+1]))+((Fft_Image[j+1]*Fft_Image[j+1])))>>1);//求各频段幅值 
* U! g- t* u" M. [4 c8 G                if(TEMP1<1)TEMP1=0; - T' g, f* M% [ 
                LED_TAB[j]=TEMP1;         
3 `9 E2 G$ i2 X$ A( f. o                if(LED_TAB[j]>max)max=LED_TAB[j]; 
' S) ^2 x- ^/ O: H9 p( B3 r  l( R        } 
; V! O; l6 }& i% W5 ]) P        if(max > 16)//分级量化6 m- ]. ?: q2 |# |/ ^/ C9 S 
        { 
( v" D! F0 s* {: e                max/=16; 
6 ?1 K$ n- Q2 N4 y                for(j=0;j<16;j++)LED_TAB[j]/=max; 
6 W0 |# A$ n* `        }        
5 \& \% l. S) v& z) D} 
2 x" p2 R) Y: }; h! i3 T, l 
! @$ E! u, w: j9 a$ o& r- q; T 
! a! w) [" _" ]- Y+ v/******************************************************************** 
0 E1 ^3 G8 \- S+ X4 Y* 名称 : GPIO_init 
! ^2 f; N, ^5 L0 q" V* 功能 : GPIO初始化 
. G) ?; N+ T, n! e8 @- q( ^7 d3 _* 输入 : 无9 F( m' p4 Z9 m8 h# r# b" R 
* 输出 : 读出的值- n9 V) ~' Z2 v 
***********************************************************************/: \& q# ]/ B( i$ H4 k8 I; t 
void GPIO_init()4 w$ f' k/ ~1 K/ N$ d# u, \" r 
{0 a1 b" v, _* v" @. o! | 
        P0M0 = 1; P0M1 = 0; P0 = 0XFF;    /*列*/ 
- }& B1 v* _0 o8 Q        P2M0 = 1; P2M1 = 0; P2 = 0XFF;, q; Y; N0 E5 h0 z 
        P3M0 = 1; P3M1 = 0; P3 = 0XFF;          /*行*/ 
) Q% O1 h% S# v} 
. h% m6 A# s1 }3 M* j/******************************************************************** 
3 x1 i% ^2 u4 A1 w9 a* 名称 : timer_Init 
2 a$ Y: K2 e& G) w7 M$ w# G* 功能 : 内部寄存器初始化3 b, F6 K! u: j2 A& r 
* 输入 : 无: }0 {) E' J0 ?. ^ 
* 输出 : 无% c# `4 c0 o) N; ^: k  `0 e" ?0 T1 g 
***********************************************************************/$ r) G! e7 w* @7 ~ 
void timer_Init()) |0 d5 S0 K' N4 a, M  |- X$ L& m 
{! U1 X4 @' U( ]8 b 
        TMOD = 0X12; 
7 r( V" g, D# m+ F        TH0 = 0xb0;                                                                   4 {" P7 D  M. Z6 K' F; }0 T 
        TL0 = 0xb0; 
1 r1 I" N3 m1 |; e        ET0 = 1;                                               //定时器0 打开6 h) V6 o5 |. B% ^  e9 W. _1 Q" g' d 
        TR0 = 0;                                                      //关闭定时器+ ^6 K: ], i6 B: R 
        TH1 = 0xfd;                                                                                                  
) l; f6 Z' [% Q: @4 q/ I        TL1 = 0Xa8; 
, G. C+ y- s5 a. p: f/ u3 n        ET1  = 1;( g, q' Q+ f" z  i; Q 
        TR1  = 1;         
2 M4 U* R4 ?2 g8 ~4 Z7 G0 Q        EA   = 1;        $ G  j  }1 _! P9 a/ ]8 R 
} 
3 @+ V4 D$ A9 q, B* `( H) d9 r# t/******************************************************************** 
. B+ b9 u* P) X* 名称 : adc_Init* K) v( ~4 f/ I* P6 g2 a 
* 功能 : 内部寄存器初始化& n+ g3 t9 u7 a! E4 {: a4 q. B  y1 `7 g 
* 输入 : 无% b; z; i! I8 k5 l" V 
* 输出 : 无! J; U/ o. w  {7 f 
***********************************************************************/ 
* p; ^! T9 M7 Y7 Y& Xvoid adc_Init() 
9 a$ [7 ^+ y' V{          + c# |" U4 o. W 
        ADC_CONTR = 0x80;             //ADC电源打开 
9 X5 o& s* d% \  g) p        _nop_();_nop_();_nop_();_nop_();% u# n( q0 o$ z- O" f: w 
        P1ASF = 0x01;                 //0000,0001, 将 P1.0 置成模拟口; U. E+ i. Y& ]- h- [$ \+ p; ? 
        AUXR1 &=0xFB;                 //1111,1011, 令 ADRJ=0 
7 k+ A# J5 e- R0 p' p        ADC_RES = 0x00;               //清零寄存器6 w. S/ y' V7 ?+ F4 L& c 
        ADC_RESL = 0x00; 
8 S1 |! W% ^* p0 A. t        EADC  = 1;                                          //AD中断打开; |* n2 Y4 u5 N& {5 {( ? 
        EA = 1;                                                  //总中断打开/ D, k2 i. V/ e; c 
}7 ~- ?- N+ [* t; _4 e- p! ^ 
* Y3 y: V$ |. x8 f2 ]+ g& Z# x6 E4 j3 h 
# ^7 b9 ]# m. c  A 
/********************************************************************* y3 d) k* X7 }+ `: r6 [ 
* 名称 : main 
+ Y: s" `( I- t0 W4 I, l$ Q* 功能 : 主程序# q, q3 s0 ?* V! {# e. c 
* 输入 : 无: b6 g7 ~" m( }/ Q( z; d. o 
* 输出 : 无4 |( H; L" S$ X7 T4 q 
***********************************************************************/* G5 g3 A3 ~) j1 G1 A) L8 {( a 
void main() 
  ~" F, i# Z/ v& N2 a( _1 u& ~* c% N{ 
* `/ {! W8 O2 F6 V& _! R9 n. r        uint8 i = 0;& x) J  u2 G6 H8 Q3 G- D2 P: l 
        GPIO_init();* b& N. b: @# _  z; W# U 
        timer_Init(); 
6 B/ V& g5 ]4 Z- l' `% v        adc_Init(); 
2 u: x5 g6 m  n6 `+ [        while(1)# T2 o9 d: P; u5 {# [3 M1 I% G 
        { 
' d7 \8 Z7 k& }$ b                ADC_Count = 0; 
6 y/ Y7 D( \0 K3 Z" N                EADC = 1; 
; f- g$ D2 I6 a9 O! o# n. {" z* u: T                TR0  = 1;9 u/ ?, z$ \" Z7 Q/ M1 u  J* m- c 
                while(ADC_Count < 128);       //满足128点 
5 T; Q; |' V9 B8 [6 C9 i                for(i=0; i<128; i++)                  //清除虚部 
1 p% G$ U2 ^; I* n# H6 C                { 
0 y; r5 a" S6 h3 o: S                        Fft_Image = 0; 
7 L& k3 h' N3 W/ ?2 H3 J- p3 Q                } 
) @( Y/ [/ M/ ^" H6 p1 }& A9 N& p                FFT();                        //FFT运算并转换为各频段幅值* H/ f; d' Y$ s5 X/ H! |0 L 
 
& H$ R! q! b7 e2 p: i! @/ _ 
! g+ ^& ^% i4 L  u        }. i7 ~' [/ i2 h/ |, i# j 
}% n" H6 |' V6 e- D4 G, Q8 E 
/********************************************************************: y5 ^# Y  K2 C 
* 名称 : ADC_Finish- ]. `6 g- D& ]/ J 
* 功能 : ADC转换完成中断服务2 j/ C2 {% V# W' N* l# r 
* 输入 : 无 
% C1 P' `! ~" j% k$ e" s* 输出 : 无: r. _- U0 I9 c% s% K 
***********************************************************************/ 
6 V0 e2 F; \( K5 Bvoid ADC_Finish() interrupt 5 
+ M5 \: ]0 R0 ~& l; W3 w  p{ 
2 z) c% {) i1 l" |3 `        Fft_Real[LIST_TAB[ADC_Count]] = (int)(((ADC_RES)<<1)+(ADC_RESL>>1)*2)>>3;    /*按LIST_TAB表顺序,进行存储采样值*/ 
6 k5 U$ W6 @+ p& L% `5 w        if(ADC_Count <= 127) 
4 _7 h) K. G% c2 f3 ^5 u        { 
: m9 p5 \: J% Z( W! v                ADC_Count++;           /*自动增量控制*/ 
/ P( i! v! ^( I4 Y- v                ADC_CONTR &= !ADC_FLAG; 
4 p  \7 _. K' g$ a. T1 D        } 
; R5 a9 Y: {( A; f' y" N* \& \; m        else 
) V* v# b1 R- n# m* d        { 
( m( d* f; I% `( Q& Z8 @1 v                EADC = 0;/ e+ V9 o, y. X. l, ^ 
                TR0  = 0;        ) }8 e6 A; M3 |3 _ 
        }                          B! w! P5 K0 J9 Y7 i 
}) U) H: i/ c2 U5 U) t& k( P. w% C 
/********************************************************************2 m9 @# D& M% ^% B0 o 
* 名称 : interrupt_timer1 
& C# f+ n. |: M; h& Q* 功能 : 显示屏幕刷新中断服务 
  N7 T8 ~9 m* n8 U9 `: g8 m! e$ E* 输入 : 无 
2 o' P0 u& n- Q3 W& W% @  B5 s* 输出 : 无 
( e/ B! g3 m7 P6 f***********************************************************************/' n& N, r5 ?7 Z: O 
void interrupt_timer1() interrupt 3 
0 ~$ J  |0 C3 L% z) l{        + N% B2 ^# Q" K: e  y2 g) k 
        static uint8 rec = 0;0 Z. I7 H" q& f# Q9 Q: k2 I0 s 
        TH1 = 0xfd;                                                                                                 9 y2 k% v7 c( q6 a 
        TL1 = 0Xa8;" Y$ @; I9 i) N$ g3 ?7 {4 N 
 
' C6 I5 @* X5 m 
% @: |/ }  B& o" Q- S4 h& x9 N, W        switch(rec)                                                                     //往点阵屏填充一列的数据 
+ F5 a) y5 T# d9 M        { 
. U' [  H0 j7 ~' X9 S! z6 g" B                case 0: P0 = QTY_TAB[LED_TAB[0]]; P2 = 0;break; 
; b" a  _+ A! D                case 1: P0 = QTY_TAB[LED_TAB[1]]; P2 = 1;break;                  
/ e7 E% K! ~* A/ q) m2 F                case 2: P0 = QTY_TAB[LED_TAB[2]]; P2 = 2;break;        0 u/ J8 E# F" U% y 
                case 3: P0 = QTY_TAB[LED_TAB[3]]; P2 = 3;break;        . X/ G8 M. I$ j7 {, h$ B 
                case 4: P0 = QTY_TAB[LED_TAB[4]]; P2 = 4;break;         
7 j7 `1 \- P) k, f                case 5: P0 = QTY_TAB[LED_TAB[5]]; P2 = 5;break;                " x; N1 v& k7 B  f/ } 
                case 6: P0 = QTY_TAB[LED_TAB[6]]; P2 = 6;break;        9 ^# }8 r. ~2 g* t- k# M7 E 
                case 7: P0 = QTY_TAB[LED_TAB[7]]; P2 = 7;break;9 M$ ~7 p/ D% ^' n/ T& [7 m 
                case 8: P0 = QTY_TAB[LED_TAB[8]]; P2 = 8;break; 
1 ~% ~7 g5 a3 x- m9 F                case 9: P0 = QTY_TAB[LED_TAB[9]]; P2 = 9;break;                 ) z2 n0 q" I! Y 
                case 10: P0 = QTY_TAB[LED_TAB[10]]; P2 = 10;break;        - W0 n0 a' v- T% `" g 
                case 11: P0 = QTY_TAB[LED_TAB[11]]; P2 = 11;break;         
* e9 I; V" f& Z4 \                case 12: P0 = QTY_TAB[LED_TAB[12]]; P2 = 12;break;        * w1 o7 h3 b' ^! |1 J5 B7 ^ 
                case 13: P0 = QTY_TAB[LED_TAB[13]]; P2 = 13;break;                 
# l* H. b4 R5 M" w8 O4 |                case 14: P0 = QTY_TAB[LED_TAB[14]]; P2 = 14;break;          S$ t8 P4 J0 [& r 
                case 15: P0 = QTY_TAB[LED_TAB[15]]; P2 = 15;break;                 
+ i9 s) A4 k% X: r                default:break; 
3 A9 N4 ~" g0 `& Y6 _" H        } 
" M/ f* }# d2 N# L/ i1 L& v        rec++; 
5 l) \. T" U  E+ g  x- m& [* ]        if(rec > 15) 
: n  [" p+ {2 ?; o        {& T. U5 ]- w  n, e 
                rec = 0; 
. R! }( c; g1 S0 V# m. f        } 
7 |! L% w& t0 \5 n7 V$ }6 U" \}, U& F3 h7 d0 l) ^' {6 L- z 
/******************************************************************** 
* P! |+ \' w) n4 |  @# |* 名称 : Ad_Control" E( d* A4 H9 J 
* 功能 : 控制采样率6 `" g% R0 O8 V, s 
* 输入 : 无. Q7 i5 D% k. N4 o: O' T2 a 
* 输出 : 无7 [- g4 G+ X) h3 l+ i6 n 
***********************************************************************/ 
! ]# w  ^. D; ]/ z! i+ uvoid Ad_Control() interrupt 19 L+ r* \+ p! Z3 B1 J: ] 
{, w* E7 t5 [2 @2 } 
        ADC_CONTR = 0xe8;                     //开始AD采集 
9 u' ?" y2 X/ c3 t  C        _nop_();_nop_();_nop_();_nop_();          
) j8 c+ s* q" [& f  r}  
/ ?4 z( T9 E7 C( H+ L& f8 l2 O3 e! @3 a# ^# C0 D4 ]" { 
 
  T6 o- {0 }; U( x. a' m# a3 X下载:  ]) C. x# ~1 Y. u 
 
3 e, T( ?7 p" M5 I' j( W; |# Z2 U* _4 S- b8 ~9 }' J 
 |   
 
 
 
 |