【语音平台开发进程】:VS1053B芯片的SPI驱动程序编写完成
经过近一周的编写和调试,昨天,正式将VS1053B芯片的SPI驱动程序编写和调试完毕,在编写和调试的过程中也吸取了许多经验和教训,现总结如下:
1、首先,用最原始的方法在主函数里先将SPI对VS1053B芯片的简单控制实现。
2、在最原始的方法上对上述控制进行头文件的简单改写,采用边改写,边调试的方法,这一步目的不再于要实现多么强大的驱动功能,而在于将整个驱动的整体框架搭建起来,以便于在下一步中在向其中添加功能的同时,而又不破坏整个架构的完整性。
3、一步步按照预先的规划逐步完善程序的功能,同样也是边编写边调试。
4、最后,整理出正个驱动程序,写出Demo主程序测试函数,以便于演示和测试。
下面将编写好的驱动程序贴于下面,以便于大家学习和提出宝贵的意见和建议:
VS1053B.h头文件程序:
#ifndef __VS10XX_H__
#define __VS10XX_H__
#include <rxduino.h>
#define SPI_MODE 0x00
#define SPI_STATUS 0x01
#define SPI_BASS 0x02
#define SPI_CLOCKF 0x03
#define SPI_DECODE_TIME 0x04
#define SPI_AUDATA 0x05
#define SPI_WRAM 0x06
#define SPI_WRAMADDR 0x07
#define SPI_HDAT0 0x08
#define SPI_HDAT1 0x09
#define SPI_AIADDR 0x0a
#define SPI_VOL 0x0b
#define SPI_AICTRL0 0x0c
#define SPI_AICTRL1 0x0d
#define SPI_AICTRL2 0x0e
#define SPI_AICTRL3 0x0f
#define VS_DQ PIN_P23 //DREQ
#define VS_RST PIN_P22 //RST
#define VS_XCS PIN_PC4 //XCS--SPI_CS0--IO10
#define VS_XDCS PIN_PC1 //XDCS--SPI_CS2--IO23
unsigned int VS_RD_Reg(unsigned char address);
void VS_WR_Data(unsigned long data);
void VS_WR_Data_Test(unsigned long data);
void VS_WR_Cmd(unsigned char address,unsigned int data);
void VS_Init(void);
void VS_HD_Reset(void);
void VS_Soft_Reset(void);
void VS_Ram_Test(void);
void VS_Sine_Test(void);
void Set1053B(void);
unsigned int GetDecodeTime(void);
void ResetDecodeTime(void);
unsigned int GetHeadInfo(void);
#endif
VS1053B.cpp,作为VS1053B.h的功能实现函数库
#include "VS1053B.h"
#include <spi.h>
//#include <rxduino.h>
unsigned char VS1053Bram[5]={2,10,2,6,250};
unsigned long SPItemp;
const unsigned int bitrate[2][16]=
{
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}
};
unsigned int GetHeadInfo(void)
{
unsigned int HEAD0;
unsigned int HEAD1;
HEAD0=VS_RD_Reg(SPI_HDAT0);
HEAD1=VS_RD_Reg(SPI_HDAT1);
//printf("(H0,H1):%x,%x\n",HEAD0,HEAD1);
switch(HEAD1)
{
case 0x7665:return 0;//WAV格式
case 0X4D54:return 1;//MIDI格式
case 0X574D://WMA格式
{
HEAD1=HEAD0*2/25;
if((HEAD1%10)>5)return HEAD1/10+1;
else return HEAD1/10;
}
default://MP3格式
{
HEAD1>>=3;
HEAD1=HEAD1&0x03;
if(HEAD1==3)HEAD1=1;
else HEAD1=0;
return bitrate[HEAD1][HEAD0>>12];
}
}
}
void VS_WR_Cmd(unsigned char address,unsigned int data)
{
unsigned long WRCmdreg;
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS0_DUINO;
//SPI.setClockDivider(SPI_CLOCK_DIV64);
WRCmdreg=(0x02<<24)+(address<<16)+data;
SPItemp=SPI.transfer(WRCmdreg);
}
unsigned int VS_RD_Reg(unsigned char address)
{
unsigned long RDreg;
unsigned int RDregreturn;
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS0_DUINO;
RDreg=(0x03<<24)+(address<<16);
SPItemp=SPI.transfer(RDreg);
RDregreturn = (unsigned int) SPItemp;
return RDregreturn;
}
unsigned int GetDecodeTime(void)
{
return VS_RD_Reg(SPI_DECODE_TIME);
}
void ResetDecodeTime(void)
{
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
}
void VS_WR_Data(unsigned long data)
{
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV64);
SPI.port=SPI_PORT_CS2_MARY2;
SPItemp=SPI.transfer(data);
}
void VS_WR_Data_Test(unsigned long data)
{
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS2_MARY2;
SPItemp=SPI.transfer(data);
}
void VS_Sine_Test(void)
{
VS_HD_Reset();
VS_WR_Cmd(SPI_VOL,0X0505);
VS_WR_Cmd(SPI_MODE,0x0820);
while(VS_DQ== 0);
VS_WR_Data_Test(0x53ef6e2400000000);
delay(500);
VS_WR_Data_Test(0x4578697400000000);
delay(500);
VS_WR_Data_Test(0x53ef6e4400000000);
delay(500);
VS_WR_Data_Test(0x4578697400000000);
delay(500);
}
void VS_Ram_Test(void)
{
unsigned int regvalue;
VS_HD_Reset();
VS_WR_Cmd(SPI_MODE,0x0820);
while (VS_DQ==0); // 等待DREQ为高
VS_WR_Data_Test(0x4dea6d5400000000);
delay(500);
regvalue=VS_RD_Reg(SPI_HDAT0);
Serial.println(regvalue, BIN); //output the result in HEX
delay(500);
regvalue=VS_RD_Reg(SPI_MODE);
Serial.println(regvalue, BIN); //output the result in HEX
}
void VS_Init(void)
{
pinMode(VS_XCS,OUTPUT);
pinMode(VS_RST,OUTPUT);
pinMode(VS_DQ,INPUT);
digitalWrite(VS_RST,0);
delay(500);
digitalWrite(VS_RST,1);
delay(500);
SPI.begin();
//Serial.begin(9600); //set baudrate 9600bps
SPI.port=SPI_PORT_CS0_DUINO;
SPI.setBitOrder(MSBFIRST);
SPI.setBitLength(32);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setDataMode(SPI_MODE0);
}
void VS_Soft_Reset(void)
{
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS0_DUINO;
VS_WR_Cmd(SPI_MODE,0X0804);
delay(3);
while(digitalRead(VS_DQ)==0);
VS_WR_Cmd(SPI_CLOCKF,0x7800);
VS_WR_Cmd(SPI_AUDATA,0xBB81);
}
void VS_HD_Reset(void)
{
digitalWrite(2,0);
delay(2000);
digitalWrite(VS_XDCS,1);
digitalWrite(VS_XCS,1);
digitalWrite(VS_RST,1);
}
void Set1053B(void)
{
unsigned char t;
unsigned int bass=0;
unsigned int volt=0;
unsigned char vset=0;
vset=255-VS1053Bram[4];
volt=vset;
volt<<=8;
volt+=vset;
//0,henh.1,hfreq.2,lenh.3,lfreq
for(t=0;t<4;t++)
{
bass<<=4;
bass+=VS1053Bram[t];
}
VS_WR_Cmd(SPI_BASS,bass);//BASS
//delay(50);
VS_WR_Cmd(SPI_VOL,volt);
}