各位大神帮我看看:stm32f103+vs1003的代码移植到stm32f407就不行

2019-12-12 18:16发布

本帖最后由 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);//重新打开音乐文件夹
                       
                }
               
        }

       
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
天涯行客
1楼-- · 2019-12-12 18:55
帮顶!!!
heitu103
2楼-- · 2019-12-12 20:51
SPI的时序是不是比F1的快了?
wz18th
3楼-- · 2019-12-13 02:08
if(VS_Send_MusicData(databuf+i)==0)//给VS10XX发送音频数据
这句里面发送文件数据和DREQ脚的脉冲对上了么?感觉问题应该在这里。
smog
4楼-- · 2019-12-13 06:30
 精彩回答 2  元偷偷看……
smog
5楼-- · 2019-12-13 10:21
wz18th 发表于 2014-10-22 21:31
if(VS_Send_MusicData(databuf+i)==0)//给VS10XX发送音频数据
这句里面发送文件数据和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上运行过,是没有问题的,我怀疑的是配置上那里错了
smog
6楼-- · 2019-12-13 16:12
问题找出来了,这一句读取数据时出错了:res=f_read(file1,databuf,4096,(UINT*)&br);//读出4096个字节
每次读取数据大于1k,数据就乱了,还没清楚为什么会这样,F1是用spi读写SD卡的,F4是用SDIO读写SD卡的

一周热门 更多>