本帖最后由 smog 于 2014-10-23 17:29 编辑
程序在stm32f103上运行是没问题的,vs1003也正常播放,但我移植到stm32f407上,正弦测试可以,但播放音乐时就好像快进了一样,声音噼噼啪啪的响,30秒左右就播放完一首歌了,移植上就只改了IO的配置!
看了很久也没找出是哪里的问题!
贴上移植前后的代码,大家帮我看看怎么回事?
移植前的初始化代码(stm32f103):
//SPI1初始化
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );//PORTB,SPI2时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PA5.6.7复用推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PA5.6.7上拉
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //选择了串行时钟的稳态:时钟悬空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第二个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为16
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
SPI1_ReadWriteByte(0xff);//启动传输
}
//初始化VS10XX的IO口
void VS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PC13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PE6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
//PF6,PF7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOF, &GPIO_InitStructure);
SPI1_Init();
}
移植后的初始化代码(stm32f407):
//SPI1初始化
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//PORTB,SPI1时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 配置PA5、PA6、PA7链接到SPI1 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //PA5.6.7复用推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PA5.6.7上拉
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //选择了串行时钟的稳态:时钟悬空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第二个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为16
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
SPI1_ReadWriteByte(0xff);//启动传输
}
//初始化VS10XX的IO口
void VS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PC13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PE6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
//PF6,PF7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOF, &GPIO_InitStructure);
SPI1_Init();
}
主函数:
int main()
{
u32 total,free;
u16 res;
u8 *databuf;
u32 i;
DIR dir; //声明目录结构体,保存要打开的
FILINFO fileinfo;//文件状态结构体
u8 *pname;//带路径文件名
u8 *file_name;//长文件名
GPIO_InitTypeDef GPIO_InitStructure;
// SysClockSet(HSE,21);//外部时钟,168MHz
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); /*使能LED灯使用的GPIO时钟*/
/* Configure LED Pins in output pushpull mode */
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_ResetBits(GPIOF,GPIO_Pin_8|GPIO_Pin_9);/*关闭所有的LED指示灯*/
mem_init(SRAMIN); //初始化内部内存池
delay_init();
usart1_init(9600);
TIM3Init(5000,16800);
VS_Init(); //初始化VS1003
VS_Sine_Test();
printf("
系统时钟:%dMHz
",SysClockGet()/1000000);
while(SD_Init() != SD_OK)
{
printf("SD Error!
");
delay_ms(2000);
delay_ms(1000);
}
exfuns_init(); //为fatfs相关变量申请内存
f_mount(0,fs[0]); //挂载SD卡
while(exf_getfree("0:",&total,&free)) //得到SD卡的总容量和剩余容量
{
printf("Fatfs Error!
");
delay_ms(1000);
}
printf(" SD卡总内存 : %d MB
",total>>10);
delay_ms(100);
printf("SD卡可用内存 : %d MB
",free>>10);
delay_ms(100);
databuf=(u8*)mymalloc(SRAMIN,4096); //开辟4096字节的内存区域
if(databuf==NULL) //内存申请失败.
while(1)
{
printf("memery Error!
");
delay_ms(1000);
}
VS_Sine_Test();
fileinfo.lfsize=_MAX_LFN*2+1; //长文件名最大长度
fileinfo.lfname=mymalloc(SRAMIN,fileinfo.lfsize); //为长文件缓存区分配内存
pname=mymalloc(SRAMIN,fileinfo.lfsize); //为带路径的文件名分配内存
file_name=mymalloc(SRAMIN,fileinfo.lfsize); //为长文件名分配内存
while(f_opendir(&dir,"0:/MUSIC")!=FR_OK);//打开音乐文件夹
while(1)
{
loop:
while(f_readdir(&dir,&fileinfo)==FR_OK) //读目录信息到文件结构体
{
if(fileinfo.fname[0]!=NULL)
{
file_name=(u8*)(*fileinfo.lfname?fileinfo.lfname:fileinfo.fname); //获取文件名
printf("文件名:%s
",file_name);
delay_ms(500);
res=f_typetell(file_name); //获得文件后缀
printf("文件属性:%x
",fileinfo.fattrib);
delay_ms(200);
if((res&0XF0)!=0X40)//取高四位,看看是不是音乐文件
goto loop;//如果不是音乐文件,读取下一个文件
strcpy((char*)pname,"0:/MUSIC/"); //复制路径(目录)
strcat((char*)pname,(const char*)file_name); //将文件名接在后面
VS_Restart_Play(); //重启播放
VS_Set_All(); //设置音量等信息
VS_Reset_DecodeTime(); //复位解码时间
res=f_open(file1,(const TCHAR*)pname,FA_READ);//打开文件
if(res==0)//打开成功.
{
VS_SPI_SpeedHigh(); //高速
do
{
res=f_read(file1,databuf,4096,(UINT*)&br);//读出4096个字节
i=0;
do//主播放循环
{
if(VS_Send_MusicData(databuf+i)==0)//给VS10XX发送音频数据
{
i+=32;
LED1=0;
}
else
{
LED1=1;
}
}while(i<4096);//循环发送4096个字节
}while(br==4096);
f_close(file1);
}
else
{
printf("mp3 Error!
");
delay_ms(1000);
}
}
else
while(f_opendir(&dir,"0:/MUSIC")!=FR_OK);//重新打开音乐文件夹
}
}
}
这句里面发送文件数据和DREQ脚的脉冲对上了么?感觉问题应该在这里。
u8 VS_Send_MusicData(u8* buf)
{
u8 n;
if(VS_DQ!=0) //送数据给VS10XX
{
VS_XDCS=0;
for(n=0;n<32;n++)
{
VS_SPI_ReadWriteByte(buf[n]);
}
VS_XDCS=1;
}else return 1;
return 0;//成功发送了
}
这个程序在F103上运行过,是没有问题的,我怀疑的是配置上那里错了
每次读取数据大于1k,数据就乱了,还没清楚为什么会这样,F1是用spi读写SD卡的,F4是用SDIO读写SD卡的
一周热门 更多>