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); //延時(shí)初始化 uart_init(72, 9600); //設(shè)置串口1的波特率 // LED_Init(); // LED2 = 1; Vs1003_Init(); //Vs1003的初始化 Vs1003SoftReset(); //軟復(fù)位VS1003

VsRamTest(); //RAM測(cè)試 VsSineTest(); //VS1003正弦測(cè)試

CH376_Init();

while(1) { SPI1_SetSpeed(SPI_SPEED_16); // //高速,對(duì)VS1003B,最大值不能超過(guò)36.864/6Mhz,這里設(shè)置為4.5M if(CH376DiskConnect()==USB_INT_SUCCESS) /* 檢查U盤是否連接,不支持SD卡 */ { // LED2 = 0; USART1_SendByte(0xe3); if(CH376DiskMount()==USB_INT_SUCCESS) /* 初始化磁盤并測(cè)試磁盤是否就緒 */ { USART1_SendByte(0xe4); // LED2 = 1; // delay_ms(1000); // LED2 = 0; // delay_ms(1000); // LED2 = 1; // delay_ms(1000); // LED2 = 0; u8Length = CH376ReadBlock(pu8Temp); /*從當(dāng)前主機(jī)端點(diǎn)的接收緩沖區(qū)讀取數(shù)據(jù)塊,返回長(zhǎng)度*/ if (u8Length != 0) { CH376DiskQuery((u32 *)pu8Temp); /*查詢磁盤剩余空間信息,扇區(qū)數(shù)*/ strcpy((char*)pu8Temp, "\\風(fēng).MP3"); u8Result = CH376FileOpen(pu8Temp); // 打開(kāi)文件

if (u8Result == USB_INT_SUCCESS) { USART1_SendByte(0xe5); //LED2 = 1; u32FileLen = CH376GetFileSize(); /* 獲取文件大小 */ while (u32DataCnt < u32FileLen) { pu8Temp = u8SectorBuf; CH376SecRead(pu8Temp, 1, 0); /*以扇區(qū)為單位從當(dāng)前位置讀取數(shù)據(jù)塊,不支持SD卡*/ u32DataCnt += 512; // SPI1_SetSpeed(SPI_SPEED_8);

// VS_XDCS = 0; /*VS_XDCS = 0,選擇vs1003的數(shù)據(jù)接口 */ i = 0; while (i < 512) //循環(huán)發(fā)送512個(gè)字節(jié) { while (VS_DREQ == 0); //等待DREQ為高 VS_XDCS = 0; for (j=0; j<32; j++) { SPI1_ReadWriteByte(*pu8Temp++); } i += 32; VS_XDCS = 1; } // VS_XDCS = 1; /*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;; /* 防止之前未通過(guò)xEndCH376Cmd禁止SPI片選 */ delay_us(1); /* 對(duì)于雙向I/O引腳模擬SPI接口,那么必須確保已經(jīng)設(shè)置SPI_SCS,SPI_SCK,SPI_SDI為輸出方向,SPI_SDO為輸入方向 */ xEndCH376Cmd = 0; /* SPI片選有效 */ SPI2_ReadWriteByte( mCmd ); /* 發(fā)出命令碼 */

// DelayXms(1);; /* 延時(shí)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 ) { // return( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)? FALSE : TRUE ); /* 如果未連接CH376的中斷引腳則查詢兼做中斷輸出的SDO引腳狀態(tài) */

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

/******************************SPI1及VS1003端口初始化*******************************/ void SPI1_Init(void) { RCC->APB2ENR|=1<<2; //PORTA時(shí)鐘使能 RCC->APB2ENR|=1<<12; //SPI1時(shí)鐘使能 //這里只針對(duì)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ù)采樣從第二個(gè)時(shí)間邊沿開(kāi)始,CPHA=1 SPI1->CR1|=5<<3; //Fsck=Fcpu/64

// SPI1->CR1|=0<<7; //MSBfirst SPI1->CR1 &= ~(1<<7); //MSBfirst SPI1->CR1|=1<<13; //CRC 計(jì)算多項(xiàng)式 SPI1->CR1|=1<<6; //SPI設(shè)備使能 // SPI1_ReadWriteByte(0xff);//啟動(dòng)傳輸 }

//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 讀寫一個(gè)字節(jié) //TxData:要寫入的字節(jié) //返回值:讀取到的字節(jié) u8 SPI1_ReadWriteByte(u8 TxData) { // u8 retry=0; // while((SPI1->SR&1<<1)==0)//等待發(fā)送區(qū)空 // { // retry++; // if(retry>200)return 0; // } // SPI1->DR=TxData; //發(fā)送一個(gè)byte // retry=0; // while((SPI1->SR&1<<0)==0) //等待接收完一個(gè)byte // { // retry++; // if(retry>200)return 0; // } // return SPI1->DR; //返回收到的數(shù)據(jù) while((SPI1->SR&1<<1)==0);//等待發(fā)送區(qū)空 SPI1->DR=TxData; //發(fā)送一個(gè)byte

while((SPI1->SR&1<<0)==0); //等待接收完一個(gè)byte return SPI1->DR; //返回收到的數(shù)據(jù) }

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

void SPI2_Init(void) { RCC->APB2ENR|=1<<3; //PORTB時(shí)鐘使能 RCC->APB2ENR|=1<<5; //PORTD時(shí)鐘使能 RCC->APB1ENR|=1<<14; //SPI2時(shí)鐘使能 /*CH376端口初始化*/ // GPIOD->CRL &= 0XF0FF0FFF; //(SCS)PD3推挽輸出 (INT#)PD6輸入 // GPIOD->CRL |= 0X08003000; // GPIOD->ODR |= 1 << 6;

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

//這里只針對(duì)