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); //設(shè)置串口1的波特率
Vs1003_Init(); //Vs1003的初始化 Vs1003SoftReset(); //軟復(fù)位VS1003
VsRamTest(); //RAM測試 VsSineTest(); //VS1003正弦測試
CH376_Init();
while(1) { // 高速,對VS1003B,最大值不能超36.864/6Mhz,這里設(shè)4.5M SPI1_SetSpeed(SPI_SPEED_16); if(CH376DiskConnect()==USB_INT_SUCCESS) /* 檢查U盤是否連接,不支持SD卡 */ { if(CH376DiskMount()==USB_INT_SUCCESS) /* 初始化磁盤并測試磁盤是否就緒 */ { /*從當(dāng)前主機(jī)端點的接收緩沖區(qū)讀取數(shù)據(jù)塊,返回長度*/ u8Length = CH376ReadBlock(pu8Temp); if (u8Length != 0) { /*查詢磁盤剩余空間信息,扇區(qū)數(shù)*/ CH376DiskQuery((u32 *)pu8Temp); strcpy((char*)pu8Temp, "\\風(fēng).MP3"); u8Result = CH376FileOpen(pu8Temp); // 打開文件
if (u8Result == USB_INT_SUCCESS) {
u32FileLen = CH376GetFileSize(); /* 獲取文件大小 */ while (u32DataCnt < u32FileLen) { /*以扇區(qū)為單位從當(dāng)前位置讀取數(shù)據(jù)塊,不支持SD卡*/ pu8Temp = u8SectorBuf; CH376SecRead(pu8Temp, 1, 0); u32DataCnt += 512; i = 0; while (i < 512) //循環(huán)發(fā)送512個字節(jié) { //等待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中斷并獲取狀態(tài),主機(jī)端等待操作完成,返回操作狀態(tài) */ while ( Query376Interrupt( ) == FALSE ); /* 一直等中斷 */ xWriteCH376Cmd( CMD_GET_STATUS ); /* 產(chǎn)生操作完成中斷,獲取中斷狀態(tài) */ 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接口,那么必須確保已經(jīng)設(shè)置SPI_SCS,SPI_SCK,SPI_SDI為輸出方向,SPI_SDO為輸入方向 */ xEndCH376Cmd = 0; /* SPI片選有效 */ SPI2_ReadWriteByte( mCmd ); /* 發(fā)出命令碼 */
// DelayXms(1);; /* 延時1.5uS確保讀寫周期大于1.5uS,或者用上面一行的狀態(tài)查詢代替 */
} /*****************************************************
* Name: xWriteCH376Data
* Function: 寫1字節(jié)數(shù)據(jù)到CH376
* Input: no
* Output: no
* Author: PowerAVR / 2009-12-19
* Update:
*****************************************************/ void xWriteCH376Data( u8 mData ) /* 向CH376寫數(shù)據(jù) */ { SPI2_ReadWriteByte( mData ); // delay_us(1); /* 確保讀寫周期大于0.6uS */ }
/*****************************************************
* Name: xReadCH376Data
* Function: 從CH376讀取1字節(jié)數(shù)據(jù)
* Input: no
* Output: no
* Author: PowerAVR / 2009-12-19
* Update:
*****************************************************/ u8 xReadCH376Data( void ) /* 從CH376讀數(shù)據(jù) */ { // 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引腳狀態(tài) */
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復(fù)用 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主機(jī) SPI1->CR1|=0<<11;//8bit數(shù)據(jù)格式 SPI1->CR1|=1<<1; //空閑模式下SCK為1 CPOL=1 SPI1->CR1|=1<<0; //數(shù)據(jù)采樣從第二個時間邊沿開始,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設(shè)備使能 // SPI1_ReadWriteByte(0xff);//啟動傳輸 }
//SPI 速度設(shè)置函數(shù) //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設(shè)備使能 } //SPIx 讀寫一個字節(jié) //TxData:要寫入的字節(jié) //返回值:讀取到的字節(jié) u8 SPI1_ReadWriteByte(u8 TxData) { while((SPI1->SR&1<<1)==0);//等待發(fā)送區(qū)空 SPI1->DR=TxData; //發(fā)送一個byte
while((SPI1->SR&1<<0)==0); //等待接收完一個byte return SPI1->DR; //返回收到的數(shù)據(jù) }
/*****************************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復(fù)用 // 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主機(jī) SPI2->CR1|=0<<11;//8bit數(shù)據(jù)格式 SPI2->CR1 |= 0<<0; //數(shù)據(jù)采樣從第一個時間邊沿開始,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設(shè)備使能 }
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