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

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

[复制链接]
STMCU小助手 发布时间:2022-11-18 22:00
主要内容:
1) 硬件连接;
2) VS1053简介;
3) 相关实验及其代码解读。
实验功能:程序开启后,系统先进行RAM测试,再进行正弦测试,可以接耳机听到所设的单频声音。备注:音乐播放实验还未深入研究,本章内容不涉及。

硬件连接:如下图所示:

20201025205213346.png

VS1053与STM32F103ZET6芯片的连接关系如下:
1) VS_MISO→PA6;
2) VS_MOSI→PA7;
3) VS_SCK→PA5;
4) VS_XCS→PF7;
5) VS_XDCS→PF6;
6) VS_DREQ→PC13;
7) VS_RST→PE6。
备注:PA5/PA6/PA7,即:STM32的SPI1;SPK_CTRL,控制板载喇叭(输入到HT6872)!由程序控制。

1. VS1053简介
1.1 VS1053是继VS1003后荷兰VLSI公司推出的又一款高性能编解码芯片。该芯片可对MP3/OGG/WMA/FLAC/WAV/AAC/MIDI等音频格式解码,同时还支持ADPCM/OGG等格式的编码,性能相对VS1003提升不少。
VS1053拥有一个高性能的DSP处理器核VS_DSP,16K的指令RAM,0.5K的数据RAM,通过SPI控制,具有8个可用的通用IO口和一个串口,芯片内部还带了一个可变采样率的立体声ADC(支持咪头或线路输入)、一个高性能立体声DAC及音频耳机放大器。

1.2 特点
1) 支持OGG/MP3/WMA/WAV/FLAC(需加载patch)/MIDI/AAC等格式解码;
2) 支持OGG(需加载patch)/IMA ADPCM编码;
3) 支持音量调节、高低音控制和EarSpeaker空间效果;
4) 自带高性能立体声ADC和DAC,音质比VS 1003好很多;
5) 自带耳机驱动器,可驱动30欧负载的耳机;
6) 自带8个GPIO,可用于控制外设/作为I2S接口(外接DAC );
7) 通过SPI接口控制/传输数据,接口简单;
8) 可通过加载patch,实现新功能添加;
9) 低功耗 。

1.3 接口介绍
VS1053通过SPI接口来接受输入的音频数据流,它可以是一个系统的从机,也可以作为独立的主机。本例程,我们把它当成从机使用。我们通过SPI口向VS1053不停的输入音频数据,它就会自动帮我们解码了,然后从输出通道输出音乐,这时我们接上耳机就能听到所播放的歌曲了。
VS1053通过7根线同MCU连接,如下:
VS_RST:VS1053的复位信号线,低电平有效;
VS_DREQ:数据请求信号(高电平有效),用来通知主机,VS1053是否可以接收数据;
VS_XCS:命令片选(低电平有效);
VS_XDCS:数据片选(低电平有效);
VS_MISO、VS_MOSI和VS_SCK:SPI信号线。

1.4 VS1053工作模式
VS1053的SPI支持两种工作模式:
1,VS1002有效模式(即新模式);
2,VS1001兼容模式。
这里仅介绍VS1002有效模式(此模式也是VS1053的默认模式)。在新模式下VS1053的SPI信号线功能描述如下表所示:

2020102520553924.png

VS1053的SPI数据传送,分为SDI和SCI,分别用来传输数据/命令。SDI采用SPI协议,不过,数据传输受DREQ控制,主机在判断DREQ有效(高电平)之后,直接发送数据即可(一次可以发送32个字节)。

1.5 VS1053之SCI命令传输介绍
SCI串行总线命令接口包含了一个指令字节、一个地址字节和一个16位的数据字。读写操作可以读写单个寄存器,在SCK的上升沿读出数据位,所以主机必须在下降沿刷新数据。SCI的字节数据总是高位在前低位在后的。第一个字节指令字节,只有2个指令,也就是读和写,读为0X03,写为0X02。
SCI读时序如下图所示:

2020102520570422.png

SCI写时序如下图所示:

20201025205737881.png

写指令为:0X02,数据通过SI写入VS1053, SO则一直维持低电平。
注意:在读和写时序图中,DREQ信号上都产生了一个短暂的低脉冲,也就是执行时间,在写入和读出VS1053的数据之后,它需要一些时间来处理内部的事情,这段时间,是不允许外部打断的。所以,在SCI操作之前,最好判断一下DREQ是否为高电平,如果不是,则等待DREQ变为高。

2. VS1053寄存器介绍
2.1 VS1053的所有的SCI寄存器,如下表:

20201025205924828.jpg

2.2 MODE寄存器(0X00)

20201025210013379.png

SM_RESET:软件复位,建议在每播放一首歌曲之后,软复位一次。
SM_SDINEW:模式设置位,设置为1,选择VS1002新模式(本地模式)。
其他位的详细介绍,请参考:VS1053_cn.pdf。

2.3 BASS寄存器(0X02)

20201025210115913.png

该寄存器可以用于设置VS1053的高低音效,通过这个寄存器以上位的一些设置,我们可以随意配置自己喜欢的音效(其实就是高低音的调节)。
注意:EarSpeaker效果由MODE寄存器控制。

2.4 CLOCKF寄存器(0X03)

20201025210211236.png

该寄存器用来设置时钟频率、倍频等相关信息。其中:SC_FREQ是以4Khz为步进的一个时钟寄存器,当外部时钟是12.288M的时候,设置为0即可。
XTALI是外部晶振的时钟频率(单位为:Hz )。CLKI是内部时钟频率。由于我们使用的是12.288M的晶振,在这里设置此寄存器的值为0X9800,也就是设置内部时钟频率为输入时钟频率的3倍,倍频增量为1.5倍(0X9800=1001 1000 0000 0000)。

2.5 DECODE_TIME寄存器(0X04)
该寄存器是一个存放解码时间的寄存器,以秒钟为单位,我们通过读取该寄存器的值,就可以得到解码时间。不过,它是一个累计时间,在每首歌播放之前,需要把它清空一下,以得到这首歌的准确解码时间。

2.6 HDAT0&HDAT1寄存器(0X08&0X09)
这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。这两个寄存器的详细介绍,请参考:VS1053的数据手册(VS1053_cn.pdf)。

2.7 VOL寄存器(0X0B)
该寄存器用于控制VS1053的输出音量,该寄存器可以分别控制左右声道的音量,每个声道的控制范围为0~254,每个增量代表0.5db的衰减,所以该值越小,代表音量越大。比如设置为0X0000则音量最大,而设置为0XFEFE则音量最小。
注意:如果设置VOL的值为0XFFFF,将使芯片进入掉电模式!

3 VS1053初始化步骤
1) 复位VS1053
包括硬复位和软复位,让VS1053恢复初始状态,准备解码下一首歌曲。在每首歌曲播放之前都可以执行一次硬件复位和软件复位,以便更好的播放音乐。
2) 配置VS1053的相关寄存器
这里配置的寄存器包括VS1053的模式寄存器(MODE)、时钟寄存器(CLOCKF)、音调寄存器(BASS)、音量寄存器(VOL)等。

3) 发送音频数据
经过以上①、②配置以后,剩下来要做的事情,就是往VS1053里面发送音频数据,只要是VS1053支持的音频格式,直接往里面丢就可以了,VS1053会自动识别,并进行播放。不过,发送数据要在DREQ信号的控制下有序的进行,不能乱发。这个规则很简单:只要DREQ变高,就向VS1053发送32个字节。然后继续等待DREQ变高,直到音频数据发送完。

4. 部分源码讲解
4.1 VS1053低速2.25MHz,高速9MHz。

  1. /*******************************************************************************
  2. 函数名称:u8 VS_SPI_ReadWriteByte(u8 data)
  3. 函数功能:读写数据,移植用         
  4. 入口参数:u8 data:要写入的数据
  5. 返回参数:u8 读到的数据
  6. 解读作者:Aaron
  7. ********************************************************************************/
  8. u8 VS_SPI_ReadWriteByte(u8 data)
  9. {                             
  10.     return SPI1_ReadWriteByte(data);     
  11. }
  12. /* VS1053初始化时,需要低速 */
  13. void VS_SPI_SpeedLow(void)
  14. {                                                                    
  15.     SPI1_SetSpeed(SPI_BaudRatePrescaler_32);     /* 设置低速模式,72/32≈2.25MHz */
  16. }
  17. /* VS1053正常工作时,可以高速 */
  18. void VS_SPI_SpeedHigh(void)
  19. {                                                   
  20.     SPI1_SetSpeed(SPI_BaudRatePrescaler_8);      /* 设置高速模式,72/8=9MHz */               
  21. }
复制代码

这么设置的原因如下表(VS1053芯片手册):

20201025210704342.png

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。

5 相关实验代码解读
5.1 vs10xx.c部分代码(我修改了下)

  1. /**********************************************************************
  2. 函数名称:VS_Init()
  3. 函数功能:初始化VS10XX的IO口  
  4. 入口参数:无
  5. 返回参数:无
  6. 解读作者:Aaron
  7. ***********************************************************************/
  8. void VS_Init(void)
  9. {
  10. GPIO_InitTypeDef  GPIO_InitStructure;
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE);  /* 使能PC,PE,PF端口时钟 */
  12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;     
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          /* 上拉输入 */
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(GPIOC, &GPIO_InitStructure);                 /* 初始化PC13,对应VS_DREQ(数据请求信号) */
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */
  18. GPIO_Init(GPIOE, &GPIO_InitStructure);                 /* 初始化PE6,对应复位信号线 */      
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       /* 推挽输出 */
  21. GPIO_Init(GPIOF, &GPIO_InitStructure);                 /* 初始化PF6和PF7,对应VS_XDCS(数据片选)和VS_XCS(命令片选) */
  22. SPI1_Init();                                           /* 初始化SPI */
  23. }

  24. /**********************************************************************
  25. 函数名称:VS_Sine_Test()
  26. 函数功能:正弦测试   
  27. 入口参数:无
  28. 返回参数:无
  29. 解读作者:Aaron
  30. ***********************************************************************/
  31. void VS_Sine_Test(void)
  32. {               
  33. VS_HD_Reset();                /* 硬件复位 */
  34. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */
  35. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     
  36. while(VS_DQ==0);              /* 等待DREQ为高 */
  37. printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE));
  38. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00 其中n = 0x28=0b00101000, 即FS=48000Hz,频率=48000*8/128=3000Hz  */
  39. VS_SPI_SpeedLow();            /* 低速模式 */
  40. VS_XDCS=0;                    /* 选中数据传输 */
  41. VS_SPI_ReadWriteByte(0x53);
  42. VS_SPI_ReadWriteByte(0xef);
  43. VS_SPI_ReadWriteByte(0x6e);
  44. VS_SPI_ReadWriteByte(0x28);
  45. VS_SPI_ReadWriteByte(0x00);
  46. VS_SPI_ReadWriteByte(0x00);
  47. VS_SPI_ReadWriteByte(0x00);
  48. VS_SPI_ReadWriteByte(0x00);
  49. delay_ms(200);                /* 测试经验告诉我,延迟时间不能超过1s */
  50. VS_XDCS=1;
  51. /* 退出正弦测试 */
  52. VS_XDCS=0;                    /* 选中数据传输 */
  53. VS_SPI_ReadWriteByte(0x45);
  54. VS_SPI_ReadWriteByte(0x78);
  55. VS_SPI_ReadWriteByte(0x69);
  56. VS_SPI_ReadWriteByte(0x74);
  57. VS_SPI_ReadWriteByte(0x00);
  58. VS_SPI_ReadWriteByte(0x00);
  59. VS_SPI_ReadWriteByte(0x00);
  60. VS_SPI_ReadWriteByte(0x00);
  61. delay_ms(100);
  62. VS_XDCS=1;   
  63. /* 向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00其 中n = 0x22=0b001 00010, 即FS=48000Hz,频率=48000*2/128=750Hz  */
  64. VS_HD_Reset();                /* 硬件复位 */
  65. VS_WR_Cmd(0x0b,0X5050);       /* 设置音量,值越小声音越大 */
  66. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式,MODE寄存器,[位5]SM_TEST允许SDI测试,[位11]SM_SDINEW本地模式 */     
  67. while(VS_DQ==0);              /* 等待DREQ为高 */
  68. VS_SPI_SpeedLow();            /* 低速模式 */
  69. VS_XDCS=0;                    /* 选中数据传输 */      
  70. VS_SPI_ReadWriteByte(0x53);
  71. VS_SPI_ReadWriteByte(0xef);
  72. VS_SPI_ReadWriteByte(0x6e);
  73. VS_SPI_ReadWriteByte(0x22);
  74. VS_SPI_ReadWriteByte(0x00);
  75. VS_SPI_ReadWriteByte(0x00);
  76. VS_SPI_ReadWriteByte(0x00);
  77. VS_SPI_ReadWriteByte(0x00);
  78. delay_ms(400);
  79. VS_XDCS=1;
  80. /* 退出正弦测试 */
  81. VS_XDCS=0;                    /* 选中数据传输 */
  82. VS_SPI_ReadWriteByte(0x45);
  83. VS_SPI_ReadWriteByte(0x78);
  84. VS_SPI_ReadWriteByte(0x69);
  85. VS_SPI_ReadWriteByte(0x74);
  86. VS_SPI_ReadWriteByte(0x00);
  87. VS_SPI_ReadWriteByte(0x00);
  88. VS_SPI_ReadWriteByte(0x00);
  89. VS_SPI_ReadWriteByte(0x00);
  90. delay_ms(100);
  91. VS_XDCS=1;  
  92. }

  93. /**********************************************************************
  94. 函数名称:u16 VS_Ram_Test()
  95. 函数功能:RAM测试
  96. 入口参数:无
  97. 返回参数:u16 RAM测试结果,VS1003若得到0x807F,则表明完好,VS1053则为0X83FF
  98. 解读作者:Aaron
  99. ***********************************************************************/
  100. u16 VS_Ram_Test(void)
  101. {
  102. VS_HD_Reset();                /* 硬件复位 */
  103. VS_WR_Cmd(SPI_MODE,0x0820);   /* 进入VS10XX的测试模式 */
  104. while (VS_DQ==0);             /* 等待DREQ为高 */      
  105. VS_SPI_SpeedLow();            /* 低速 */
  106. VS_XDCS=0;                    /* xDCS = 1,选择VS10XX的数据接口 */
  107. VS_SPI_ReadWriteByte(0x4d);
  108. VS_SPI_ReadWriteByte(0xea);
  109. VS_SPI_ReadWriteByte(0x6d);
  110. VS_SPI_ReadWriteByte(0x54);
  111. VS_SPI_ReadWriteByte(0x00);
  112. VS_SPI_ReadWriteByte(0x00);
  113. VS_SPI_ReadWriteByte(0x00);
  114. VS_SPI_ReadWriteByte(0x00);
  115. delay_ms(150);  
  116. VS_XDCS=1;
  117. return VS_RD_Reg(SPI_HDAT0);  /* VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF */      
  118. }
复制代码

5.2 main.c主函数代码解读

  1. /************************************************
  2. 函数名称:int main()
  3. 函数功能:主函数
  4. 入口参数:无
  5. 返回参数:int
  6. 解读作者:Aaron
  7. *************************************************/
  8. int main(void)
  9. {  
  10.   delay_init();                                   
  11.   NVIC_Configuration();
  12.   LED_Init();      
  13.   KEY_Init();
  14.   My_USART1_Init();   
  15.   VS_Init();           /* 包含对SPI1初始化 */
  16.   printf("存储器测试:%d\r\n",VS_Ram_Test());
  17.   while(1)
  18.   {
  19.    DS0=0;        
  20.    printf("开始播放单频信号\r\n");
  21.    VS_Sine_Test();   
  22.    delay_ms(1000);  
  23.    DS0=1;
  24.    delay_ms(1000);  
  25.   }                  
  26. }
复制代码

实验结果
接上耳机,能听到200ms的3000Hz单频声,然后紧接着听到400ms的750Hz单频声。

20201025211948294.jpg

————————————————
版权声明:天亮继续睡


收藏 评论0 发布时间:2022-11-18 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

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