主要内容:
% 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
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
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
" 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
( 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
, 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
! 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" ^
+ 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
# 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
- /*******************************************************************************
; e" N& Y9 \* e& ` - 函数名称:u8 VS_SPI_ReadWriteByte(u8 data)
9 A [/ s4 k$ C3 T7 E8 Y N+ e - 函数功能:读写数据,移植用 , `8 F1 O0 Z7 h1 U9 a6 |! ~ m
- 入口参数:u8 data:要写入的数据
z$ N% d- t" e* [" S* A - 返回参数:u8 读到的数据1 A% k8 s/ e z! g6 Z2 R* p E1 U
- 解读作者:Aaron
, [/ B; J* s8 h - ********************************************************************************/8 `8 l( r2 M7 a0 T9 i% o
- u8 VS_SPI_ReadWriteByte(u8 data)
/ C1 S5 j9 o+ Q0 c9 g$ E9 u: e - { # p9 g' L8 m# o. G0 ^
- return SPI1_ReadWriteByte(data);
" B, z& _$ Z) K" N, Q4 L - }) T; @* d+ G1 ~! b/ Q; ~
- /* VS1053初始化时,需要低速 */ r+ }) J! h7 c' U# M, A1 @
- void VS_SPI_SpeedLow(void)
, Z9 k# r5 |6 u6 h - {
; M0 [7 I! e% h# Q8 r/ [0 v - SPI1_SetSpeed(SPI_BaudRatePrescaler_32); /* 设置低速模式,72/32≈2.25MHz */ $ ]; `( B; i B: h& W" R) P; \
- }
& D) G* F- V, E" _+ K: e - /* VS1053正常工作时,可以高速 */ y x9 ?* y- z5 w9 Z
- void VS_SPI_SpeedHigh(void)
1 K4 {2 p4 o7 E! M8 [6 a# e6 s - {
( S: N7 m3 l$ [+ f. b6 a) s7 J - SPI1_SetSpeed(SPI_BaudRatePrescaler_8); /* 设置高速模式,72/8=9MHz */ . _& ~# O0 D0 n& z
- }
复制代码 $ O& J; q/ N- \7 V0 \) w4 l- G5 l
这么设置的原因如下表(VS1053芯片手册):
9 ^2 [, f T; p) }+ h$ Z# q; g3 [+ L! E1 w5 L
+ 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 [- /**********************************************************************
# o' [4 u! ^" C& i - 函数名称:VS_Init()
. P# u Q/ z* L6 @2 ?6 G - 函数功能:初始化VS10XX的IO口 1 b- Y- Y6 L( x. v9 [
- 入口参数:无' E7 [7 L' E* B3 X; O5 h
- 返回参数:无2 x7 V' D8 F% R) B1 f( V
- 解读作者:Aaron
; }" N9 {; V6 Q) { - ***********************************************************************/
' [" Z& g0 W" w. V - void VS_Init(void)
* G" z: p( @# Z1 W7 e" s6 S2 [8 g - {+ @5 I; ~! [1 o7 l% E
- GPIO_InitTypeDef GPIO_InitStructure;0 B0 V1 H7 E% s; d) A
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE); /* 使能PC,PE,PF端口时钟 */( v2 [! j4 c4 m$ [
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; - [( [9 v w3 N. E" z* V$ @8 e
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* 上拉输入 */
. |+ R5 Q; o; u5 t9 D, a) }+ t$ ]4 e - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/ K& L5 \% p8 j. O5 J( X - GPIO_Init(GPIOC, &GPIO_InitStructure); /* 初始化PC13,对应VS_DREQ(数据请求信号) */, r- f+ ?$ [$ k" f
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
3 V% ~* C1 B! W6 }* q9 o - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 */3 ]( R, a( }* K) U
- GPIO_Init(GPIOE, &GPIO_InitStructure); /* 初始化PE6,对应复位信号线 */ 3 `' G9 H3 v" O6 L e; [
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;$ {- X: C3 H1 O' V) k
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 *// C& o; w1 r8 l! ], s. E
- GPIO_Init(GPIOF, &GPIO_InitStructure); /* 初始化PF6和PF7,对应VS_XDCS(数据片选)和VS_XCS(命令片选) */
4 D& @6 |* J, R& d F - SPI1_Init(); /* 初始化SPI */, n1 m& h. _) o- f2 v0 o
- } 6 g1 |0 O0 ?0 g8 x: ` T! m
: B: v0 r4 z2 L. ?; {. c- /**********************************************************************( [# r5 Z. M( F9 ~0 }% g5 }; P
- 函数名称:VS_Sine_Test()6 [2 K6 H# u$ t+ b( S$ Q* Y/ Q$ D
- 函数功能:正弦测试
0 ?& f$ U0 M+ O. K( C" A5 ] - 入口参数:无/ A/ D, n$ @$ b
- 返回参数:无
6 `' m8 s" [9 I# ]6 ^ - 解读作者:Aaron
6 S j3 P# I1 B$ t+ ^ - ***********************************************************************/
9 U/ G. f4 m6 |4 Q" ^* E+ N. }- v - void VS_Sine_Test(void)
9 L& `1 l! b# H% b' o" j - { 7 z V& e' Z, O3 M# L
- VS_HD_Reset(); /* 硬件复位 */
+ ?. G* A+ k9 B' P - VS_WR_Cmd(0x0b,0X5050); /* 设置音量,值越小声音越大 */ P1 S/ ~' p6 G0 Y
- VS_WR_Cmd(SPI_MODE,0x0820); /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */
! g/ ?8 U! m3 O4 \0 _ - while(VS_DQ==0); /* 等待DREQ为高 */
R8 T- a3 D" R, B2 Q - printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE));
" v# }- a( e7 a: g' ^ - /* 向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 - VS_SPI_SpeedLow(); /* 低速模式 */
8 e, l1 ]5 @& m" h - VS_XDCS=0; /* 选中数据传输 */
! N6 B N( J. B* I - VS_SPI_ReadWriteByte(0x53);) C/ T+ m3 K. k0 Q, s- i
- VS_SPI_ReadWriteByte(0xef);
/ v' e- F+ s0 e9 F, A3 E4 K1 N0 @ - VS_SPI_ReadWriteByte(0x6e);
, B1 _- w6 a2 ~( y# } - VS_SPI_ReadWriteByte(0x28);
9 X, A) s3 ?. y, D2 [7 `, J - VS_SPI_ReadWriteByte(0x00);% C( h) c6 d8 [
- VS_SPI_ReadWriteByte(0x00);
6 [" i x9 U( }4 o - VS_SPI_ReadWriteByte(0x00);
+ Z4 t5 ]% v/ M( O- o - VS_SPI_ReadWriteByte(0x00);
9 M V# d! i; b; u0 ^+ x - delay_ms(200); /* 测试经验告诉我,延迟时间不能超过1s */% Q0 X* o- Z" I8 D6 V2 B) R
- VS_XDCS=1;
* ]* O7 b. F; L% \ - /* 退出正弦测试 */& N! O g7 ^* V: y4 J* Z; V5 A- \
- VS_XDCS=0; /* 选中数据传输 */* I9 B. t9 U* T2 R- R% D- V+ m3 ^+ N
- VS_SPI_ReadWriteByte(0x45);
0 r Z* }8 ]7 n% i; J+ T - VS_SPI_ReadWriteByte(0x78);
8 l' p8 K* h0 M; o) {" z - VS_SPI_ReadWriteByte(0x69);/ k! G$ Q# X+ H
- VS_SPI_ReadWriteByte(0x74);
, j6 D/ P; z9 r5 S, D) z/ d - VS_SPI_ReadWriteByte(0x00);
" k7 o. l _$ c2 e3 P; @. E/ Q* p' } - VS_SPI_ReadWriteByte(0x00);
5 A7 _8 y) P r( v% O- m: W7 A - VS_SPI_ReadWriteByte(0x00);+ I% @2 A# T* n' D2 i- g
- VS_SPI_ReadWriteByte(0x00);0 z+ q) O- u8 W5 {8 G* C
- delay_ms(100);
$ K+ {. ^7 k+ J5 u0 [% f1 N - VS_XDCS=1;
6 n) K1 Z& i% H1 I - /* 向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 - VS_HD_Reset(); /* 硬件复位 */
4 v3 ]% i3 j+ B+ v4 Z, g; R - VS_WR_Cmd(0x0b,0X5050); /* 设置音量,值越小声音越大 */
; P1 r$ Z, Z4 w; ~( j! q( W - VS_WR_Cmd(SPI_MODE,0x0820); /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */ 2 w* n4 @; H$ k3 i
- while(VS_DQ==0); /* 等待DREQ为高 */
9 v4 \5 m9 A N - VS_SPI_SpeedLow(); /* 低速模式 */# e9 F: u; }+ U& L* U) A
- VS_XDCS=0; /* 选中数据传输 */
. Z4 j* V- A& R( o2 W) i; O - VS_SPI_ReadWriteByte(0x53);
- T$ x/ L' o4 D1 n" }- y$ E2 T - VS_SPI_ReadWriteByte(0xef);. S' k) B3 e2 N- n( H6 y f* f
- VS_SPI_ReadWriteByte(0x6e);
- W1 E: n8 {+ N# z6 e - VS_SPI_ReadWriteByte(0x22);
G$ M% m' t- l# e: z7 Z# F/ t - VS_SPI_ReadWriteByte(0x00);! }# D- ~. v) r
- VS_SPI_ReadWriteByte(0x00);
# q D+ c( v, z - VS_SPI_ReadWriteByte(0x00);2 C# m' h6 W9 t J4 V5 i8 i+ t1 I
- VS_SPI_ReadWriteByte(0x00);3 Z- O7 t- [. L J9 Z
- delay_ms(400);6 V/ }9 \9 H) \; G( J# c
- VS_XDCS=1;. E! K) d7 N7 b, i1 `/ N7 s
- /* 退出正弦测试 */( O6 v5 m& M# v# @/ T
- VS_XDCS=0; /* 选中数据传输 */( N" J7 |% I/ `
- VS_SPI_ReadWriteByte(0x45);/ S1 ^3 Q5 e5 L; u O/ A5 S
- VS_SPI_ReadWriteByte(0x78);
4 o1 h, l/ s: r5 K2 T - VS_SPI_ReadWriteByte(0x69);, m/ N8 d/ j, o0 p+ Z: ^, e' O
- VS_SPI_ReadWriteByte(0x74);, Q& e2 J% N1 K& A
- VS_SPI_ReadWriteByte(0x00);
L4 g5 q) a6 y3 S - VS_SPI_ReadWriteByte(0x00);
2 Q! J- r: y, q: x8 H4 s, ^ - VS_SPI_ReadWriteByte(0x00);
- A1 z0 o) g" ^1 \9 S7 H - VS_SPI_ReadWriteByte(0x00);0 B$ l5 W Q9 r( t5 F. W8 l
- delay_ms(100);
' G) _( N0 ~* T5 G7 } - VS_XDCS=1; ( U9 }; \& r5 }0 x$ ~6 x
- }) } h( z, C5 B, c
' O# i4 K% k/ K. R3 V3 t6 `* v" j: f- /**********************************************************************
. Z; w+ {8 {( V! | A - 函数名称:u16 VS_Ram_Test()$ @0 X/ y! p# H) z* t/ M
- 函数功能:RAM测试 ! c) j2 y( a! U
- 入口参数:无
& c+ S4 B1 r& b" J( x - 返回参数:u16 RAM测试结果,VS1003若得到0x807F,则表明完好,VS1053则为0X83FF
* i+ {- I& W/ G5 q9 u/ w. R - 解读作者:Aaron# N& ~% D' w! K
- ***********************************************************************/0 x0 z4 [; \9 p+ W, E( }
- u16 VS_Ram_Test(void)
3 ~+ A- `' j/ B# o# U - {
8 |; v, L7 n N( _" ` - VS_HD_Reset(); /* 硬件复位 */ ( P) \! ?3 x% \$ F T( V$ k
- VS_WR_Cmd(SPI_MODE,0x0820); /* 进入VS10XX的测试模式 */7 g0 ^; R* c+ W- G$ _
- while (VS_DQ==0); /* 等待DREQ为高 */
- B9 F ]. g1 [5 z$ F - VS_SPI_SpeedLow(); /* 低速 */ ! f- W, I; [5 e8 _, Y2 S- ^
- VS_XDCS=0; /* xDCS = 1,选择VS10XX的数据接口 *// b( I* `3 Z$ G% {& Q0 i
- VS_SPI_ReadWriteByte(0x4d);
8 Z) v. h) k6 J# z5 ~ - VS_SPI_ReadWriteByte(0xea);
; ]# ]% I: @! K1 \' ?4 B8 @ - VS_SPI_ReadWriteByte(0x6d);
/ j3 a' ] O7 K5 t" t3 f1 Y- P) v4 L - VS_SPI_ReadWriteByte(0x54);
% C! \* V2 M. L% p! B - VS_SPI_ReadWriteByte(0x00);) _6 }- Z# x5 V9 |* F* _
- VS_SPI_ReadWriteByte(0x00);% O' z$ V* V- Q/ o' s) s
- VS_SPI_ReadWriteByte(0x00);0 `- C2 b% ^: }; i
- VS_SPI_ReadWriteByte(0x00);9 b0 A2 K C5 \9 Z. x+ j
- delay_ms(150);
* q4 \$ `/ [/ l6 s$ Z4 L3 ?0 J5 \ - VS_XDCS=1;
/ @' X, k7 C5 p6 \* i5 H( W; d5 K - return VS_RD_Reg(SPI_HDAT0); /* VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF */
, [- [3 C9 F+ v c - }
复制代码
* 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- /************************************************
/ y- X$ b& \5 F& k! o - 函数名称:int main()" }9 s4 l$ f9 y
- 函数功能:主函数
% ~4 v' U; b p0 I+ R - 入口参数:无, s/ d* M' W8 p/ Z+ A
- 返回参数:int9 Y9 |5 M& j0 a$ U3 E
- 解读作者:Aaron
* m- M; \6 _6 Q' p% z7 I5 w- C - *************************************************/
u" `. [* q3 x) Z - int main(void)
+ L: X! A4 n$ z# Y& `0 e - { 3 P( A. L4 u, O t% ?8 `) q: x! V' z% v
- delay_init();
3 H% e) `+ a. b( ~* ?" _ - NVIC_Configuration();
+ H) H5 s+ b! I$ j' I2 c - LED_Init();
! W& N$ x% i" }# M6 E, u - KEY_Init();
: u) a1 [# B1 R8 S% e - My_USART1_Init(); 6 D6 E0 P+ y+ `- I* Y. L& a- p
- VS_Init(); /* 包含对SPI1初始化 */
0 C2 m4 c3 W7 y" P$ V - printf("存储器测试:%d\r\n",VS_Ram_Test());
1 j6 a/ u/ y/ f" K3 O. j0 h - while(1)
4 n/ i$ _% l5 h( c& d - {
, i. k# r* `/ W9 t2 y3 S% U F3 q - DS0=0;
b% j+ z! @3 z" L5 B |* y - printf("开始播放单频信号\r\n");
1 f) a8 C9 A" R- C+ F* b - VS_Sine_Test();
( ^- D, Z! o" r- o' c* S( k) k - delay_ms(1000); % L; Z8 n# }4 o3 p
- DS0=1;
& l% X/ J& K( W" H - delay_ms(1000);
* x" Q3 U7 ?3 l% I+ u( j - } + O$ M% t( f5 _5 w& _
- }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
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
|