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

STM32心得:VS1053实验之RAM测试及正弦测试

[复制链接]
STMCU小助手 发布时间:2022-11-18 22:00
主要内容:
% k! G4 u5 ^) X4 Y1) 硬件连接;
+ L" e8 C3 G! d4 I# D6 J# ?2) VS1053简介;
$ _& ?4 B- I, a. t3 ?+ j( C9 A, H3) 相关实验及其代码解读。# X: n" F5 `* s3 s- q8 ?" Q4 R
实验功能:程序开启后,系统先进行RAM测试,再进行正弦测试,可以接耳机听到所设的单频声音。备注:音乐播放实验还未深入研究,本章内容不涉及。
8 m6 l8 [" S& K8 m0 j8 Y5 D. Y1 _
: W: q% ~- o( j% _4 h2 P& ~1 t硬件连接:如下图所示:" X$ t! C( f0 T; U2 T
* {& A) e, m/ @/ u( e3 o. h
20201025205213346.png 1 T/ `" M& T  }4 N
8 Q$ o9 B, M: F) M8 E; v
VS1053与STM32F103ZET6芯片的连接关系如下:& X2 c8 _# t9 d" p5 D4 x8 ~
1) VS_MISO→PA6;
3 G9 u' B  ]1 k2) VS_MOSI→PA7;  h! f+ [- t' a; R' m4 ?
3) VS_SCK→PA5;) v- Z. Z! k' Z0 i% C) w; X
4) VS_XCS→PF7;
5 ?' x5 A8 q. {+ R; S, h. N, h" }5) VS_XDCS→PF6;( n# S0 `  K' g4 \
6) VS_DREQ→PC13;# C" D) P* k# i! {6 T8 t
7) VS_RST→PE6。2 O6 I0 l5 y" d. s8 ~: V
备注:PA5/PA6/PA7,即:STM32的SPI1;SPK_CTRL,控制板载喇叭(输入到HT6872)!由程序控制。( M1 b  ~* u& V. i/ h2 s7 V
& `: Z! |  u/ f. `) {
1. VS1053简介& Y: K. R4 p  z0 X  v# K
1.1 VS1053是继VS1003后荷兰VLSI公司推出的又一款高性能编解码芯片。该芯片可对MP3/OGG/WMA/FLAC/WAV/AAC/MIDI等音频格式解码,同时还支持ADPCM/OGG等格式的编码,性能相对VS1003提升不少。& a* }5 {2 I6 @* V
VS1053拥有一个高性能的DSP处理器核VS_DSP,16K的指令RAM,0.5K的数据RAM,通过SPI控制,具有8个可用的通用IO口和一个串口,芯片内部还带了一个可变采样率的立体声ADC(支持咪头或线路输入)、一个高性能立体声DAC及音频耳机放大器。
1 v: g# ]1 B) G2 b- d, i5 q  \
: i) {1 e2 q) `, w$ W1.2 特点
- k$ \5 Y) C% |' a" Z8 `1) 支持OGG/MP3/WMA/WAV/FLAC(需加载patch)/MIDI/AAC等格式解码;  ]" |9 [9 F- L: p" s9 _
2) 支持OGG(需加载patch)/IMA ADPCM编码;
  }* z8 J  d! S0 M3) 支持音量调节、高低音控制和EarSpeaker空间效果;( t# \/ o  v9 y8 N/ @
4) 自带高性能立体声ADC和DAC,音质比VS 1003好很多;
) B) R, F9 Z6 Y; O9 f" x; y5) 自带耳机驱动器,可驱动30欧负载的耳机;
& a; D- a, ~! c- h6) 自带8个GPIO,可用于控制外设/作为I2S接口(外接DAC );8 ?2 I! x+ T6 C; G$ A2 M) s
7) 通过SPI接口控制/传输数据,接口简单;
- c! A, J. ~8 o8) 可通过加载patch,实现新功能添加;
  f- E. \$ K1 i" W+ X9) 低功耗 。
3 G: w8 T6 Q$ s8 V" K0 }, W* l5 U
9 w& O7 h) J% t; o+ u1.3 接口介绍( |5 G. J! |7 k3 R  z1 z& v! Q
VS1053通过SPI接口来接受输入的音频数据流,它可以是一个系统的从机,也可以作为独立的主机。本例程,我们把它当成从机使用。我们通过SPI口向VS1053不停的输入音频数据,它就会自动帮我们解码了,然后从输出通道输出音乐,这时我们接上耳机就能听到所播放的歌曲了。8 {  D4 |' S" F& \, P
VS1053通过7根线同MCU连接,如下:  r% ^4 J+ H, u" d9 N' h
VS_RST:VS1053的复位信号线,低电平有效;* H* Z* s: _/ f3 H3 g7 X3 \- r1 _/ [2 q
VS_DREQ:数据请求信号(高电平有效),用来通知主机,VS1053是否可以接收数据;
! [3 Y# R; t2 l, Y* \, [) LVS_XCS:命令片选(低电平有效);
" Z% ]- k+ a# a* @) Y" @( N7 @VS_XDCS:数据片选(低电平有效);- c. e5 {6 P3 s% |9 _7 R
VS_MISO、VS_MOSI和VS_SCK:SPI信号线。! |+ k/ Z4 z5 J( u4 G# o+ y' a

8 W; x6 j& n" U3 [/ y- Y. i1.4 VS1053工作模式
; z3 ^% }$ n2 Q* g# tVS1053的SPI支持两种工作模式:( L# k. U# n6 K3 z9 X& \
1,VS1002有效模式(即新模式);
9 Y3 L: ~* k1 b  F9 ]8 |2,VS1001兼容模式。
' j1 O& g3 E1 V这里仅介绍VS1002有效模式(此模式也是VS1053的默认模式)。在新模式下VS1053的SPI信号线功能描述如下表所示:' ^6 H2 B, C6 y( j* O( x

# E8 C) q# }# y 2020102520553924.png 8 Z/ p! [* |. }" L  F5 u

: L# t0 T8 U. u- l) _) ]9 cVS1053的SPI数据传送,分为SDI和SCI,分别用来传输数据/命令。SDI采用SPI协议,不过,数据传输受DREQ控制,主机在判断DREQ有效(高电平)之后,直接发送数据即可(一次可以发送32个字节)。
; u' e4 ]1 z1 D: }1 j8 r0 E
7 L: |# y1 a! ~( k3 q. U1 \9 [1.5 VS1053之SCI命令传输介绍9 h. A: f* g& B6 w
SCI串行总线命令接口包含了一个指令字节、一个地址字节和一个16位的数据字。读写操作可以读写单个寄存器,在SCK的上升沿读出数据位,所以主机必须在下降沿刷新数据。SCI的字节数据总是高位在前低位在后的。第一个字节指令字节,只有2个指令,也就是读和写,读为0X03,写为0X02。6 Y6 m' Q- g, r! M* Z6 }' X( S
SCI读时序如下图所示:2 D3 X% o8 n# b" e2 o2 k8 ~. ^
) M/ G" M, F+ P$ R# ~2 U) M
2020102520570422.png
" a! g" V) W" ^# U; a/ e
( b5 {& d" D9 m8 Q5 WSCI写时序如下图所示:% |' I! Q3 q6 d2 c( a
& ~8 q: z. k  S2 Y4 N
20201025205737881.png
( B/ i" b  v* s8 h) i
, s, Z" |7 J* R5 s, Z+ F写指令为:0X02,数据通过SI写入VS1053, SO则一直维持低电平。: u& d# \8 r( C' s8 \! _* _
注意:在读和写时序图中,DREQ信号上都产生了一个短暂的低脉冲,也就是执行时间,在写入和读出VS1053的数据之后,它需要一些时间来处理内部的事情,这段时间,是不允许外部打断的。所以,在SCI操作之前,最好判断一下DREQ是否为高电平,如果不是,则等待DREQ变为高。' s# z2 s* y1 }1 d

+ t( U' Z5 ^& F, h2. VS1053寄存器介绍' E/ F) ]: e0 _; J
2.1 VS1053的所有的SCI寄存器,如下表:+ u/ q$ F% f! I! C
) H, G, F% I* W5 s* o+ ?" ~9 N
20201025205924828.jpg , R+ J9 D) o2 J0 g9 ], Q  G

8 g$ i% k- _7 N# D& W! I# {. S2.2 MODE寄存器(0X00)
# ~+ z, @9 t! G$ r
8 T; B. z9 X3 s9 c7 b! y, Z$ ~2 r 20201025210013379.png ! V& H* J5 v% d

- D' \/ O( z7 }0 q, t, T+ s4 aSM_RESET:软件复位,建议在每播放一首歌曲之后,软复位一次。2 `5 X& W7 ^" k. H1 ^, d( O
SM_SDINEW:模式设置位,设置为1,选择VS1002新模式(本地模式)。
6 |+ ?) e  ]& W其他位的详细介绍,请参考:VS1053_cn.pdf。
* P4 q9 G3 {4 T) R% s8 S
- y2 L6 A1 D4 q- Q2.3 BASS寄存器(0X02)
1 N$ P) p8 e/ w3 c0 Q) G
( g: |! l: k; K  s& l% Z" ^ 20201025210115913.png + W4 t: U# i2 X$ [& p

) ]( y) d. R+ D4 N该寄存器可以用于设置VS1053的高低音效,通过这个寄存器以上位的一些设置,我们可以随意配置自己喜欢的音效(其实就是高低音的调节)。
3 J8 ]7 k* {1 @4 a" y注意:EarSpeaker效果由MODE寄存器控制。3 i/ d) [3 R  v* R# v- d6 E; c# b

6 O' y5 l$ \! X; w  s( C2.4 CLOCKF寄存器(0X03); w: b, V3 o. M4 o

) V" c% g; c7 A! f 20201025210211236.png
# o) G0 i/ N/ p" m. Z9 N$ N. O5 ^
8 e# O$ D- B8 k4 P3 i该寄存器用来设置时钟频率、倍频等相关信息。其中:SC_FREQ是以4Khz为步进的一个时钟寄存器,当外部时钟是12.288M的时候,设置为0即可。- v3 o/ p& Q3 c- I: C$ z5 g
XTALI是外部晶振的时钟频率(单位为:Hz )。CLKI是内部时钟频率。由于我们使用的是12.288M的晶振,在这里设置此寄存器的值为0X9800,也就是设置内部时钟频率为输入时钟频率的3倍,倍频增量为1.5倍(0X9800=1001 1000 0000 0000)。
& Q+ u# ]& z) [
  o* [# a6 _9 z6 A2.5 DECODE_TIME寄存器(0X04)3 l- L$ ^* N5 n2 l
该寄存器是一个存放解码时间的寄存器,以秒钟为单位,我们通过读取该寄存器的值,就可以得到解码时间。不过,它是一个累计时间,在每首歌播放之前,需要把它清空一下,以得到这首歌的准确解码时间。# ^$ [3 L# U  b( u9 X

, g9 e: d& c6 e1 H1 T+ m2.6 HDAT0&HDAT1寄存器(0X08&0X09)
9 q$ G. k5 a1 }- G这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。这两个寄存器的详细介绍,请参考:VS1053的数据手册(VS1053_cn.pdf)。, z! ^2 x; E3 w) K) E
6 f% p& P7 d5 c. O
2.7 VOL寄存器(0X0B)
3 a  i# D. P% x. Z9 j& v, W该寄存器用于控制VS1053的输出音量,该寄存器可以分别控制左右声道的音量,每个声道的控制范围为0~254,每个增量代表0.5db的衰减,所以该值越小,代表音量越大。比如设置为0X0000则音量最大,而设置为0XFEFE则音量最小。
4 W( g7 i3 V( |) s5 h3 F1 S5 W, q注意:如果设置VOL的值为0XFFFF,将使芯片进入掉电模式!3 M9 b8 I! \1 \$ `- u0 M7 j
/ B4 X7 c/ |9 q
3 VS1053初始化步骤9 K4 V, _: j1 s2 F* T/ |6 V" X- d8 v
1) 复位VS1053
3 _: \5 m7 a1 Y2 R" J9 L包括硬复位和软复位,让VS1053恢复初始状态,准备解码下一首歌曲。在每首歌曲播放之前都可以执行一次硬件复位和软件复位,以便更好的播放音乐。0 |0 L3 t/ `, M5 B( A2 E  a
2) 配置VS1053的相关寄存器% \3 b1 @: D$ U. m: |
这里配置的寄存器包括VS1053的模式寄存器(MODE)、时钟寄存器(CLOCKF)、音调寄存器(BASS)、音量寄存器(VOL)等。
* O0 j! A# |3 k* A2 k3 O/ Z5 D% Y) s$ D% \0 u9 H% F7 }# }) W
3) 发送音频数据
3 V- N4 [! \0 F" g3 b经过以上①、②配置以后,剩下来要做的事情,就是往VS1053里面发送音频数据,只要是VS1053支持的音频格式,直接往里面丢就可以了,VS1053会自动识别,并进行播放。不过,发送数据要在DREQ信号的控制下有序的进行,不能乱发。这个规则很简单:只要DREQ变高,就向VS1053发送32个字节。然后继续等待DREQ变高,直到音频数据发送完。
! b# V! i9 }& G2 a" F! n! s9 W5 f
4. 部分源码讲解: s2 @0 b3 \( h! r8 ~( l& R
4.1 VS1053低速2.25MHz,高速9MHz。5 ]; q4 J2 O8 l  S2 G9 W. c
& b3 m$ D7 M- V( q, f7 a0 q, C
  1. /*******************************************************************************
    ; e" N& Y9 \* e& `
  2. 函数名称:u8 VS_SPI_ReadWriteByte(u8 data)
    9 A  [/ s4 k$ C3 T7 E8 Y  N+ e
  3. 函数功能:读写数据,移植用         , `8 F1 O0 Z7 h1 U9 a6 |! ~  m
  4. 入口参数:u8 data:要写入的数据
      z$ N% d- t" e* [" S* A
  5. 返回参数:u8 读到的数据1 A% k8 s/ e  z! g6 Z2 R* p  E1 U
  6. 解读作者:Aaron
    , [/ B; J* s8 h
  7. ********************************************************************************/8 `8 l( r2 M7 a0 T9 i% o
  8. u8 VS_SPI_ReadWriteByte(u8 data)
    / C1 S5 j9 o+ Q0 c9 g$ E9 u: e
  9. {                             # p9 g' L8 m# o. G0 ^
  10.     return SPI1_ReadWriteByte(data);     
    " B, z& _$ Z) K" N, Q4 L
  11. }) T; @* d+ G1 ~! b/ Q; ~
  12. /* VS1053初始化时,需要低速 */  r+ }) J! h7 c' U# M, A1 @
  13. void VS_SPI_SpeedLow(void)
    , Z9 k# r5 |6 u6 h
  14. {                                                                    
    ; M0 [7 I! e% h# Q8 r/ [0 v
  15.     SPI1_SetSpeed(SPI_BaudRatePrescaler_32);     /* 设置低速模式,72/32≈2.25MHz */ $ ]; `( B; i  B: h& W" R) P; \
  16. }
    & D) G* F- V, E" _+ K: e
  17. /* VS1053正常工作时,可以高速 */  y  x9 ?* y- z5 w9 Z
  18. void VS_SPI_SpeedHigh(void)
    1 K4 {2 p4 o7 E! M8 [6 a# e6 s
  19. {                                                   
    ( S: N7 m3 l$ [+ f. b6 a) s7 J
  20.     SPI1_SetSpeed(SPI_BaudRatePrescaler_8);      /* 设置高速模式,72/8=9MHz */                . _& ~# O0 D0 n& z
  21. }
复制代码
$ O& J; q/ N- \7 V0 \) w4 l- G5 l
这么设置的原因如下表(VS1053芯片手册):
9 ^2 [, f  T; p) }+ h$ Z# q; g3 [+ L! E1 w5 L
20201025210704342.png + g) B$ Y9 t0 _

7 U7 F5 y. y# G0 T6 y) r4 }SPI读取操作时,速率为CLKI/7 MHz,在SCI和SDI写入操作时允许为CLKI/4MHz。CLKI值为3倍(本项目要求设置的)的晶振频率,即12.288×3=36.864MHz,那么CLKI/7<5MHz,CLKI/4<9.2MHz。因此低速时,2.25MHz满足5MHz要求,高速时,9MHz满足9.2MHz。  @4 }+ ?: X# J7 N0 Q
: |: W4 b  O" ]1 b# o5 p
5 相关实验代码解读2 j* c: s" t! N3 q- t
5.1 vs10xx.c部分代码(我修改了下)
- Z- y6 [3 @) Y8 q
5 F6 l0 x! {) g- q3 [
  1. /**********************************************************************
    # o' [4 u! ^" C& i
  2. 函数名称:VS_Init()
    . P# u  Q/ z* L6 @2 ?6 G
  3. 函数功能:初始化VS10XX的IO口  1 b- Y- Y6 L( x. v9 [
  4. 入口参数:无' E7 [7 L' E* B3 X; O5 h
  5. 返回参数:无2 x7 V' D8 F% R) B1 f( V
  6. 解读作者:Aaron
    ; }" N9 {; V6 Q) {
  7. ***********************************************************************/
    ' [" Z& g0 W" w. V
  8. void VS_Init(void)
    * G" z: p( @# Z1 W7 e" s6 S2 [8 g
  9. {+ @5 I; ~! [1 o7 l% E
  10. GPIO_InitTypeDef  GPIO_InitStructure;0 B0 V1 H7 E% s; d) A
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE);  /* 使能PC,PE,PF端口时钟 */( v2 [! j4 c4 m$ [
  12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;     - [( [9 v  w3 N. E" z* V$ @8 e
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          /* 上拉输入 */
    . |+ R5 Q; o; u5 t9 D, a) }+ t$ ]4 e
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    / K& L5 \% p8 j. O5 J( X
  15. GPIO_Init(GPIOC, &GPIO_InitStructure);                 /* 初始化PC13,对应VS_DREQ(数据请求信号) */, r- f+ ?$ [$ k" f
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
    3 V% ~* C1 B! W6 }* q9 o
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */3 ]( R, a( }* K) U
  18. GPIO_Init(GPIOE, &GPIO_InitStructure);                 /* 初始化PE6,对应复位信号线 */       3 `' G9 H3 v" O6 L  e; [
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;$ {- X: C3 H1 O' V) k
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 *// C& o; w1 r8 l! ], s. E
  21. GPIO_Init(GPIOF, &GPIO_InitStructure);                 /* 初始化PF6和PF7,对应VS_XDCS(数据片选)和VS_XCS(命令片选) */
    4 D& @6 |* J, R& d  F
  22. SPI1_Init();                                           /* 初始化SPI */, n1 m& h. _) o- f2 v0 o
  23. } 6 g1 |0 O0 ?0 g8 x: `  T! m

  24. : B: v0 r4 z2 L. ?; {. c
  25. /**********************************************************************( [# r5 Z. M( F9 ~0 }% g5 }; P
  26. 函数名称:VS_Sine_Test()6 [2 K6 H# u$ t+ b( S$ Q* Y/ Q$ D
  27. 函数功能:正弦测试   
    0 ?& f$ U0 M+ O. K( C" A5 ]
  28. 入口参数:无/ A/ D, n$ @$ b
  29. 返回参数:无
    6 `' m8 s" [9 I# ]6 ^
  30. 解读作者:Aaron
    6 S  j3 P# I1 B$ t+ ^
  31. ***********************************************************************/
    9 U/ G. f4 m6 |4 Q" ^* E+ N. }- v
  32. void VS_Sine_Test(void)
    9 L& `1 l! b# H% b' o" j
  33. {               7 z  V& e' Z, O3 M# L
  34. VS_HD_Reset();                /* 硬件复位 */
    + ?. G* A+ k9 B' P
  35. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */   P1 S/ ~' p6 G0 Y
  36. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     
    ! g/ ?8 U! m3 O4 \0 _
  37. while(VS_DQ==0);              /* 等待DREQ为高 */
      R8 T- a3 D" R, B2 Q
  38. printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE));
    " v# }- a( e7 a: g' ^
  39. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00 其中n = 0x28=0b00101000, 即FS=48000Hz,频率=48000*8/128=3000Hz  */
    ! p& \# d8 I5 p7 [% J7 D' D. J( O
  40. VS_SPI_SpeedLow();            /* 低速模式 */
    8 e, l1 ]5 @& m" h
  41. VS_XDCS=0;                    /* 选中数据传输 */
    ! N6 B  N( J. B* I
  42. VS_SPI_ReadWriteByte(0x53);) C/ T+ m3 K. k0 Q, s- i
  43. VS_SPI_ReadWriteByte(0xef);
    / v' e- F+ s0 e9 F, A3 E4 K1 N0 @
  44. VS_SPI_ReadWriteByte(0x6e);
    , B1 _- w6 a2 ~( y# }
  45. VS_SPI_ReadWriteByte(0x28);
    9 X, A) s3 ?. y, D2 [7 `, J
  46. VS_SPI_ReadWriteByte(0x00);% C( h) c6 d8 [
  47. VS_SPI_ReadWriteByte(0x00);
    6 [" i  x9 U( }4 o
  48. VS_SPI_ReadWriteByte(0x00);
    + Z4 t5 ]% v/ M( O- o
  49. VS_SPI_ReadWriteByte(0x00);
    9 M  V# d! i; b; u0 ^+ x
  50. delay_ms(200);                /* 测试经验告诉我,延迟时间不能超过1s */% Q0 X* o- Z" I8 D6 V2 B) R
  51. VS_XDCS=1;
    * ]* O7 b. F; L% \
  52. /* 退出正弦测试 */& N! O  g7 ^* V: y4 J* Z; V5 A- \
  53. VS_XDCS=0;                    /* 选中数据传输 */* I9 B. t9 U* T2 R- R% D- V+ m3 ^+ N
  54. VS_SPI_ReadWriteByte(0x45);
    0 r  Z* }8 ]7 n% i; J+ T
  55. VS_SPI_ReadWriteByte(0x78);
    8 l' p8 K* h0 M; o) {" z
  56. VS_SPI_ReadWriteByte(0x69);/ k! G$ Q# X+ H
  57. VS_SPI_ReadWriteByte(0x74);
    , j6 D/ P; z9 r5 S, D) z/ d
  58. VS_SPI_ReadWriteByte(0x00);
    " k7 o. l  _$ c2 e3 P; @. E/ Q* p' }
  59. VS_SPI_ReadWriteByte(0x00);
    5 A7 _8 y) P  r( v% O- m: W7 A
  60. VS_SPI_ReadWriteByte(0x00);+ I% @2 A# T* n' D2 i- g
  61. VS_SPI_ReadWriteByte(0x00);0 z+ q) O- u8 W5 {8 G* C
  62. delay_ms(100);
    $ K+ {. ^7 k+ J5 u0 [% f1 N
  63. VS_XDCS=1;   
    6 n) K1 Z& i% H1 I
  64. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00其 中n = 0x22=0b001 00010, 即FS=48000Hz,频率=48000*2/128=750Hz  */
    0 q( E1 j% I( s- v
  65. VS_HD_Reset();                /* 硬件复位 */
    4 v3 ]% i3 j+ B+ v4 Z, g; R
  66. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */
    ; P1 r$ Z, Z4 w; ~( j! q( W
  67. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     2 w* n4 @; H$ k3 i
  68. while(VS_DQ==0);              /* 等待DREQ为高 */
    9 v4 \5 m9 A  N
  69. VS_SPI_SpeedLow();            /* 低速模式 */# e9 F: u; }+ U& L* U) A
  70. VS_XDCS=0;                    /* 选中数据传输 */      
    . Z4 j* V- A& R( o2 W) i; O
  71. VS_SPI_ReadWriteByte(0x53);
    - T$ x/ L' o4 D1 n" }- y$ E2 T
  72. VS_SPI_ReadWriteByte(0xef);. S' k) B3 e2 N- n( H6 y  f* f
  73. VS_SPI_ReadWriteByte(0x6e);
    - W1 E: n8 {+ N# z6 e
  74. VS_SPI_ReadWriteByte(0x22);
      G$ M% m' t- l# e: z7 Z# F/ t
  75. VS_SPI_ReadWriteByte(0x00);! }# D- ~. v) r
  76. VS_SPI_ReadWriteByte(0x00);
    # q  D+ c( v, z
  77. VS_SPI_ReadWriteByte(0x00);2 C# m' h6 W9 t  J4 V5 i8 i+ t1 I
  78. VS_SPI_ReadWriteByte(0x00);3 Z- O7 t- [. L  J9 Z
  79. delay_ms(400);6 V/ }9 \9 H) \; G( J# c
  80. VS_XDCS=1;. E! K) d7 N7 b, i1 `/ N7 s
  81. /* 退出正弦测试 */( O6 v5 m& M# v# @/ T
  82. VS_XDCS=0;                    /* 选中数据传输 */( N" J7 |% I/ `
  83. VS_SPI_ReadWriteByte(0x45);/ S1 ^3 Q5 e5 L; u  O/ A5 S
  84. VS_SPI_ReadWriteByte(0x78);
    4 o1 h, l/ s: r5 K2 T
  85. VS_SPI_ReadWriteByte(0x69);, m/ N8 d/ j, o0 p+ Z: ^, e' O
  86. VS_SPI_ReadWriteByte(0x74);, Q& e2 J% N1 K& A
  87. VS_SPI_ReadWriteByte(0x00);
      L4 g5 q) a6 y3 S
  88. VS_SPI_ReadWriteByte(0x00);
    2 Q! J- r: y, q: x8 H4 s, ^
  89. VS_SPI_ReadWriteByte(0x00);
    - A1 z0 o) g" ^1 \9 S7 H
  90. VS_SPI_ReadWriteByte(0x00);0 B$ l5 W  Q9 r( t5 F. W8 l
  91. delay_ms(100);
    ' G) _( N0 ~* T5 G7 }
  92. VS_XDCS=1;  ( U9 }; \& r5 }0 x$ ~6 x
  93. }) }  h( z, C5 B, c

  94. ' O# i4 K% k/ K. R3 V3 t6 `* v" j: f
  95. /**********************************************************************
    . Z; w+ {8 {( V! |  A
  96. 函数名称:u16 VS_Ram_Test()$ @0 X/ y! p# H) z* t/ M
  97. 函数功能:RAM测试 ! c) j2 y( a! U
  98. 入口参数:无
    & c+ S4 B1 r& b" J( x
  99. 返回参数:u16 RAM测试结果,VS1003若得到0x807F,则表明完好,VS1053则为0X83FF
    * i+ {- I& W/ G5 q9 u/ w. R
  100. 解读作者:Aaron# N& ~% D' w! K
  101. ***********************************************************************/0 x0 z4 [; \9 p+ W, E( }
  102. u16 VS_Ram_Test(void)
    3 ~+ A- `' j/ B# o# U
  103. {
    8 |; v, L7 n  N( _" `
  104. VS_HD_Reset();                /* 硬件复位 */ ( P) \! ?3 x% \$ F  T( V$ k
  105. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式 */7 g0 ^; R* c+ W- G$ _
  106. while (VS_DQ==0);             /* 等待DREQ为高 */      
    - B9 F  ]. g1 [5 z$ F
  107. VS_SPI_SpeedLow();            /* 低速 */ ! f- W, I; [5 e8 _, Y2 S- ^
  108. VS_XDCS=0;                    /* xDCS = 1,选择VS10XX的数据接口 *// b( I* `3 Z$ G% {& Q0 i
  109. VS_SPI_ReadWriteByte(0x4d);
    8 Z) v. h) k6 J# z5 ~
  110. VS_SPI_ReadWriteByte(0xea);
    ; ]# ]% I: @! K1 \' ?4 B8 @
  111. VS_SPI_ReadWriteByte(0x6d);
    / j3 a' ]  O7 K5 t" t3 f1 Y- P) v4 L
  112. VS_SPI_ReadWriteByte(0x54);
    % C! \* V2 M. L% p! B
  113. VS_SPI_ReadWriteByte(0x00);) _6 }- Z# x5 V9 |* F* _
  114. VS_SPI_ReadWriteByte(0x00);% O' z$ V* V- Q/ o' s) s
  115. VS_SPI_ReadWriteByte(0x00);0 `- C2 b% ^: }; i
  116. VS_SPI_ReadWriteByte(0x00);9 b0 A2 K  C5 \9 Z. x+ j
  117. delay_ms(150);  
    * q4 \$ `/ [/ l6 s$ Z4 L3 ?0 J5 \
  118. VS_XDCS=1;
    / @' X, k7 C5 p6 \* i5 H( W; d5 K
  119. return VS_RD_Reg(SPI_HDAT0);  /* VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF */      
    , [- [3 C9 F+ v  c
  120. }
复制代码

* Y' n+ t. D1 q/ i% ]0 \2 O) n5.2 main.c主函数代码解读2 i+ a* T* d! M5 d. S% P+ C

& p  t$ R6 j( ^; |0 K
  1. /************************************************
    / y- X$ b& \5 F& k! o
  2. 函数名称:int main()" }9 s4 l$ f9 y
  3. 函数功能:主函数
    % ~4 v' U; b  p0 I+ R
  4. 入口参数:无, s/ d* M' W8 p/ Z+ A
  5. 返回参数:int9 Y9 |5 M& j0 a$ U3 E
  6. 解读作者:Aaron
    * m- M; \6 _6 Q' p% z7 I5 w- C
  7. *************************************************/
      u" `. [* q3 x) Z
  8. int main(void)
    + L: X! A4 n$ z# Y& `0 e
  9. {  3 P( A. L4 u, O  t% ?8 `) q: x! V' z% v
  10.   delay_init();                                   
    3 H% e) `+ a. b( ~* ?" _
  11.   NVIC_Configuration();
    + H) H5 s+ b! I$ j' I2 c
  12.   LED_Init();      
    ! W& N$ x% i" }# M6 E, u
  13.   KEY_Init();
    : u) a1 [# B1 R8 S% e
  14.   My_USART1_Init();   6 D6 E0 P+ y+ `- I* Y. L& a- p
  15.   VS_Init();           /* 包含对SPI1初始化 */
    0 C2 m4 c3 W7 y" P$ V
  16.   printf("存储器测试:%d\r\n",VS_Ram_Test());
    1 j6 a/ u/ y/ f" K3 O. j0 h
  17.   while(1)
    4 n/ i$ _% l5 h( c& d
  18.   {
    , i. k# r* `/ W9 t2 y3 S% U  F3 q
  19.    DS0=0;        
      b% j+ z! @3 z" L5 B  |* y
  20.    printf("开始播放单频信号\r\n");
    1 f) a8 C9 A" R- C+ F* b
  21.    VS_Sine_Test();   
    ( ^- D, Z! o" r- o' c* S( k) k
  22.    delay_ms(1000);  % L; Z8 n# }4 o3 p
  23.    DS0=1;
    & l% X/ J& K( W" H
  24.    delay_ms(1000);  
    * x" Q3 U7 ?3 l% I+ u( j
  25.   }                   + O$ M% t( f5 _5 w& _
  26. }6 n$ H$ j+ n$ s! l& N" r% V
复制代码
  y# P* ]& K0 s6 _* W
实验结果
3 I# _( }! e2 D7 Q9 k$ Q! w接上耳机,能听到200ms的3000Hz单频声,然后紧接着听到400ms的750Hz单频声。( }+ }- M/ s2 C
: r6 n; e; K" A, {" V
20201025211948294.jpg 6 w/ I# o& e. z! X. q+ K

+ Y' x9 w8 H; m" D- z————————————————
! U$ a8 m3 C# j, Y! ?+ D版权声明:天亮继续睡
0 }1 |0 E9 `( q% b  h- d" [9 h2 U" V1 Q% C
% m( @. c9 Y6 ~2 B9 O
赞 收藏 评论0 发布时间:2022-11-18 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版