历史上的今天
返回首页

历史上的今天

今天是:2024年09月10日(星期二)

正在发生

2018年09月10日 | STM8L151 使用硬件SPI驱动VS1003B MP3解码芯片

2018-09-10 来源:eefocus

该如何使用STM8L的硬件SPI去驱动VS1003B?

这个问题分两部分来思考,一是STM8L的SPI部分该如何配置以及与VS1003B相连的控制管脚该如何配置,二是关于VS1003B的时序以及指令使用。

由于STM8L的SPI部分与VS1003B的SPI部分进行相互通信,先看看VS1003B的SPI特性,才能对STM8L进行配置。

在VS1003B中SPI模式定义如下:

其中XDCS为发送MP3数据是的芯片控制管脚,XCS为发送VS1003B指令的控制管脚,在手册中亦有对SPI通信速度的说明,见下图:


上图中CLKI在手册中为:36.864Mhz

故上面SPI的通信速率在6.144MHz-9.216MHz之间,但在本例中根据6.144MHz来配置,在STM8L中主频最高为16MHz,故可以4分频得到4M的SPI速率,但在实际测试中,发现4分频后通信有时会失败,于是改为8分频降低通信速率,故SPI以及VS1003的控制管脚的配置如下:


CLK_PeripheralClockConfig(CLK_Peripheral_SPI1, ENABLE);

//SPI_CLOCK:PB5, SPI_MOSI: PB6, SPI_MISO: PB7

GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast);

GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast);

//主机模式,配置为输入

GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT);

/* 初始化SPI */

SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_8, SPI_Mode_Master,\

SPI_CPOL_Low, SPI_CPHA_1Edge, \

SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07);

SPI_Cmd(SPI1, ENABLE); /* 使能SPI */  

    /* 输入 */

GPIO_Init(VS_1003_DREQ_PORT, VS_1003_DREQ_PIN, GPIO_Mode_In_PU_No_IT);

GPIO_Init(VS_1003_XRST_PORT, VS_1003_XRST_PIN, GPIO_Mode_Out_PP_High_Fast);

    /* 推挽输出 */

GPIO_Init(VS_1003_XDCS_PORT, VS_1003_XDCS_PIN, GPIO_Mode_Out_PP_High_Fast);

    /* 推挽输出 */

GPIO_Init(VS_1003_XCS_PORT, VS_1003_XCS_PIN, GPIO_Mode_Out_PP_High_Fast);

当数据总线传送的是指令数据时,此时的通信协议在VS1003B中称为SCI,该协议的发送时序图如下:


根据上面这个时序图,SCI的Read函数如下面所示:

uint8_t VS1003_ReadByte(void)

{

    /* Loop while DR register in not emplty */

 while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);

 /* Send byte through the SPI1 peripheral */

 SPI_SendData(SPI1, 0);

 /* Wait to receive a byte */

 while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);

 /* Return the byte read from the SPI bus */

return SPI_ReceiveData(SPI1);                

}

uint16_t VS1003_ReadRegister(uint8_t addressbyte)

{

uint16_t resultvalue = 0;

XDCS_SET(1);          

XCS_SET(0);              

VS1003_WriteByte(VS_READ_COMMAND);                   //发送读寄存器命令

VS1003_WriteByte((addressbyte));                 //发送寄存器的地址

resultvalue = (uint16_t)(VS1003_ReadByte() << 8);   //读取高8位数据

resultvalue |= VS1003_ReadByte();                     //读取低8位数据

XCS_SET(1);                      

return resultvalue;//返回16位寄存器的值                                 

}

SCI 写的时序如下图:


根据该时序图,SCI的Write函数如下:

uint8_t VS1003_WriteByte( uint8_t byte )

{

  /* Loop while DR register in not emplty */

 while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);

 /* Send byte through the SPI1 peripheral */

 SPI_SendData(SPI1, byte);

 /* Wait to receive a byte */

 while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);

 /* Return the byte read from the SPI bus */

return SPI_ReceiveData(SPI1);  

void VS1003_WriteRegister(uint8_t addressbyte, uint8_t highbyte, uint8_t lowbyte)

{

XDCS_SET(1);  //拉高XDCS电平

XCS_SET(0);   //拉低XCS电平   

VS1003_WriteByte( VS_WRITE_COMMAND );//发送写指令字节

VS1003_WriteByte( addressbyte );//发送地址字节

VS1003_WriteByte( highbyte ); //发送数据字的高字节

VS1003_WriteByte( lowbyte ); //发送数据字的低字节

XCS_SET(1); //拉高XCS电平    

}

接下来对VS1003B进行初始化操作:


void VS1003_Init(void)

{

uint8_t BassEnhanceValue = 0x00;      // 低音值先初始化为0

uint8_t TrebleEnhanceValue = 0x00;      // 高音值先初始化为0

RST_SET(0);            

Delayms( 10 );                         // 10ms

VS1003_WriteByte(0xff);                   // 发送一个字节的无效数据,启动SPI传输

XDCS_SET(1);        

XCS_SET(1);          

RST_SET(1);            

Delayus( 1000 );            

  VS1003_WriteRegister( SPI_MODE,0x08,0x00);   // 进入VS1003的播放模式

VS1003_WriteRegister(3, 0x98, 0x00);      // 设置vs1003的时钟,3倍频

VS1003_WriteRegister(5, 0xBB, 0x81);      // 采样率48k,立体声

VS1003_WriteRegister(SPI_BASS, TrebleEnhanceValue, BassEnhanceValue);// 设置重低音

VS1003_WriteRegister(0x0b,0x00,0x00);                               // VS1003 音量

Delayus( 1000 );

while( DREQ == 0 );          // 等待DREQ为高  表示能够接受音乐数据输入

}

在VS1003B中有几种测试模式,如Sine Test、Pin Test、Memory Test,下面就贴一个Sine Test的函数:


void VS1003_TestSIN(void)

{

VS1003_WriteRegister(SCI_MODE, 0x08, 0x20);

while( DREQ == 0);

XDCS_SET(0);

VS1003_WriteByte(0x53);

VS1003_WriteByte(0xef);

VS1003_WriteByte(0x6e);

VS1003_WriteByte(0x44);

VS1003_WriteByte(0x00);

VS1003_WriteByte(0x00);

VS1003_WriteByte(0x00);

VS1003_WriteByte(0x00);

XDCS_SET(1);

XDCS_SET(0);

VS1003_WriteByte(0x45);

VS1003_WriteByte(0x78);

VS1003_WriteByte(0x69);

VS1003_WriteByte(0x74);

VS1003_WriteByte(0x00);

VS1003_WriteByte(0x00);

VS1003_WriteByte(0x00);

VS1003_WriteByte(0x00);

XDCS_SET(1);

while( DREQ == 0);

}

到这里,如果正弦测试正常通过,那么基本上完成了对VS1003B的使用。


推荐阅读

史海拾趣

Banner Engineering公司的发展小趣事

Banner Engineering公司成立于XXXX年,起初主要致力于传感器技术的研发和生产。在公司初创时期,面临着激烈的市场竞争和技术挑战。然而,公司凭借其创新的思维和技术实力,成功开发出一系列具有高精度、高可靠性的传感器产品,迅速在市场中获得了认可。这些传感器产品在工业自动化、机器人技术等领域得到了广泛应用,为Banner Engineering公司的初步发展奠定了坚实基础。

Excellence Optoelectronics Inc公司的发展小趣事

EOI深知客户的重要性,因此公司一直致力于提供优质的服务。无论是售前咨询还是售后服务,EOI都认真对待每一个客户的需求和问题。公司建立了完善的客户服务体系,为客户提供及时、专业的支持。同时,EOI还定期举办客户培训和技术交流活动,提高客户的技术水平和使用效果。这些努力使得EOI赢得了客户的信任和忠诚度。

富瀚(Fullhan)公司的发展小趣事
设计紧凑合理,安装简便快捷;同时提供清晰的故障指示和便捷的维护接口,方便用户进行日常维护和故障排除。
康奈特(CNNT)公司的发展小趣事

康奈特一直致力于拓展全球市场。公司通过参加国际展会、与海外经销商建立合作关系等方式,不断提升品牌在国际市场的知名度和影响力。同时,公司还针对不同国家和地区的市场需求和文化差异,推出了定制化的产品和服务。这些举措不仅帮助公司成功进入了多个海外市场,也为公司带来了丰厚的利润回报。

BVLED公司的发展小趣事

随着公司规模的扩大和业务范围的拓展,BVLED公司开始注重产业链的整合和成本控制。公司通过与上游供应商建立长期稳定的合作关系,确保了原材料的稳定供应和质量保障;同时,公司还加强了对生产过程的监控和管理,通过优化生产流程和降低能耗等方式降低了生产成本。这些措施使得公司在激烈的市场竞争中保持了较强的竞争力。

广东华裕(GDHY)公司的发展小趣事

为了进一步扩大市场份额和提升品牌影响力,BVLED公司开始积极拓展国内外市场。在国内,公司加强了与大型照明企业的合作,通过联合推广和定制服务等方式提高了产品知名度。在国外,公司积极参加国际展览和贸易洽谈会,与国际知名企业建立了合作关系,成功打开了国际市场的大门。

问答坊 | AI 解惑

数字集成电路设计入门--从HDL到版图

数字集成电路设计入门7 @4 q; c  e5 s --从HDL到版图 于敦山 北大微电子学系( G. n# y9 N8 T+ B/ F …

查看全部问答>

LED通电电流不变,电压逐渐降低

今天调试反激电源的时候发现一个问题: 4*1W的LED通电电流不变350MA,压降13.2V;随着通电时间的增加,电压逐渐降低到12.5V; 这种情况是不是可以解释为 :是不是 LED的阀门电压时随着温度的身高而降低;  …

查看全部问答>

1个16按键 的程序问题。

   今天很郁闷,话了很久写了个程序,就是按下16个矩阵键盘依次在数码管上显示1-16的平方。如按下第一个显示1,第二个显示4...    但是怎么只就显示第一个 到  第8个键呢,就是 是显示001 到081, 到案第十个键的时 ...…

查看全部问答>

WINCE 动画显示窗体问题

wince 下如何实现类似windows xp下用AnimateWindow 显示窗体的效果…

查看全部问答>

有没有谁用过OSEK/VDX相关的RTOS?有那些?是否有源码的?

有没有谁用过OSEK/VDX相关的RTOS?有那些?是否有源码的?用于那种目标CPU?…

查看全部问答>

基于arm的毕业设计课题!

老师让我们吧毕业设计的课题报上去,我想做arm方面的, 谁有这方面的课题,指导一下哈!!!…

查看全部问答>

这些汇编器分别是哪些公司出的?有啥区别?那个最好?

这些汇编器分别是哪些公司出的?有啥区别?那个最好? 80C51单片机常用的汇编器有:ASM51.EXE、A8051.EXE、MCS51.EXE和A51.EXE…

查看全部问答>

8kHz/16bits PCM 语音回放失真问题

   最近做一个语音播放的东东,8KHz/16bits PCM 语音信号经过一个16bitPCM DAC 以8KHz的sampling rate playback.发现语音失真很严重,还伴随有噪音.人的语音都变调了很难听.小弟以前没做过语音相关的,不知道怎么解决?还望各位帮忙.   ...…

查看全部问答>

很火的电容触控,有了解的吗

电容触控很火,目前很多手机都用了电容触控屏,我们这些做小家电的总是后知后觉,现在才计划在下半年的新款电磁炉上改用电容触控代替之前的机械按钮(机械按钮是返修率和投诉率最高的部件,我个人举双手赞成更换新触摸技术),筒子们有什么好的方案 ...…

查看全部问答>

用到"LM5002"芯片和"STP5NK50ZFP"MOS管,遇到问题,求助

我在设计的时候,用到了LM5002芯片。我建的电路图是按照该芯片的datasheet里应用电路的最后一张图(输入是3.1 - 60VDC,输出是12VDC) 问题是,在输入端我提供了一个电源,然后用两个电阻分压控制电压值供给LM5002(测试的电阻值在1K - 500K欧,测 ...…

查看全部问答>