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

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

[复制链接]
STMCU小助手 发布时间:2022-11-18 22:00
主要内容:
, ?+ c/ a  A$ l: Z% c1) 硬件连接;
, G# G5 k3 K9 L2) VS1053简介;
: L) s) ^# L  c  o7 W$ m* A2 s. M$ S3) 相关实验及其代码解读。, o/ H1 b3 |1 z! F4 a
实验功能:程序开启后,系统先进行RAM测试,再进行正弦测试,可以接耳机听到所设的单频声音。备注:音乐播放实验还未深入研究,本章内容不涉及。
  z6 E6 A% H% E  O' W9 @7 J7 x# z5 p( f% o2 c
硬件连接:如下图所示:$ H/ I2 n: b$ r1 y/ n/ C
" K& T  _% A% ]' |! N7 ~2 @! B
20201025205213346.png
" @  L& b! Q2 ~4 y  [9 R( B
/ i9 ?8 @5 ^. xVS1053与STM32F103ZET6芯片的连接关系如下:6 N) d( a% J2 |  J2 r
1) VS_MISO→PA6;: Z/ J) B, U6 O9 }- Y/ [
2) VS_MOSI→PA7;+ h$ y( k# l) Y1 P8 z4 u
3) VS_SCK→PA5;
. T* X/ l3 A9 t2 J: b& x3 J' c1 G4) VS_XCS→PF7;
7 @% v, c8 y8 J1 Z$ a+ _5) VS_XDCS→PF6;
8 _# c8 S9 G9 ^, e" W# n3 M9 C6) VS_DREQ→PC13;
1 b" H1 Q- ], Y. k$ D5 h7) VS_RST→PE6。
' p- P; {( c5 S1 S) X7 L备注:PA5/PA6/PA7,即:STM32的SPI1;SPK_CTRL,控制板载喇叭(输入到HT6872)!由程序控制。
0 A! I% a8 W2 A' `, O8 _/ B
4 ]' g) ~( e5 m. l5 y1. VS1053简介8 O) _5 T, @& |) L/ I
1.1 VS1053是继VS1003后荷兰VLSI公司推出的又一款高性能编解码芯片。该芯片可对MP3/OGG/WMA/FLAC/WAV/AAC/MIDI等音频格式解码,同时还支持ADPCM/OGG等格式的编码,性能相对VS1003提升不少。7 v( f, t3 s) Q: U
VS1053拥有一个高性能的DSP处理器核VS_DSP,16K的指令RAM,0.5K的数据RAM,通过SPI控制,具有8个可用的通用IO口和一个串口,芯片内部还带了一个可变采样率的立体声ADC(支持咪头或线路输入)、一个高性能立体声DAC及音频耳机放大器。, H  ?) N* I$ A2 z  T" f. V+ z5 M; \
' T6 G0 C" [* e, n
1.2 特点9 W! Z0 k( E: E4 t2 V) L
1) 支持OGG/MP3/WMA/WAV/FLAC(需加载patch)/MIDI/AAC等格式解码;
% V- i. Y4 }. n1 e, d% r4 r2) 支持OGG(需加载patch)/IMA ADPCM编码;" ^: Q/ N2 l# K5 k7 Q9 z& `: h3 N
3) 支持音量调节、高低音控制和EarSpeaker空间效果;% M, p4 |- K5 y# |
4) 自带高性能立体声ADC和DAC,音质比VS 1003好很多;
, z" M; S* p4 Z5) 自带耳机驱动器,可驱动30欧负载的耳机;
' S( c1 Y1 S( h, j% g  [2 M  I+ V7 ^6) 自带8个GPIO,可用于控制外设/作为I2S接口(外接DAC );: y# F5 |7 x0 E/ Z# f! j
7) 通过SPI接口控制/传输数据,接口简单;9 n& k' X* J6 U2 I
8) 可通过加载patch,实现新功能添加;
% M7 C! \/ h% Z$ m3 c0 \8 Y" W9) 低功耗 。! [' a7 c1 i6 Y8 l4 U9 F3 A
& j$ d0 n3 k7 ]+ j
1.3 接口介绍- R. c) V' o# v2 }4 T/ I4 m9 {
VS1053通过SPI接口来接受输入的音频数据流,它可以是一个系统的从机,也可以作为独立的主机。本例程,我们把它当成从机使用。我们通过SPI口向VS1053不停的输入音频数据,它就会自动帮我们解码了,然后从输出通道输出音乐,这时我们接上耳机就能听到所播放的歌曲了。
/ w/ W4 c% P. {& [0 u2 uVS1053通过7根线同MCU连接,如下:
' p' z5 G1 ^, ^& b: nVS_RST:VS1053的复位信号线,低电平有效;
6 [8 m/ L. i" s/ T, zVS_DREQ:数据请求信号(高电平有效),用来通知主机,VS1053是否可以接收数据;
9 w" w2 [5 _' A5 E1 {VS_XCS:命令片选(低电平有效);' J0 K, F( N) t! J' v) l
VS_XDCS:数据片选(低电平有效);
/ r$ L) [% u& f+ ]VS_MISO、VS_MOSI和VS_SCK:SPI信号线。
( a2 i5 |* m6 r/ j6 P. a" T9 u) ~6 Y$ W/ v- y3 Y% X0 x
1.4 VS1053工作模式
0 r0 l9 V0 x6 W7 ]' YVS1053的SPI支持两种工作模式:
, M7 O3 T  ?$ [" b" D( S1,VS1002有效模式(即新模式);
7 X: @$ ~- P; X% T8 U2,VS1001兼容模式。
/ g% l' l; m5 q: U这里仅介绍VS1002有效模式(此模式也是VS1053的默认模式)。在新模式下VS1053的SPI信号线功能描述如下表所示:
0 u4 k# S/ w5 Y( o' K/ ]% S. C9 ~$ d6 U% _) h, l2 i
2020102520553924.png 6 Y( A' `$ ?  M+ {/ B- h

* B2 _4 Y4 G& W) H9 LVS1053的SPI数据传送,分为SDI和SCI,分别用来传输数据/命令。SDI采用SPI协议,不过,数据传输受DREQ控制,主机在判断DREQ有效(高电平)之后,直接发送数据即可(一次可以发送32个字节)。6 A; N8 R- c7 P% Y# W
7 m( s2 E; R- ~0 }( ~
1.5 VS1053之SCI命令传输介绍6 g# q. l6 [4 Y6 y
SCI串行总线命令接口包含了一个指令字节、一个地址字节和一个16位的数据字。读写操作可以读写单个寄存器,在SCK的上升沿读出数据位,所以主机必须在下降沿刷新数据。SCI的字节数据总是高位在前低位在后的。第一个字节指令字节,只有2个指令,也就是读和写,读为0X03,写为0X02。
5 K$ L" f. z: t5 e4 T1 U# YSCI读时序如下图所示:, ?5 P1 \( v/ w  Z/ Z
( n! t' R' o0 k4 l/ B* p" N
2020102520570422.png 9 w5 ^% k* T! o: W+ ^/ M
6 K( p  z* n1 |! O) {! `: _' w$ ^
SCI写时序如下图所示:
# ^( T- z% @! k! l: E; t' }2 S! _" c0 |$ a6 ~3 k# \2 Q3 f
20201025205737881.png
4 w4 T4 P4 ?1 Q& x. n, u+ C2 |4 Q
5 }+ q3 g$ h: K, t& i0 x" ^写指令为:0X02,数据通过SI写入VS1053, SO则一直维持低电平。+ o1 N  u8 L% t) z8 d9 V
注意:在读和写时序图中,DREQ信号上都产生了一个短暂的低脉冲,也就是执行时间,在写入和读出VS1053的数据之后,它需要一些时间来处理内部的事情,这段时间,是不允许外部打断的。所以,在SCI操作之前,最好判断一下DREQ是否为高电平,如果不是,则等待DREQ变为高。
7 L/ W+ p% Q" S: ?7 E4 v/ Y6 ^4 A/ D
2. VS1053寄存器介绍
6 Y3 @/ r/ S2 P8 G' y+ P2.1 VS1053的所有的SCI寄存器,如下表:) a0 K/ {3 l" T, N9 |
( {; o! u+ M) h' `4 c
20201025205924828.jpg 3 o; t3 l8 a- c7 y; H2 \6 G

" I! d( E& ~: u; g2.2 MODE寄存器(0X00)
$ ~* j# `  X" C+ k; S; D- ~) B: X/ V; X8 B) n6 I: ]
20201025210013379.png * Z' y' v. y, d
0 I) `) Q4 I/ S
SM_RESET:软件复位,建议在每播放一首歌曲之后,软复位一次。
/ `" y+ _' L! M8 g% f# jSM_SDINEW:模式设置位,设置为1,选择VS1002新模式(本地模式)。
2 f0 `/ x# q: x+ K- D3 I2 G其他位的详细介绍,请参考:VS1053_cn.pdf。# w0 \4 o; V! U9 u: w: _

& i+ i# U. T& \' J- T5 f2.3 BASS寄存器(0X02)/ B1 o. }4 P& T; t! E

, V7 L8 l, [, I, q0 h 20201025210115913.png
7 |& x8 N- k- v) k7 X7 `' Y
- x7 o4 s7 K# U5 h' ~( A  N该寄存器可以用于设置VS1053的高低音效,通过这个寄存器以上位的一些设置,我们可以随意配置自己喜欢的音效(其实就是高低音的调节)。
) ?9 E: v2 K4 W注意:EarSpeaker效果由MODE寄存器控制。
' d1 V/ J: p; ]# c  _8 C! W
% o, V: w6 m2 C2 ~+ q( K5 p2.4 CLOCKF寄存器(0X03)4 F5 C' c7 R) i

9 z' e. {  @, q7 |+ Y 20201025210211236.png
2 e! C" p4 ~0 H) t$ j- I6 S4 d' Y# a" F! y! R+ k% {2 v3 E4 }# G2 X$ b
该寄存器用来设置时钟频率、倍频等相关信息。其中:SC_FREQ是以4Khz为步进的一个时钟寄存器,当外部时钟是12.288M的时候,设置为0即可。3 i  E' @/ w' J9 C" q$ L: |
XTALI是外部晶振的时钟频率(单位为:Hz )。CLKI是内部时钟频率。由于我们使用的是12.288M的晶振,在这里设置此寄存器的值为0X9800,也就是设置内部时钟频率为输入时钟频率的3倍,倍频增量为1.5倍(0X9800=1001 1000 0000 0000)。, u' |5 a- b. Y( |& S7 c

6 s/ p5 Q1 y! j9 |% s6 C% i2.5 DECODE_TIME寄存器(0X04)
, i* @9 t- F, W6 x: c: o% k# x* R. `$ p该寄存器是一个存放解码时间的寄存器,以秒钟为单位,我们通过读取该寄存器的值,就可以得到解码时间。不过,它是一个累计时间,在每首歌播放之前,需要把它清空一下,以得到这首歌的准确解码时间。
1 _3 a* b/ }* j! ^/ x
( i+ i% B8 J3 q$ M0 s5 h2.6 HDAT0&HDAT1寄存器(0X08&0X09)' e, l+ C* ]4 P* U, d# S+ R
这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。这两个寄存器的详细介绍,请参考:VS1053的数据手册(VS1053_cn.pdf)。
2 ^: j) O2 V0 e" C  c! Y7 ~8 N: N2 B1 R- a9 U% f; K5 z
2.7 VOL寄存器(0X0B)
5 O6 _. V' ~/ J3 s+ H该寄存器用于控制VS1053的输出音量,该寄存器可以分别控制左右声道的音量,每个声道的控制范围为0~254,每个增量代表0.5db的衰减,所以该值越小,代表音量越大。比如设置为0X0000则音量最大,而设置为0XFEFE则音量最小。2 B: X+ t& x& m; X7 Y) P, o8 u
注意:如果设置VOL的值为0XFFFF,将使芯片进入掉电模式!& v( m) x8 l5 ?% Q* s/ ]; r% l

7 P1 u; I* [: x! [3 VS1053初始化步骤  C5 ]0 w( a7 D0 J) q- v0 |
1) 复位VS1053
4 k# \8 v3 b. F1 H3 T' O" U5 H4 _3 O包括硬复位和软复位,让VS1053恢复初始状态,准备解码下一首歌曲。在每首歌曲播放之前都可以执行一次硬件复位和软件复位,以便更好的播放音乐。
7 s; r; b7 g; n4 Z( D6 N9 n2) 配置VS1053的相关寄存器, [. o! `  w7 o6 e
这里配置的寄存器包括VS1053的模式寄存器(MODE)、时钟寄存器(CLOCKF)、音调寄存器(BASS)、音量寄存器(VOL)等。
/ m8 m' D1 }8 X) T1 W; m' O5 R- z% o4 o4 B! E
3) 发送音频数据& R3 g3 ?. t% r. z, k
经过以上①、②配置以后,剩下来要做的事情,就是往VS1053里面发送音频数据,只要是VS1053支持的音频格式,直接往里面丢就可以了,VS1053会自动识别,并进行播放。不过,发送数据要在DREQ信号的控制下有序的进行,不能乱发。这个规则很简单:只要DREQ变高,就向VS1053发送32个字节。然后继续等待DREQ变高,直到音频数据发送完。) ], y$ k+ ]+ k# X7 _) X

+ _' i. E5 P; ]: ^# J5 _4. 部分源码讲解' [3 d# ^; G' l; r
4.1 VS1053低速2.25MHz,高速9MHz。
7 m1 z: f/ j& M' W9 O+ ?# @, E8 |8 R! V& J% k
  1. /*******************************************************************************
    7 Y5 l8 S6 u1 f: Z; _; c: s: I/ `
  2. 函数名称:u8 VS_SPI_ReadWriteByte(u8 data); ?4 R; O# |# n5 Z/ L% y
  3. 函数功能:读写数据,移植用         ) c+ {3 k: J; k: t5 X
  4. 入口参数:u8 data:要写入的数据; Q) x% a4 `: U1 S
  5. 返回参数:u8 读到的数据5 Z5 P+ ?9 z3 a  a, w; [
  6. 解读作者:Aaron% j( K# J# }* E# D8 {
  7. ********************************************************************************/1 H& q' z  I" T, i) P
  8. u8 VS_SPI_ReadWriteByte(u8 data)6 A: Z+ s! V6 O) B, [
  9. {                             2 v2 b6 J2 Q' ]/ V* y
  10.     return SPI1_ReadWriteByte(data);     
    ' c, ]& ~* P+ h, X) T5 J: W4 N! H2 k
  11. }
    5 O( U" {- ]4 n# s
  12. /* VS1053初始化时,需要低速 */
    + g9 P7 x; G2 H+ N/ ~
  13. void VS_SPI_SpeedLow(void)% D  K' m8 q+ c* e3 E+ `
  14. {                                                                    ' ?2 q. M' y; G& w, C1 y5 `
  15.     SPI1_SetSpeed(SPI_BaudRatePrescaler_32);     /* 设置低速模式,72/32≈2.25MHz */ % @6 O9 B5 Y+ o# H6 f) L
  16. }
    & N+ W) ]. S( I
  17. /* VS1053正常工作时,可以高速 */0 i6 f4 A5 G, s0 ?
  18. void VS_SPI_SpeedHigh(void)
    + c4 q4 P4 x; O& J9 @
  19. {                                                   
    ( |. z, R* y* ]" F2 X7 L- x
  20.     SPI1_SetSpeed(SPI_BaudRatePrescaler_8);      /* 设置高速模式,72/8=9MHz */               
    / v# @- j: i6 D5 R, b" ?
  21. }
复制代码

( i! u9 V( `" C+ A这么设置的原因如下表(VS1053芯片手册):, p/ ?# B/ p7 l) }& s

% u) r  e% ^  q: }+ K$ X 20201025210704342.png
: ?1 d- E6 E  J" T* t9 U! U9 B6 R, s) u% S: Y% v! @; n) H
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。2 d# V5 q1 ?! ]( u% u

1 _, X$ K+ J3 v$ R5 相关实验代码解读
- O7 F% N1 {. e( w/ R; v5.1 vs10xx.c部分代码(我修改了下)3 |- D, l; O  }, E: Z
9 \" l% z) u, @' \, U  ^, S
  1. /**********************************************************************8 f$ z/ R$ ~2 [, I  ?$ X
  2. 函数名称:VS_Init()
    6 S' H( S% j+ S) Z
  3. 函数功能:初始化VS10XX的IO口  # C2 w  n' }. t4 ]( {
  4. 入口参数:无
    ! T6 P' `, n, D9 ^
  5. 返回参数:无
    5 g* D! K1 |8 P' K
  6. 解读作者:Aaron
    5 Q* Y, h4 y0 [, i+ A; `" C/ L
  7. ***********************************************************************/
    6 V4 {! L, X: z9 s: T7 }* l
  8. void VS_Init(void)
    ! b( v- \" f5 F4 C/ |
  9. {4 q  H" m# ^/ H6 k  f. [
  10. GPIO_InitTypeDef  GPIO_InitStructure;( h; g  _: z9 O2 \9 c
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE);  /* 使能PC,PE,PF端口时钟 */9 k7 z# Q1 t( |" k9 z
  12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;       P: F( m! R7 T9 @4 Q9 B* x
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          /* 上拉输入 */
    7 W  l6 |' I; K) h$ |+ j, M  B
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    $ L. N- R& e7 g: S
  15. GPIO_Init(GPIOC, &GPIO_InitStructure);                 /* 初始化PC13,对应VS_DREQ(数据请求信号) */* A0 x2 M+ [/ I7 i' C
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
    9 m6 t1 j6 D+ e/ i% H9 E
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */
    - d8 b. m' G- r/ \' e& K. G
  18. GPIO_Init(GPIOE, &GPIO_InitStructure);                 /* 初始化PE6,对应复位信号线 */       ! d. {7 ?" x( d* J6 }! [
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    * X4 _! A6 X& x$ Q% y) ^
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */4 C) W( U! A+ M
  21. GPIO_Init(GPIOF, &GPIO_InitStructure);                 /* 初始化PF6和PF7,对应VS_XDCS(数据片选)和VS_XCS(命令片选) */3 Z3 R8 z4 A" K1 p5 G- h
  22. SPI1_Init();                                           /* 初始化SPI */
    " ?- R* q- W- u/ D( b
  23. }
    ( b4 z1 b6 n" ^0 W6 _& E
  24. 3 E% m5 R4 N+ A  w# C6 G
  25. /**********************************************************************
    5 `  @3 h0 _) u) k& o
  26. 函数名称:VS_Sine_Test()
    - u, u! N+ S8 S- r+ s7 X
  27. 函数功能:正弦测试   ! y' M+ ~5 q" B% L! {
  28. 入口参数:无
    & @  ?2 Y- e$ z& D" L7 A, G
  29. 返回参数:无
      `- K9 S2 p% [- N  Q- Y
  30. 解读作者:Aaron
    + j: m- n5 Q" @( U1 {& |$ B# A
  31. ***********************************************************************/! V; i7 D, O4 u/ Q- W
  32. void VS_Sine_Test(void); @9 |* ~9 j1 j
  33. {               " B9 s2 B* {! @: X& C! U
  34. VS_HD_Reset();                /* 硬件复位 */( Q. A' d6 p/ {5 j% f' p8 T. n, f! J# U
  35. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */
    $ O2 i" n$ Q8 D; n9 l! C. Y
  36. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     
    + d# I8 F/ {$ _
  37. while(VS_DQ==0);              /* 等待DREQ为高 */
    . h1 Q" s# y# D6 ]2 L! ^/ P8 W9 o
  38. printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE));( Z& K* j  x" ~6 z, i5 F+ U
  39. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00 其中n = 0x28=0b00101000, 即FS=48000Hz,频率=48000*8/128=3000Hz  */# e, s  @3 P& `" O3 |5 b4 Z1 {# K
  40. VS_SPI_SpeedLow();            /* 低速模式 */
    2 ]  y0 r* H7 g# Z# N/ Z
  41. VS_XDCS=0;                    /* 选中数据传输 */
    1 R0 G1 [: [- f2 V0 Z
  42. VS_SPI_ReadWriteByte(0x53);* n; B, p/ `2 {4 l3 U: g
  43. VS_SPI_ReadWriteByte(0xef);+ j  z7 b% v+ }+ A3 @2 B
  44. VS_SPI_ReadWriteByte(0x6e);
    8 I  f( O6 p4 m3 j7 C
  45. VS_SPI_ReadWriteByte(0x28);4 A6 l6 Y- c1 y* X3 G' ~
  46. VS_SPI_ReadWriteByte(0x00);
    + o3 a4 `: d" ?% a
  47. VS_SPI_ReadWriteByte(0x00);
    6 H! \: f1 d% C
  48. VS_SPI_ReadWriteByte(0x00);9 O; [4 A8 \+ r. U3 A
  49. VS_SPI_ReadWriteByte(0x00);
    ; u9 [' A( k6 x3 O) S1 x
  50. delay_ms(200);                /* 测试经验告诉我,延迟时间不能超过1s */' X: T! J) F0 z+ B
  51. VS_XDCS=1; ) e& e5 a% C; g5 H/ b
  52. /* 退出正弦测试 */( i6 W% s! x. X' G/ f
  53. VS_XDCS=0;                    /* 选中数据传输 */
    * C5 z  c& C& l# E2 m4 h6 P! I7 ~
  54. VS_SPI_ReadWriteByte(0x45);
    7 b% @0 [) _, \# t! l7 b
  55. VS_SPI_ReadWriteByte(0x78);
    6 L/ X3 H9 n: \1 K
  56. VS_SPI_ReadWriteByte(0x69);( W! J( P5 D/ R1 r& C- m
  57. VS_SPI_ReadWriteByte(0x74);" p6 M/ m* o5 H+ C2 ]
  58. VS_SPI_ReadWriteByte(0x00);" C2 o' D# w$ K( h+ Y# C! _# S) K4 _
  59. VS_SPI_ReadWriteByte(0x00);
    3 i% _+ J5 O/ V2 b# o0 i/ ^
  60. VS_SPI_ReadWriteByte(0x00);% `& Z/ d/ S: P
  61. VS_SPI_ReadWriteByte(0x00);
    / B4 j3 X; D6 c3 m* u
  62. delay_ms(100);4 v. H( e8 T. @8 o* |4 D
  63. VS_XDCS=1;   0 A' A: z. s; S2 c# E
  64. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00其 中n = 0x22=0b001 00010, 即FS=48000Hz,频率=48000*2/128=750Hz  */; x2 V! L& P* C& W, c, ^0 z
  65. VS_HD_Reset();                /* 硬件复位 */5 B+ G$ s5 f6 q4 X3 q
  66. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */ . _# u; R. J! Y+ O# x. d
  67. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     5 u* l" _: U1 K3 b9 c3 g$ c8 `
  68. while(VS_DQ==0);              /* 等待DREQ为高 */5 m, ?. i. o. G! ?6 Z& Y, b0 D5 Y( L
  69. VS_SPI_SpeedLow();            /* 低速模式 */
    # u0 V& u% c8 E/ K& B
  70. VS_XDCS=0;                    /* 选中数据传输 */      
    * Q, o* g- p( R& F& m: e
  71. VS_SPI_ReadWriteByte(0x53);
    9 h& z1 M- a' b8 T9 N
  72. VS_SPI_ReadWriteByte(0xef);4 E* h6 t$ M; q) g) S! ?: R6 M
  73. VS_SPI_ReadWriteByte(0x6e);* `6 a5 V6 g" i, r( d
  74. VS_SPI_ReadWriteByte(0x22);9 D1 ~) [& C$ k' `0 L/ |' _
  75. VS_SPI_ReadWriteByte(0x00);
    8 E3 w# t( @6 B1 a
  76. VS_SPI_ReadWriteByte(0x00);" L0 L* p5 `8 f0 m7 P1 v
  77. VS_SPI_ReadWriteByte(0x00);
    - S/ v9 M1 A: @- n
  78. VS_SPI_ReadWriteByte(0x00);
    7 ], L4 ]4 y: H, s9 y8 E0 Z/ D
  79. delay_ms(400);
    0 b* X3 v( ~! A; q4 X
  80. VS_XDCS=1;
    0 @9 B0 r$ V. L$ }3 n- {
  81. /* 退出正弦测试 */
    8 f/ ]/ \% r/ P
  82. VS_XDCS=0;                    /* 选中数据传输 */
    ) `; ~. ?) Z7 Z  h$ j
  83. VS_SPI_ReadWriteByte(0x45);1 ?0 \+ ^+ W2 h7 T
  84. VS_SPI_ReadWriteByte(0x78);* @2 A8 n& Z  L2 I1 \. B
  85. VS_SPI_ReadWriteByte(0x69);
    ) V+ \  X0 k% [/ M2 F; m
  86. VS_SPI_ReadWriteByte(0x74);
    , }" w" a7 Q$ p: Q$ r1 V9 c! K9 i' e
  87. VS_SPI_ReadWriteByte(0x00);
    7 x: [' n! o7 c" x* X
  88. VS_SPI_ReadWriteByte(0x00);2 M; X4 x6 o) E2 ^+ y
  89. VS_SPI_ReadWriteByte(0x00);6 x7 d% S8 L; a/ [3 ^: h. d
  90. VS_SPI_ReadWriteByte(0x00);' }* q- h) t# x
  91. delay_ms(100);
    % q! ]5 [, e+ H
  92. VS_XDCS=1;  
    5 R  u/ r& K, x$ ]' E* Q
  93. }
    % R2 I4 ?1 G) {) J/ t/ E

  94. ' _# |" D* b& J* I. ]) L5 o
  95. /**********************************************************************3 E, t0 I8 A, P) B
  96. 函数名称:u16 VS_Ram_Test()& t4 A6 q. r. x+ @: n
  97. 函数功能:RAM测试 9 e% L$ p/ i3 h# l. z; C! n
  98. 入口参数:无( y) q- ^$ p  J5 _' ^
  99. 返回参数:u16 RAM测试结果,VS1003若得到0x807F,则表明完好,VS1053则为0X83FF2 ?% K* u2 p5 _" ^  x$ R
  100. 解读作者:Aaron% K( S' M' p% D. m
  101. ***********************************************************************/0 K7 R# ]$ S1 o; b8 \  e
  102. u16 VS_Ram_Test(void)2 l5 ?. H! Y$ X7 ]
  103. {
    & n, [1 |5 F" p1 ^' c8 Q. c+ L# t  h
  104. VS_HD_Reset();                /* 硬件复位 */
    ( [7 C' y! z; ~7 h
  105. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式 */
    . B9 A4 J9 h" h7 N- E
  106. while (VS_DQ==0);             /* 等待DREQ为高 */      / r3 i$ G0 B0 s$ J1 P  n7 I( u
  107. VS_SPI_SpeedLow();            /* 低速 */
    : `& n3 o! N, a$ x! K$ U
  108. VS_XDCS=0;                    /* xDCS = 1,选择VS10XX的数据接口 */3 u- S4 [6 F) T' Q3 G! t
  109. VS_SPI_ReadWriteByte(0x4d);
    , u1 _# I, G- i% ?
  110. VS_SPI_ReadWriteByte(0xea);8 ~9 j, V+ X- e! y. c* Y
  111. VS_SPI_ReadWriteByte(0x6d);
    3 N  Z% M& }# {5 @. \
  112. VS_SPI_ReadWriteByte(0x54);% ]  J6 n$ L0 v2 U- P  g
  113. VS_SPI_ReadWriteByte(0x00);
    8 n( \# H' K2 C, j# ]$ Q
  114. VS_SPI_ReadWriteByte(0x00);$ d7 |( P2 d& ~
  115. VS_SPI_ReadWriteByte(0x00);
    9 Q1 X; k% x3 B4 {. N: l6 L
  116. VS_SPI_ReadWriteByte(0x00);. ^# ?$ J0 g; Y8 H
  117. delay_ms(150);  
    . n+ P' G! H& z, B; J8 ~
  118. VS_XDCS=1;* j4 `9 f, x1 {! l% Z5 C/ ?' i6 v
  119. return VS_RD_Reg(SPI_HDAT0);  /* VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF */       - n& p  O) x& [, V+ T* |
  120. }
复制代码
+ D! L4 L' ~3 L8 P# U) J0 j' F0 `
5.2 main.c主函数代码解读
- b$ j" Y; a: s  A0 D4 N# n( g2 }( g  w; ]( b; D1 z
  1. /************************************************
    6 i9 W& F- e) P+ z7 |; R/ n3 E
  2. 函数名称:int main()" o# X9 _/ v1 q( X$ R
  3. 函数功能:主函数
    4 e0 F" P1 j1 S, W
  4. 入口参数:无8 r9 f1 P4 O% Y
  5. 返回参数:int5 K0 ]2 i: b' S. D- J9 X4 ^
  6. 解读作者:Aaron
    ' G+ [- |9 i4 D# ~3 T
  7. *************************************************/
    - ]5 b$ p* }+ Z
  8. int main(void)
    ; l$ T8 k* O) N4 b# ~2 R% P
  9. {  6 }% O2 R  D& }+ R0 G
  10.   delay_init();                                   ( |5 P# F& W, q: C
  11.   NVIC_Configuration();
    , i. V# t" Q( B, c
  12.   LED_Init();      4 o4 l4 D! u6 n: Y/ k- T
  13.   KEY_Init(); + \: L7 O0 ]4 b2 m1 d
  14.   My_USART1_Init();   ; Q/ N; W- T- ^7 f0 E5 Y
  15.   VS_Init();           /* 包含对SPI1初始化 */
    8 H6 D& U$ ^: y$ f/ u. ]. b( y9 t9 F
  16.   printf("存储器测试:%d\r\n",VS_Ram_Test());- S7 z3 T5 h1 b" u! o
  17.   while(1)8 u0 f& m. Y) X- G5 T
  18.   {
    ; e' O2 \( y$ j% E: j
  19.    DS0=0;        ) x1 D4 g8 }: S+ _3 x. r
  20.    printf("开始播放单频信号\r\n"); ( h% F- _, g. U6 H9 s% J. ]
  21.    VS_Sine_Test();   ; R. ]" r, X9 |1 i- q9 _% y
  22.    delay_ms(1000);  
    / s' q& Q6 }8 n. y9 M
  23.    DS0=1;2 s+ {, C5 f: {% Z1 U
  24.    delay_ms(1000);  ! j+ [/ O* i! |) J4 M! _/ E
  25.   }                  
    : \  S, G# f! C. p0 ?
  26. }2 e" w  F# k+ p# A$ ?' ]' o( z
复制代码
0 K: M& E6 s4 c
实验结果
2 R; @# U- [+ G0 N5 r9 M+ m0 D接上耳机,能听到200ms的3000Hz单频声,然后紧接着听到400ms的750Hz单频声。- A! n; u  U) F& C- a7 e$ }3 i! c

) B1 B" t" Q% z! p 20201025211948294.jpg 4 q* f: i' y- {9 G8 x
3 y8 Q/ p* j& C* |& ^
————————————————& Z- F3 t0 a4 n: P) }" V1 y% l
版权声明:天亮继续睡1 {- X% j# V; u" S( e# a: U

+ ?! x# V  T9 x2 C0 ^& C3 }
2 S( Z- p* y- `
收藏 评论0 发布时间:2022-11-18 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

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