[求助]加急!!CH376S和VS1003做的U盘MP3 播放音乐速度慢,像慢放的一样,不知为何因,麻烦各位解答下~谢谢

CH376S和VS1003均采用SPI

int main(void) { u8 u8Result; u8 u8Length; u8 *pu8Temp = u8SectorBuf; u32 u32FileLen = 0; u32 u32DataCnt = 0; u32 i,j;

Stm32_Clock_Init(9); //72M delay_init(72); //延时初始化 uart_init(72, 9600); //设置串口1的波特率

Vs1003_Init(); //Vs1003的初始化 Vs1003SoftReset(); //软复位VS1003

VsRamTest(); //RAM测试 VsSineTest(); //VS1003正弦测试

CH376_Init();

while(1) { // 高速,对VS1003B,最大值不能超36.864/6Mhz,这里设4.5M SPI1_SetSpeed(SPI_SPEED_16); if(CH376DiskConnect()==USB_INT_SUCCESS) /* 检查U盘是否连接,不支持SD卡 */ { if(CH376DiskMount()==USB_INT_SUCCESS) /* 初始化磁盘并测试磁盘是否就绪 */ { /*从当前主机端点的接收缓冲区读取数据块,返回长度*/ u8Length = CH376ReadBlock(pu8Temp); if (u8Length != 0) { /*查询磁盘剩余空间信息,扇区数*/ CH376DiskQuery((u32 *)pu8Temp); strcpy((char*)pu8Temp, "\\风.MP3"); u8Result = CH376FileOpen(pu8Temp); // 打开文件

if (u8Result == USB_INT_SUCCESS) {

u32FileLen = CH376GetFileSize(); /* 获取文件大小 */ while (u32DataCnt < u32FileLen) { /*以扇区为单位从当前位置读取数据块,不支持SD卡*/ pu8Temp = u8SectorBuf; CH376SecRead(pu8Temp, 1, 0); u32DataCnt += 512; i = 0; while (i < 512) //循环发送512个字节 { //等待DREQ为高 while (VS_DREQ == 0); VS_XDCS = 0; for (j=0; j<32; j++) { SPI1_ReadWriteByte(*pu8Temp++); } i +=32; VS_XDCS = 1; } } } } } } }

}

u8 mWaitInterrupt( void ) { /* 等待CH376中断并获取状态,主机端等待操作完成,返回操作状态 */ while ( Query376Interrupt( ) == FALSE ); /* 一直等中断 */ xWriteCH376Cmd( CMD_GET_STATUS ); /* 产生操作完成中断,获取中断状态 */ return( xReadCH376Data( ) ); }

/*****************************************************

* Name: xWriteCH376Cmd

* Function: 写命令到CH376去

* Input: no

* Output: no

* Author: PowerAVR / 2009-12-19

* Update:

*****************************************************/ void xWriteCH376Cmd( u8 mCmd ) /* 向CH376写命令 */ { xEndCH376Cmd = 1;; /* 防止之前未通过xEndCH376Cmd禁止SPI片选 */ delay_us(1); /* 对于双向I/O引脚模拟SPI接口,那么必须确保已经设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */ xEndCH376Cmd = 0; /* SPI片选有效 */ SPI2_ReadWriteByte( mCmd ); /* 发出命令码 */

// DelayXms(1);; /* 延时1.5uS确保读写周期大于1.5uS,或者用上面一行的状态查询代替 */

} /*****************************************************

* Name: xWriteCH376Data

* Function: 写1字节数据到CH376

* Input: no

* Output: no

* Author: PowerAVR / 2009-12-19

* Update:

*****************************************************/ void xWriteCH376Data( u8 mData ) /* 向CH376写数据 */ { SPI2_ReadWriteByte( mData ); // delay_us(1); /* 确保读写周期大于0.6uS */ }

/*****************************************************

* Name: xReadCH376Data

* Function: 从CH376读取1字节数据

* Input: no

* Output: no

* Author: PowerAVR / 2009-12-19

* Update:

*****************************************************/ u8 xReadCH376Data( void ) /* 从CH376读数据 */ { // delay_us(1); /* 确保读写周期大于0.6uS */ return( SPI2_ReadWriteByte( 0xff) ); }

/*****************************************************

* Name: Query376Interrupt

* Function: 查询CH376中断(INT#低电平)

* Input: no

* Output: no

* Author: PowerAVR / 2009-12-19

* Update:

*****************************************************/ u8 Query376Interrupt( void ) { /* 如果未连接CH376的中断引脚则查询兼做中断输出的SDO引脚状态 */

return( (PBin(14)) ? FALSE : TRUE ); }

/******************************SPI1及VS1003端口初始化*******************************/ void SPI1_Init(void) { RCC->APB2ENR|=1<<2; //PORTA时钟使能 RCC->APB2ENR|=1<<12; //SPI1时钟使能 //这里只针对SPI口初始化 GPIOA->CRL&=0X000FFFFF; GPIOA->CRL|=0XBBB00000;//PA5.6.7复用 GPIOA->ODR|=0X7<<5; //PA5.6.7上拉 SPI1->CR1|=0<<10;//全双工模式 SPI1->CR1|=1<<9; //软件nss管理 SPI1->CR1|=1<<8;

SPI1->CR1|=1<<2; //SPI主机 SPI1->CR1|=0<<11;//8bit数据格式 SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1 SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1 SPI1->CR1|=5<<3; //Fsck=Fcpu/64

// SPI1->CR1|=0<<7; //MSBfirst SPI1->CR1 &= ~(1<<7); //MSBfirst SPI1->CR1|=1<<13; //CRC 计算多项式 SPI1->CR1|=1<<6; //SPI设备使能 // SPI1_ReadWriteByte(0xff);//启动传输 }

//SPI 速度设置函数 //SpeedSet: //SPI_SPEED_2 2分频 (SPI 36M@sys 72M) //SPI_SPEED_4 4分频 (SPI 18M@sys 72M) //SPI_SPEED_8 8分频 (SPI 9M@sys 72M) //SPI_SPEED_16 16分频 (SPI 4.5M@sys 72M) //SPI_SPEED_256 256分频 (SPI 281.25K@sys 72M) void SPI1_SetSpeed(u8 SpeedSet) { SPI1->CR1&=0XFFC7;//Fsck=Fcpu/256 switch(SpeedSet) { case SPI_SPEED_2://二分频 SPI1->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz break; case SPI_SPEED_4://四分频 SPI1->CR1|=1<<3;//Fsck=Fpclk/4=18Mhz break; case SPI_SPEED_8://八分频 SPI1->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz break; case SPI_SPEED_16://十六分频 SPI1->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz break; case SPI_SPEED_32: //32分频 SPI1->CR1|=4<<3;//Fsck=Fpclk/32=2.25Mhz break; case SPI_SPEED_64: //64分频 SPI1->CR1|=5<<3;//Fsck=Fpclk/64=1.125Mhz break; case SPI_SPEED_128: //128分频 SPI1->CR1|=6<<3;//Fsck=Fpclk/128=562.5Khz break; case SPI_SPEED_256: //256分频 SPI1->CR1|=7<<3;//Fsck=Fpclk/16=281.25Khz break; } SPI1->CR1|=1<<6; //SPI设备使能 } //SPIx 读写一个字节 //TxData:要写入的字节 //返回值:读取到的字节 u8 SPI1_ReadWriteByte(u8 TxData) { while((SPI1->SR&1<<1)==0);//等待发送区空 SPI1->DR=TxData; //发送一个byte

while((SPI1->SR&1<<0)==0); //等待接收完一个byte return SPI1->DR; //返回收到的数据 }

/*****************************SPI2及CH376端口初始化*************************************/

void SPI2_Init(void) { RCC->APB2ENR|=1<<3; //PORTB时钟使能 RCC->APB2ENR|=1<<5; //PORTD时钟使能 RCC->APB1ENR|=1<<14; //SPI2时钟使能 /*CH376端口初始化*/

GPIOD->CRH &= 0XFF00FFFF; //(SCS)PD12推挽输出 (INT#)PD13输入 GPIOD->CRH |= 0X00430000; GPIOD->ODR|=1<<12;

//这里只针对SPI2口初始化 GPIOB->CRH&=0X000FFFFF; GPIOB->CRH|=0XBBB00000;//PB.13,PB.14,PB.15复用 // GPIOB->ODR|=1<<14; //PB.14上拉 GPIOB->ODR|=0x7<<13; //PB.14上拉 SPI2->CR1|=0<<10;//全双工模式 SPI2->CR1|=1<<9; //软件nss管理 SPI2->CR1|=1<<8;

SPI2->CR1|=1<<2; //SPI主机 SPI2->CR1|=0<<11;//8bit数据格式 SPI2->CR1 |= 0<<0; //数据采样从第一个时间边沿开始,CPHA=0 SPI2->CR1 &= ~(1<<1); //空闲模式下SCK为0,所以此位CPOL=0 SPI2->CR1|=1<<3; //Fsck=Fcpu/8

SPI2->CR1 &= ~(1<<7); //MSBfirst

SPI2->CR1|=1<<6; //SPI设备使能 }

void SPI2_SetSpeed(u8 SpeedSet) { SPI2->CR1&=0XFFC7;//Fsck=Fcpu/256 switch(SpeedSet) { case SPI_SPEED_2://二分频 SPI2->CR1|=0<<3;//Fsck=Fpclk/2=36Mhz break; case SPI_SPEED_4://四分频 SPI2->CR1|=1<<3;//Fsck=Fpclk/4=18Mhz break; case SPI_SPEED_8://八分频 SPI2->CR1|=2<<3;//Fsck=Fpclk/8=9Mhz break; case SPI_SPEED_16://十六分频 SPI2->CR1|=3<<3;//Fsck=Fpclk/16=4.5Mhz break; case SPI_SPEED_32: //32分频 SPI1->CR1|=4<<3;//Fsck=Fpclk/32=2.25Mhz break; case SPI_SPEED_64: //64分频 SPI2->CR1|=5<<3;//Fsck=Fpcl

你有没有测试过CH376读取U盘的速度是多少?播放MP3文件的话读取U盘的速度最少要100K字节/S的速度才可以正常的播放。


您好! void xWriteCH376Data( u8 mData ) /* 向CH376写数据 */ { SPI2_SetSpeed(SPI_SPEED_8); //设置SPI速速为 9M SPI2_ReadWriteByte( mData );

}

u8 xReadCH376Data( void ) /* 从CH376读数据 */ { SPI2_SetSpeed(SPI_SPEED_8); //设置SPI速速为 9M return( SPI2_ReadWriteByte( 0xff) ); } 我在对CH376读写前 把和它通信的 SPI2 速度设置为 9M 您看这样行不?


还有请问 CH376S读写 速度怎么测试 ?这个真的不清楚~


加急啊~~ 被这问题折腾了好几天了,不知如何是好!


从CH376S里读取数据的速度设置到了18M但是都没有一点效果! STM32的主频72M 应该可以处理得了啊

自己顶一个~


CH376S的 读写速度设置为 9M应该也不低了吧


论坛好沉寂啊~一直没有人回答了!!!!


实际上不是SPI的速度,而是需要读取U盘的速度。这个速度不能低于100K字节/S,实际我们的芯片SPI的速度可以做到24M。


读取U盘的速度 涉及的函数主要是这几个: void xWriteCH376Cmd( u8 mCmd ) /* 向CH376写命令 */ { // SPI2_SetSpeed(SPI2_SPEED_4);

xEndCH376Cmd = 1;; /* 防止之前未通过xEndCH376Cmd禁止SPI片选 */ mDelay0_5uS(); /* 对于双向I/O引脚模拟SPI接口,那么必须确保已经设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */ xEndCH376Cmd = 0; /* SPI片选有效 */ SPI2_ReadWriteByte( mCmd ); /* 发出命令码 */

// DelayXms(1);; /* 延时1.5uS确保读写周期大于1.5uS,或者用上面一行的状态查询代替 */

}

void xWriteCH376Data( u8 mData ) /* 向CH376写数据 */ { // SPI2_SetSpeed(SPI2_SPEED_4); SPI2_ReadWriteByte( mData ); // delay_us(1); /* 确保读写周期大于0.6uS */ }

u8 xReadCH376Data( void ) /* 从CH376读数据 */ { // SPI2_SetSpeed(SPI2_SPEED_4); //高速 18M // delay_us(1); /* 确保读写周期大于0.6uS */ return( SPI2_ReadWriteByte( 0xff) ); } 但是命令和数据读写还是通过SPI来完成~我试过在与CH376S读写相关的函数里面都加入 SPI速度设置,要读写首先都要进行速度设置,但是都没效果


“需要读取U盘的速度” 这个是设置哪个地方读写的速度?


void CH376_PORT_INIT( void ) /* 由于使用SPI读写时序,所以进行初始化 */ { /* 如果是硬件SPI接口,那么可使用mode3(CPOL=1&CPHA=1)或mode0(CPOL=0&CPHA=0),CH376在时钟上升沿采样输入,下降沿输出,数据位是高位在前 */ CH376_SPI_SCS = 1; /* 禁止SPI片选 */ /* 对于双向I/O引脚模拟SPI接口,那么必须在此设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */ SPCR = 0x5C; /* 设置SPI模式3, DORD=0(MSB first), CPOL=1, CPHA=1, CH376也支持SPI模式0 */ }

为什么我设置成mode3(CPOL=1&CPHA=1)U盘就没有读写了???求解释


加我的QQ2314116323


只有登录才能回复,可以选择微信账号登录