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

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

[复制链接]
STMCU小助手 发布时间:2022-11-18 22:00
主要内容:
! \- A" }2 y) W  t1) 硬件连接;  n! C2 E. k3 t/ Y# f5 ~& h
2) VS1053简介;
( ~9 D/ _3 R- h- s$ m+ D- P3) 相关实验及其代码解读。
% N) U0 j7 ~9 M! n7 d2 E3 ?5 Z实验功能:程序开启后,系统先进行RAM测试,再进行正弦测试,可以接耳机听到所设的单频声音。备注:音乐播放实验还未深入研究,本章内容不涉及。+ ]7 l" J5 Y0 b4 j6 d

. X, C8 g/ g$ I3 P. k: w" {% b2 L硬件连接:如下图所示:
% Z! v7 C. P  F1 A! \0 m: q
" D; E$ g+ a7 {0 h 20201025205213346.png 5 x8 M7 R9 }" |* ]$ V: i# S, |
6 B. `) B2 {' h% v: z
VS1053与STM32F103ZET6芯片的连接关系如下:  g* R3 _  X- @* Y! w0 y
1) VS_MISO→PA6;
4 S# ~, S( R; g1 b- A! T2) VS_MOSI→PA7;5 x# w  k" S2 L) T4 p& [  U& t2 u- O
3) VS_SCK→PA5;) L1 _: i- s$ ~. l5 l! W7 o
4) VS_XCS→PF7;1 c( F) [( p* s% o3 d; N  b8 c
5) VS_XDCS→PF6;
. C" V$ I/ {0 D1 a  B- i" k# s6) VS_DREQ→PC13;
8 _5 i2 N5 C" M" \7) VS_RST→PE6。' X: h; R; T7 B/ f. [. |
备注:PA5/PA6/PA7,即:STM32的SPI1;SPK_CTRL,控制板载喇叭(输入到HT6872)!由程序控制。
" K( x: L6 \% P
! c( B/ _/ R2 s% l1. VS1053简介# n( X" F* t4 P" G2 {6 m+ ^% ?1 `
1.1 VS1053是继VS1003后荷兰VLSI公司推出的又一款高性能编解码芯片。该芯片可对MP3/OGG/WMA/FLAC/WAV/AAC/MIDI等音频格式解码,同时还支持ADPCM/OGG等格式的编码,性能相对VS1003提升不少。
: m( b: s) I0 p% d% b  u: _0 Q* GVS1053拥有一个高性能的DSP处理器核VS_DSP,16K的指令RAM,0.5K的数据RAM,通过SPI控制,具有8个可用的通用IO口和一个串口,芯片内部还带了一个可变采样率的立体声ADC(支持咪头或线路输入)、一个高性能立体声DAC及音频耳机放大器。
9 _3 B. a3 s5 A/ n3 J; p  t
# r5 ^/ H& {# J1.2 特点
: e7 i( ]5 J3 ?" b( w7 f8 K2 l1) 支持OGG/MP3/WMA/WAV/FLAC(需加载patch)/MIDI/AAC等格式解码;$ ?' I" o1 X. |8 N$ ~; y
2) 支持OGG(需加载patch)/IMA ADPCM编码;
* K( f1 W+ @) n- G4 B6 g7 E3) 支持音量调节、高低音控制和EarSpeaker空间效果;
" @- G' @$ A" E0 Y4) 自带高性能立体声ADC和DAC,音质比VS 1003好很多;
  t8 `' M  g% j. d5 Q- |5) 自带耳机驱动器,可驱动30欧负载的耳机;$ z3 y4 r" |9 S8 z8 O2 u7 m
6) 自带8个GPIO,可用于控制外设/作为I2S接口(外接DAC );, I8 \, c/ m0 N
7) 通过SPI接口控制/传输数据,接口简单;
& ?0 m4 Q$ F. x8) 可通过加载patch,实现新功能添加;' j" a5 X) B- R' d9 t; A" [6 ~# w
9) 低功耗 。
3 K! w) l8 I' r7 I# K+ S9 Z9 m. A# S  V" R
1.3 接口介绍: E* H5 W5 I/ Q7 o$ c
VS1053通过SPI接口来接受输入的音频数据流,它可以是一个系统的从机,也可以作为独立的主机。本例程,我们把它当成从机使用。我们通过SPI口向VS1053不停的输入音频数据,它就会自动帮我们解码了,然后从输出通道输出音乐,这时我们接上耳机就能听到所播放的歌曲了。
7 ?' G7 _% \" l* ^VS1053通过7根线同MCU连接,如下:
1 A3 a# C( J, B  QVS_RST:VS1053的复位信号线,低电平有效;
; y3 Y0 k( ~. r1 E+ pVS_DREQ:数据请求信号(高电平有效),用来通知主机,VS1053是否可以接收数据;! x  k9 [) s. W
VS_XCS:命令片选(低电平有效);
1 p, n& T0 z5 Q' TVS_XDCS:数据片选(低电平有效);$ n$ M7 q8 [  }$ D
VS_MISO、VS_MOSI和VS_SCK:SPI信号线。
& l5 r  b6 J+ J3 ?1 Q/ L% g/ O4 Z8 r' A% `, R9 W1 b; i2 _& ]
1.4 VS1053工作模式  [. X5 _$ K2 q! x  J$ z
VS1053的SPI支持两种工作模式:
9 }! o4 h8 e0 a7 {' A7 q1,VS1002有效模式(即新模式);
) L) _" H! y0 p$ p6 E2,VS1001兼容模式。
3 p' s& f9 k. f5 e" E$ F. n8 Z: W- t这里仅介绍VS1002有效模式(此模式也是VS1053的默认模式)。在新模式下VS1053的SPI信号线功能描述如下表所示:) R/ h+ ~. Z+ r# I& [7 a' d( o

) X3 c5 `, A6 w8 m- s! C 2020102520553924.png 4 ?: ]% E1 _& K0 W- e- D4 `! `
8 X6 S/ x/ @/ T8 v! c8 K' A
VS1053的SPI数据传送,分为SDI和SCI,分别用来传输数据/命令。SDI采用SPI协议,不过,数据传输受DREQ控制,主机在判断DREQ有效(高电平)之后,直接发送数据即可(一次可以发送32个字节)。
# G( F% q; r4 |& c# I/ e) C2 t# X; r' v, ]8 z! A
1.5 VS1053之SCI命令传输介绍2 x3 C2 T7 m+ U9 j  T- A
SCI串行总线命令接口包含了一个指令字节、一个地址字节和一个16位的数据字。读写操作可以读写单个寄存器,在SCK的上升沿读出数据位,所以主机必须在下降沿刷新数据。SCI的字节数据总是高位在前低位在后的。第一个字节指令字节,只有2个指令,也就是读和写,读为0X03,写为0X02。
- q$ |% k+ Q' P- ^7 ESCI读时序如下图所示:
0 V. r$ k& E+ o2 B1 ]6 d
1 G! X1 ]9 L: Z6 b3 j) Y4 w 2020102520570422.png
+ k8 w; \' a8 b% H
  v, y' E% V% m, J  USCI写时序如下图所示:
2 J! D" E0 P, O4 u9 u2 c7 n2 F+ b, h
# C! R' A$ a' H# f' i1 l7 y& v8 T 20201025205737881.png : n' N; b, k4 f5 O# S1 ~
) B0 k4 _$ V9 ^9 H5 \
写指令为:0X02,数据通过SI写入VS1053, SO则一直维持低电平。
+ ~; G+ H9 U" b$ X* H$ U注意:在读和写时序图中,DREQ信号上都产生了一个短暂的低脉冲,也就是执行时间,在写入和读出VS1053的数据之后,它需要一些时间来处理内部的事情,这段时间,是不允许外部打断的。所以,在SCI操作之前,最好判断一下DREQ是否为高电平,如果不是,则等待DREQ变为高。
3 U9 \+ F: U* [3 t& K. M' y" v/ o" ~7 t5 J( F
2. VS1053寄存器介绍/ R6 B# ^  d7 @4 ]' V& I  q( L
2.1 VS1053的所有的SCI寄存器,如下表:) `$ J8 w" z* k4 k* y

0 l! `- S  d" L" G2 A 20201025205924828.jpg ; M9 S7 U+ t' c; Y

+ H& c/ V% `) a2.2 MODE寄存器(0X00)
/ Y# q# G) S& G$ }, ~% m
9 Z( U9 W. v1 M2 h, l3 E5 n 20201025210013379.png ! m5 I' O! U! b! q7 K3 H
& K$ b( |( }! X4 J
SM_RESET:软件复位,建议在每播放一首歌曲之后,软复位一次。
4 g) e3 Y; m1 s* }% o% OSM_SDINEW:模式设置位,设置为1,选择VS1002新模式(本地模式)。
# T* l# w5 I& |其他位的详细介绍,请参考:VS1053_cn.pdf。
$ Z2 x' {' n" p1 |  |4 x, F3 H
2.3 BASS寄存器(0X02)+ W8 e/ m8 Y% v+ b* R7 \
7 l; Y/ J! ]( H) r- G. @$ N7 B
20201025210115913.png
1 s2 h. V( g$ N. M. L  S! ]5 N4 u0 }% U/ _  Y1 q$ R0 U
该寄存器可以用于设置VS1053的高低音效,通过这个寄存器以上位的一些设置,我们可以随意配置自己喜欢的音效(其实就是高低音的调节)。& d  }$ ~; e( `  e7 x
注意:EarSpeaker效果由MODE寄存器控制。& M/ M2 q9 S* M* _4 x  N$ m3 Q
2 z- v$ O& _- J' U4 m: |& {" C8 f
2.4 CLOCKF寄存器(0X03)) W! O0 _( j( {, s

2 N0 g6 v) @+ K& h; p7 | 20201025210211236.png : S; i( @/ l  n" a, P+ I- ^
: k' [( z9 p" _3 t+ \
该寄存器用来设置时钟频率、倍频等相关信息。其中:SC_FREQ是以4Khz为步进的一个时钟寄存器,当外部时钟是12.288M的时候,设置为0即可。) E" p# j3 F: F- r* M% c) q
XTALI是外部晶振的时钟频率(单位为:Hz )。CLKI是内部时钟频率。由于我们使用的是12.288M的晶振,在这里设置此寄存器的值为0X9800,也就是设置内部时钟频率为输入时钟频率的3倍,倍频增量为1.5倍(0X9800=1001 1000 0000 0000)。
9 e3 b; N" T/ a" R% C  ?: X9 N$ M- {% x6 `
2.5 DECODE_TIME寄存器(0X04)
1 U3 S2 i, A0 s该寄存器是一个存放解码时间的寄存器,以秒钟为单位,我们通过读取该寄存器的值,就可以得到解码时间。不过,它是一个累计时间,在每首歌播放之前,需要把它清空一下,以得到这首歌的准确解码时间。
4 ~  \$ h; F5 K' v
& M7 t3 Q& g1 n" [0 A2.6 HDAT0&HDAT1寄存器(0X08&0X09)7 u3 p- e- F- N' F
这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。这两个寄存器的详细介绍,请参考:VS1053的数据手册(VS1053_cn.pdf)。8 J1 f% L) [9 }/ U
/ g: ]) `2 n0 U
2.7 VOL寄存器(0X0B)
# h0 n" u+ {+ Q* D5 }4 c5 O1 Q该寄存器用于控制VS1053的输出音量,该寄存器可以分别控制左右声道的音量,每个声道的控制范围为0~254,每个增量代表0.5db的衰减,所以该值越小,代表音量越大。比如设置为0X0000则音量最大,而设置为0XFEFE则音量最小。
( x  V0 F. H* ~1 Q' y注意:如果设置VOL的值为0XFFFF,将使芯片进入掉电模式!
" C. U- L8 a/ g" N: ?* b' o3 h. y+ N& A5 Y- K0 W+ `9 n
3 VS1053初始化步骤
( w) A. P, x# e. b1) 复位VS1053
. V8 O2 E% r! o包括硬复位和软复位,让VS1053恢复初始状态,准备解码下一首歌曲。在每首歌曲播放之前都可以执行一次硬件复位和软件复位,以便更好的播放音乐。
# l# U& u( P, [7 z! G4 z, V2) 配置VS1053的相关寄存器3 {0 J- M1 c7 N; W6 c
这里配置的寄存器包括VS1053的模式寄存器(MODE)、时钟寄存器(CLOCKF)、音调寄存器(BASS)、音量寄存器(VOL)等。/ o( C7 p2 ]: \2 t9 ~

9 n1 o* X7 }! U3 y  v9 [3 _3) 发送音频数据! Y& z) e1 b1 l0 \# h
经过以上①、②配置以后,剩下来要做的事情,就是往VS1053里面发送音频数据,只要是VS1053支持的音频格式,直接往里面丢就可以了,VS1053会自动识别,并进行播放。不过,发送数据要在DREQ信号的控制下有序的进行,不能乱发。这个规则很简单:只要DREQ变高,就向VS1053发送32个字节。然后继续等待DREQ变高,直到音频数据发送完。/ Z* f+ ^- h. J: f; G

. {5 F) Y8 K" z6 ^/ I( X5 D- |4. 部分源码讲解& d& c# h  v$ {
4.1 VS1053低速2.25MHz,高速9MHz。9 f/ w* i/ o  E6 Y. T
5 K, ~$ e: M5 n% K5 ~4 ~* v/ S
  1. /*******************************************************************************
    , r% X$ }. N2 q- Q
  2. 函数名称:u8 VS_SPI_ReadWriteByte(u8 data)
    , W1 j- h& F& m  G1 W6 p
  3. 函数功能:读写数据,移植用         , |) s1 Q  Y" A: E  i4 I
  4. 入口参数:u8 data:要写入的数据% @6 D: c& m7 E& r
  5. 返回参数:u8 读到的数据
    - m4 Q. g* X3 S4 s
  6. 解读作者:Aaron
    # O# A) z& w; H$ h
  7. ********************************************************************************/2 [% i6 c' n& i! J# B
  8. u8 VS_SPI_ReadWriteByte(u8 data)
    0 `$ z3 S( w& r' b% X: e  s
  9. {                             * Z' T: P8 t% _
  10.     return SPI1_ReadWriteByte(data);     " b. V; l4 V1 q% C
  11. }3 F, W1 t( k+ w( R) I: K
  12. /* VS1053初始化时,需要低速 */+ V* ?$ G$ }: m) |2 K  N# w6 I
  13. void VS_SPI_SpeedLow(void)9 J4 H; R; S' U. y8 V( ^
  14. {                                                                    
    ) d7 h3 i# r' W& g
  15.     SPI1_SetSpeed(SPI_BaudRatePrescaler_32);     /* 设置低速模式,72/32≈2.25MHz */ * Z( R3 n2 H9 C5 O
  16. }
    $ t% B& F3 K7 h5 l2 ^
  17. /* VS1053正常工作时,可以高速 */1 r5 w( ~9 |5 u9 }- V; I& W
  18. void VS_SPI_SpeedHigh(void), T0 v3 h% Q* h' ~
  19. {                                                   
    ! U5 F! [9 J+ e0 l9 f
  20.     SPI1_SetSpeed(SPI_BaudRatePrescaler_8);      /* 设置高速模式,72/8=9MHz */                9 ]" E) m7 R" p! ]
  21. }
复制代码
: |9 M( @9 w. w" F$ N3 p. f4 l$ t
这么设置的原因如下表(VS1053芯片手册):
6 K6 D$ P: A  ]  R
; E! q. A- V) b' m 20201025210704342.png
7 Y0 Q# \. o9 |- I$ ^* f9 u  K* S. \
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。9 t$ j8 |/ ]  [# [- U
1 O+ Y% L% L' q  Q0 K" P8 B
5 相关实验代码解读: ?7 g% O) l3 K( v
5.1 vs10xx.c部分代码(我修改了下)
) ~$ ~9 R6 F( J: [  z+ m) _4 ]2 C; o. u
  1. /**********************************************************************, }8 x/ d) W$ X& i6 m
  2. 函数名称:VS_Init()
      q  P8 _3 [: R5 p! M0 h
  3. 函数功能:初始化VS10XX的IO口  
    $ B$ y0 X! _; l( ~3 C. y: Z9 Z
  4. 入口参数:无8 B$ n* j1 N6 g* l/ r  M; z
  5. 返回参数:无: }. b, l3 C/ l; e7 i% T+ e
  6. 解读作者:Aaron/ S/ m1 l) A  U$ p4 d  J
  7. ***********************************************************************/
    / E1 f7 t+ Y" S) Z
  8. void VS_Init(void)
    4 j# c4 _$ c8 R( ?* q. J
  9. {
    ! |* E& D4 F6 x* `  n
  10. GPIO_InitTypeDef  GPIO_InitStructure;* ?$ z( s+ f8 T  U
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE);  /* 使能PC,PE,PF端口时钟 */
    , r0 |" K" T! ^: f' p0 }% x
  12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;     9 F! J  U* W: d+ c) j
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          /* 上拉输入 */9 w# ]/ }1 Y! L7 [' y7 M) O  N
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;8 Q1 ]1 p& E% [' }- a( Y3 \
  15. GPIO_Init(GPIOC, &GPIO_InitStructure);                 /* 初始化PC13,对应VS_DREQ(数据请求信号) */
    ' c# Z7 i' H, x
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
    2 ^8 P  a& K! O+ c. [, x' E4 `
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */4 T2 l! C3 [! G- h
  18. GPIO_Init(GPIOE, &GPIO_InitStructure);                 /* 初始化PE6,对应复位信号线 */      
    : _1 y9 r- N0 \
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    / l& v1 K4 `5 q! w" ]$ Z7 z) W
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */
    , x9 F1 O( B0 G% v3 L6 V- E( E
  21. GPIO_Init(GPIOF, &GPIO_InitStructure);                 /* 初始化PF6和PF7,对应VS_XDCS(数据片选)和VS_XCS(命令片选) */8 w1 I# x, b$ U9 A: A. d- H7 G# w5 ]8 j
  22. SPI1_Init();                                           /* 初始化SPI */
    / E4 S# r4 C  L% |
  23. } * r( l9 S* u8 q

  24. + j( b; R0 h1 n  O0 t: X: a: I
  25. /**********************************************************************% b' [, Z! ^$ [' \$ J8 ^! `' c+ ~
  26. 函数名称:VS_Sine_Test()
    / K% t( R! e9 e
  27. 函数功能:正弦测试   ! g/ K# U. p& C( e; S& x# w6 g
  28. 入口参数:无
    ! ~# _% O. J9 M3 }
  29. 返回参数:无
    6 b' f" n4 V5 \" g$ r7 J# B
  30. 解读作者:Aaron) ^+ o( }8 A# a
  31. ***********************************************************************/0 q9 T* E# v# ?
  32. void VS_Sine_Test(void)7 R0 }+ c3 Z/ M$ Z- {9 H$ g
  33. {               5 A5 b, [: W! q  y  y
  34. VS_HD_Reset();                /* 硬件复位 */
    ' C! v% H9 \2 M8 `
  35. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */ 0 C# Y  f9 S) ^' X& v- }" ~- h9 J1 }  r
  36. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     : A3 D5 Q" v' q" p) i
  37. while(VS_DQ==0);              /* 等待DREQ为高 */
    8 |% c& b' @3 L4 u" h% U
  38. printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE));) O& V( ~3 }% w' j
  39. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00 其中n = 0x28=0b00101000, 即FS=48000Hz,频率=48000*8/128=3000Hz  */% V5 ?- b; n( p/ s
  40. VS_SPI_SpeedLow();            /* 低速模式 */
    - u7 G( }* d) V8 p2 z# c4 T4 [* X5 n4 _
  41. VS_XDCS=0;                    /* 选中数据传输 */
    6 l) b; ]7 X) W" [7 l$ Z
  42. VS_SPI_ReadWriteByte(0x53);( p0 W& s) A2 m- L& w/ s2 L) }' j
  43. VS_SPI_ReadWriteByte(0xef);2 i& a  ~1 U  ]& L9 K) e. ~
  44. VS_SPI_ReadWriteByte(0x6e);
    ( Z, i8 o. J# B: s5 Y% H
  45. VS_SPI_ReadWriteByte(0x28);6 b" C" ?5 B6 X% ^
  46. VS_SPI_ReadWriteByte(0x00);$ z4 O- W4 R7 K" K5 Y' K
  47. VS_SPI_ReadWriteByte(0x00);
    " ]5 C  [1 r$ {: i" |4 v
  48. VS_SPI_ReadWriteByte(0x00);6 p; `( L* j& k9 r; S! M
  49. VS_SPI_ReadWriteByte(0x00);
    9 a7 W+ k5 |+ ]3 ~1 f
  50. delay_ms(200);                /* 测试经验告诉我,延迟时间不能超过1s */
    5 t! D: }1 m/ {( F+ W
  51. VS_XDCS=1; 9 G* X# I- G' s: x
  52. /* 退出正弦测试 */
      A: E1 S2 {% j4 i1 L) U4 Z) J, b: Y- e
  53. VS_XDCS=0;                    /* 选中数据传输 */
    $ ]0 ]% F  J. r+ R
  54. VS_SPI_ReadWriteByte(0x45);
    3 j7 z4 O+ o0 h' R! g) Z' Y
  55. VS_SPI_ReadWriteByte(0x78);, q, k" J0 L" b6 t: E9 E; W0 t
  56. VS_SPI_ReadWriteByte(0x69);4 C5 n4 w2 I' i, F7 e4 C
  57. VS_SPI_ReadWriteByte(0x74);5 }+ S  ]& m3 N& W7 e3 P5 F' a
  58. VS_SPI_ReadWriteByte(0x00);6 X# W  B: c9 D( u/ G
  59. VS_SPI_ReadWriteByte(0x00);
    6 V$ p, p1 y" i; h, r
  60. VS_SPI_ReadWriteByte(0x00);5 R  W% M  r; P- i/ _, B6 b
  61. VS_SPI_ReadWriteByte(0x00);
    4 [8 h" W/ K- p# p  _
  62. delay_ms(100);
    / |  `' S( g/ |
  63. VS_XDCS=1;   8 w' D  V6 s. d( b
  64. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00其 中n = 0x22=0b001 00010, 即FS=48000Hz,频率=48000*2/128=750Hz  */7 A. f0 A0 {1 ^9 u( }; a% |
  65. VS_HD_Reset();                /* 硬件复位 */
    9 e8 _# C1 `: b
  66. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */
    ' K# K+ X% q' v
  67. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     
    & I- T$ t4 \' S$ b3 G
  68. while(VS_DQ==0);              /* 等待DREQ为高 */
    * f& F% X8 O, R3 c$ t) Y
  69. VS_SPI_SpeedLow();            /* 低速模式 */
    5 d' G, n+ F+ v/ v6 b
  70. VS_XDCS=0;                    /* 选中数据传输 */      
    1 ~* y# r* [1 E
  71. VS_SPI_ReadWriteByte(0x53);) Y& y* k: ]$ z6 ~/ O9 }$ {: f$ ^. R
  72. VS_SPI_ReadWriteByte(0xef);2 ]' U) r1 ]( J. X7 H6 O" L: h' J1 Y: Y
  73. VS_SPI_ReadWriteByte(0x6e);
    0 O) W: I4 f, _) b4 j1 b
  74. VS_SPI_ReadWriteByte(0x22);9 _  ]3 E* ^) T* w1 H5 k3 {
  75. VS_SPI_ReadWriteByte(0x00);
    . L1 F* s  h1 r/ F! A3 B
  76. VS_SPI_ReadWriteByte(0x00);! N; C, _, U: ~! Q3 p
  77. VS_SPI_ReadWriteByte(0x00);9 M8 V' S. s( J3 h
  78. VS_SPI_ReadWriteByte(0x00);
    3 z) \, u; C$ |8 P% |
  79. delay_ms(400);
    % W4 `+ [& c- A; h
  80. VS_XDCS=1;
    9 I! r/ x# M2 b
  81. /* 退出正弦测试 */
    , }6 v, ^' n* o: {! ^; D  B* J4 b
  82. VS_XDCS=0;                    /* 选中数据传输 */
    : }4 Y7 e- d: [7 W4 v6 m$ c
  83. VS_SPI_ReadWriteByte(0x45);
    + w" g0 W8 m0 S
  84. VS_SPI_ReadWriteByte(0x78);; n7 a, O7 Z% ~% f
  85. VS_SPI_ReadWriteByte(0x69);
    $ O- W; s% m( i" |1 M3 H" B
  86. VS_SPI_ReadWriteByte(0x74);! w4 ~% P* N6 G! `6 F9 G) `
  87. VS_SPI_ReadWriteByte(0x00);$ L& f# y* c; @1 n5 Q- A  @
  88. VS_SPI_ReadWriteByte(0x00);- B3 w# S! z/ h
  89. VS_SPI_ReadWriteByte(0x00);( T; ]" D  d$ V) d
  90. VS_SPI_ReadWriteByte(0x00);. A) w2 n- w: b% d
  91. delay_ms(100);
    " z: s9 m& n. q
  92. VS_XDCS=1;  
    5 Q# X3 J( V! _1 ?' y
  93. }
    # {7 g( A; ]/ [, |! }$ Z

  94. ! e; V* q- k) q
  95. /**********************************************************************
    7 M& w! o& M# V6 a9 p, q+ U
  96. 函数名称:u16 VS_Ram_Test()- F+ X3 Y/ `% M+ O! `' L$ I
  97. 函数功能:RAM测试 # H0 I/ _# i. Z6 R
  98. 入口参数:无
    " u8 L# q! @" ~5 U
  99. 返回参数:u16 RAM测试结果,VS1003若得到0x807F,则表明完好,VS1053则为0X83FF+ v2 @# ?! C1 g+ X3 N8 @( g
  100. 解读作者:Aaron
    % ]: h& t, {& }- k) M
  101. ***********************************************************************/
    0 T. K- m8 H6 L' e' H: t8 L7 |
  102. u16 VS_Ram_Test(void)
    + ~9 g& g' X3 X" i) o
  103. {
    1 s& ^) ?( C7 e5 n5 R9 b
  104. VS_HD_Reset();                /* 硬件复位 */ : h& o1 \' V0 Z
  105. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式 */; L. v+ K; S; M/ h* Y& G6 T
  106. while (VS_DQ==0);             /* 等待DREQ为高 */        r1 E6 A: ~2 O6 b# d& I
  107. VS_SPI_SpeedLow();            /* 低速 */ # Z& O, U9 n* X; m, d
  108. VS_XDCS=0;                    /* xDCS = 1,选择VS10XX的数据接口 */
    5 d! _, Q: T  m! G& n0 E
  109. VS_SPI_ReadWriteByte(0x4d);
    1 |' k( q/ ?& q8 |2 w! L2 P
  110. VS_SPI_ReadWriteByte(0xea);
    # b2 s9 O' t3 x7 X
  111. VS_SPI_ReadWriteByte(0x6d);( v. j9 m, c3 Z9 w( ^0 @, f
  112. VS_SPI_ReadWriteByte(0x54);# `9 O+ N( w# K  Z
  113. VS_SPI_ReadWriteByte(0x00);
    . ~" A/ s+ P- f
  114. VS_SPI_ReadWriteByte(0x00);6 q* v4 N, c- }
  115. VS_SPI_ReadWriteByte(0x00);
    ) w7 h  ^+ G6 v$ t$ v
  116. VS_SPI_ReadWriteByte(0x00);
    / Q3 [+ G/ j2 ^8 K. h6 s
  117. delay_ms(150);  9 s( N' f+ A$ L6 J1 Q' s( f
  118. VS_XDCS=1;
    0 c% Y* d% `* `! l; _0 o% c7 A+ c
  119. return VS_RD_Reg(SPI_HDAT0);  /* VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF */      
    0 `& u2 U. @4 m2 N
  120. }
复制代码
  u. B7 Y. q9 D/ {- P" S; h( ^
5.2 main.c主函数代码解读
4 D8 D# y& H: s0 f" G
+ J; }" w# s, t& e3 ~/ |& ?) i
  1. /************************************************
    2 A% l; o4 u' ], k4 s
  2. 函数名称:int main()
    . Y! C3 t! I: {# \$ a
  3. 函数功能:主函数4 H# u! ~/ p! v0 c6 U
  4. 入口参数:无
    . b/ }0 j- g* y- z: R
  5. 返回参数:int
    % S6 B! e/ x" t& r6 N1 d
  6. 解读作者:Aaron
    : A0 P; s" J6 i$ o
  7. *************************************************/  |) o" F' H. s9 q3 [) a# W
  8. int main(void)( P- o& d+ y" Z3 G0 {3 c
  9. {  . M0 ?& d$ A! T5 m' B
  10.   delay_init();                                   5 I* S$ @; F( T: x/ u  i
  11.   NVIC_Configuration();+ g, i- t' V* J: s8 @! u! m% Y/ a
  12.   LED_Init();      ! M3 ~9 {1 ]# X* P/ u( D
  13.   KEY_Init(); : C4 a' l/ t+ @( g' H
  14.   My_USART1_Init();   ' o/ O. u* U; S3 W' x6 b* H
  15.   VS_Init();           /* 包含对SPI1初始化 */ / @5 ]% W7 y, q( h* D
  16.   printf("存储器测试:%d\r\n",VS_Ram_Test());) o4 T1 h) o; B  g8 e4 {
  17.   while(1), e7 P) i4 c  p: Y# ^/ \3 n/ _7 y
  18.   {. v/ R& p# o" }1 y, W' q& w
  19.    DS0=0;        
    - A0 d& D  O! e9 l
  20.    printf("开始播放单频信号\r\n");
    ! o+ |  _9 v; G. m0 O- I7 `% F
  21.    VS_Sine_Test();   . c4 G( |9 f" O" N- O8 ~+ r7 l
  22.    delay_ms(1000);  
    , d0 _9 }7 [: c1 l! _
  23.    DS0=1;7 o, G, r  d! T5 R
  24.    delay_ms(1000);  
    ) B4 \, C& Y) ?
  25.   }                  
    8 l- T3 t. w8 z
  26. }
    - m% X- f' a8 k% ~/ Q" G7 R% t, H/ d
复制代码

1 t0 [4 o: [3 t: J/ w, I8 f实验结果9 q) G, f1 a7 ^$ I; Q
接上耳机,能听到200ms的3000Hz单频声,然后紧接着听到400ms的750Hz单频声。# _8 O6 _5 D, q  G8 r# |

/ t' b0 _# D, Y( K8 J; v6 L 20201025211948294.jpg ) N, ]( a7 |' T. y" e
7 h  `& r* c, \( C7 h: G
————————————————- v9 D- M- g% j$ x- L
版权声明:天亮继续睡7 t6 N- J% T3 ]3 {7 o. i. v
9 B0 g' A0 u" P4 ^* }, |; ^9 _' L6 a, t
" T  m! S4 P9 d' c& `  K) r
收藏 评论0 发布时间:2022-11-18 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版