main.c: #include "stm32f10x_lib.h" #include "hw_conf.h" #include"SST25V.h" void delay(int d); u8 Tx_Buffer[] = {0x72,0x62,0x02,0x78,0x60,0x96,0x86,0x79,0x85,0x24,0x36,0x48,0x56,0x68,0x70,0x75,0x88,0x24}; u8 Rx_Buffer[BufferSize]; u8 DataByte=0; int main(void) { #ifdef DEBUG debug(); #endif Setup_System(); //系統(tǒng)啟動(dòng) SST25V_Init(); //Flash芯片初始化 SST25V_ChipErase(); //擦除整個(gè)芯片空間 DataByte = SST25V_ByteRead(0x000000); //讀取0x000000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x000010); //讀取0x000000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x000100); //讀取0x000100地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x001000); //讀取0x001000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x010000); //讀取0x010000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x100000); //讀取0x100000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x600000); //讀取0x000000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xF00000); //讀取0x600000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFFFFF); //讀取0xFFFFFF地址空間的數(shù)據(jù)信息 SST25V_AAI_WriteBytes(0x72, 0xFFF000,0x001000); //向以0xFFF000為起始地址的數(shù)據(jù)空間寫(xiě)入0x001000個(gè)0x10--即向最后4KB空間寫(xiě)入0x10 DataByte = SST25V_ByteRead(0x000000); //讀取0x000000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x000001); //讀取0x000001地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x000002); //讀取0x000002地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFF000); //讀取0xFFF000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFF0EE); //讀取0xFFF0EE地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFFEEE); //讀取0xFFFEEE地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFFFFF); //讀取0xFFFFFF地址空間的數(shù)據(jù)信息 SST25V_SectorErase_4KByte(0xFFF000); //擦除以0xFFF000為起始地址的4KB數(shù)據(jù)空間 DataByte = SST25V_ByteRead(0x000000); //讀取0x000000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFF000); //讀取0xFFF000地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x000001); //讀取0x000001地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0x000002); //讀取0x000002地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFEEEE); //讀取0xFFEEEE地址空間的數(shù)據(jù)信息 DataByte = SST25V_ByteRead(0xFFFFFF); //讀取0xFFFFFF地址空間的數(shù)據(jù)信息 //SST25V_BufferWrite(Tx_Buffer,0xFFF000,16); //將Tx_Buffer中的16個(gè)字節(jié)數(shù)據(jù)寫(xiě)入以0xFFF000為起始地址的數(shù)據(jù)空間 SST25V_AAI_BufferProgram(Tx_Buffer,0xFFF000,16); //采用AAI模式,將Tx_Buffer中的16個(gè)字節(jié)數(shù)據(jù)寫(xiě)入以0xFFF000為起始地址的數(shù)據(jù)空間 SST25V_BufferRead(Rx_Buffer,0xFFF000,16); //讀出0xFFF000為起始地址的16字節(jié)數(shù)據(jù),存放于Rx_Buffer中 DataByte = SST25V_ByteRead(0xFFEEEE); //讀取0xFFEEEE地址空間的數(shù)據(jù)信息 while (1) { if(Rx_Buffer[0]==0x72) { GPIO_WriteBit(GPIOC,GPIO_Pin_6,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_6))); delay(100); } if(Rx_Buffer[1]==0x62) { GPIO_WriteBit(GPIOC,GPIO_Pin_7,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_7))); delay(100); } if(Rx_Buffer[2]==0x02) { GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_4))); delay(100); } if(Rx_Buffer[3]==0x78) { GPIO_WriteBit(GPIOC,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_5))); delay(100); } } } void delay(int d) { int i = 0; for ( ;d;--d) for (i = 0;i<10000;i++); } SST25VF.c: #include "stm32f10x_lib.h" #include "SST25V.h" void SST25V_Init(void) //Flash芯片初始化 { SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WP_HIGH(); //保護(hù)WP#管腳置高--BPL的狀態(tài)決定是否允許寫(xiě)狀態(tài)寄存器 SST25V_HOLD_HIGH(); //保持HOLD#管腳置高 SST25V_WriteStatusRegister(0x02); //給狀態(tài)寄存器寫(xiě)入數(shù)據(jù)02 SST25V_DBSY(); //禁止AAI模式時(shí),SO腳輸出忙狀態(tài) } u8 SST25V_ByteRead(u32 ReadAddr) //從ReadAddr地址讀取一個(gè)字節(jié)數(shù)據(jù) { u8 Temp = 0; SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(Read_Data); //發(fā)送讀取數(shù)據(jù)命令 SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發(fā)送24位的讀取數(shù)據(jù)地址 SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8); SPI_Flash_SendByte(ReadAddr & 0xFF); Temp = SPI_Flash_ReceiveByte(); //接收讀取到的數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 return Temp; //返回讀取到的數(shù)據(jù) } void SST25V_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)//從ReadAddr地址開(kāi)始讀取NumByteToRead個(gè)字節(jié)數(shù)據(jù) { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(Read_Data); //發(fā)送讀取數(shù)據(jù)命令 SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發(fā)送24位的讀取數(shù)據(jù)起始地址 SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8); SPI_Flash_SendByte(ReadAddr & 0xFF); while(NumByteToRead--) //判斷是否完成讀取NumByteToRead個(gè)字節(jié)數(shù)據(jù) { *pBuffer = SPI_Flash_ReceiveByte(); //接受讀取到的數(shù)據(jù),并存儲(chǔ)于pBuffer中 pBuffer++; //pBuffer指針自增1 } SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } u8 SST25V_HighSpeedByteRead(u32 ReadAddr) //從ReadAddr高速讀取一個(gè)字節(jié)數(shù)據(jù) { u32 Temp = 0; SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(HighSpeedReadData); //發(fā)送快速讀取數(shù)據(jù)命令 SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發(fā)送24位的讀取數(shù)據(jù)地址 SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8); SPI_Flash_SendByte(ReadAddr & 0xFF); SPI_Flash_SendByte(Dummy_Byte); //發(fā)送虛擬字節(jié)數(shù)據(jù) Temp = SPI_Flash_ReceiveByte(); //接收讀取到的數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 return Temp; //返回讀取到的數(shù)據(jù) } void SST25V_HighSpeedBufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)//從ReadAddr開(kāi)始高速讀取NumByteToRead個(gè)字節(jié)數(shù)據(jù),并存儲(chǔ)于pBuffer中 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(HighSpeedReadData); //發(fā)送快速讀取數(shù)據(jù)命令 SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發(fā)送24位的讀取數(shù)據(jù)起始地址 SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8); SPI_Flash_SendByte(ReadAddr & 0xFF); SPI_Flash_SendByte(Dummy_Byte); //發(fā)送虛擬字節(jié)數(shù)據(jù) while(NumByteToRead--) //判斷是否完成讀取NumByteToRead個(gè)字節(jié)數(shù)據(jù) { *pBuffer = SPI_Flash_ReceiveByte(); //接受讀取到的數(shù)據(jù),并存儲(chǔ)于pBuffer中 pBuffer++; //pBuffer指針自增1 } SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } u8 SPI_Flash_SendByte(u8 byte) //SPI發(fā)送數(shù)據(jù) { while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET); //等待SPI1的Tx buffer為空 SPI_SendData(SPI1, byte); //發(fā)送數(shù)據(jù)字節(jié)byte while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET); //等待SPI1完成數(shù)據(jù)接收 return SPI_ReceiveData(SPI1); //返回讀取到的數(shù)據(jù) } u8 SPI_Flash_ReceiveByte(void) //SPI接收數(shù)據(jù) { return (SPI_Flash_SendByte(Dummy_Byte)); //發(fā)送虛擬字節(jié),提供接收數(shù)據(jù)時(shí)鐘 } void SST25V_ByteWrite(u8 Byte, u32 WriteAddr) //寫(xiě)入一個(gè)數(shù)據(jù)字節(jié) { SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(Byte_Program); //發(fā)送寫(xiě)數(shù)據(jù)命令 SPI_Flash_SendByte((WriteAddr & 0xFF0000) >> 16); //發(fā)送24位的寫(xiě)入數(shù)據(jù)地址 SPI_Flash_SendByte((WriteAddr & 0xFF00) >> 8); SPI_Flash_SendByte(WriteAddr & 0xFF); SPI_Flash_SendByte(Byte); //發(fā)送要寫(xiě)入的數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 } void SST25V_BufferWrite(u8 *pBuffer,u32 Addr,u16 BufferLength)//將pBuffer中的BufferLength個(gè)字節(jié)數(shù)據(jù)寫(xiě)入到以Addr為起始地址的區(qū)域 { while(BufferLength--) //判斷是否完成寫(xiě)入NumByteToRead個(gè)字節(jié)數(shù)據(jù) { SST25V_ByteWrite(*pBuffer,Addr); //把當(dāng)前pBuffer對(duì)應(yīng)的數(shù)據(jù),寫(xiě)入當(dāng)前Addr中 pBuffer++; //數(shù)據(jù)指針自增1 Addr++; //寫(xiě)入地址自增1 } } void SST25V_WriteBytes(u8 Byte, u32 WriteAddr,u32 ByteLength) //以WriteAddr為起始地址,寫(xiě)入ByteLength個(gè)數(shù)據(jù)Byte(寫(xiě)入的是同一個(gè)數(shù)據(jù)Byte) { while(ByteLength--) //判斷是否完成寫(xiě)入NumByteToRead個(gè)字節(jié)數(shù)據(jù) { SST25V_ByteWrite(Byte,WriteAddr); //向WriteAddr中寫(xiě)入數(shù)據(jù)字節(jié)Byte WriteAddr++; //寫(xiě)入地址自增1 } } void SST25V_AAI_WriteBytes(u8 Byte, u32 Addr,u32 ByteLength)//以Addr為起始地址,用AAI模式,寫(xiě)入ByteLength個(gè)數(shù)據(jù)Byte(寫(xiě)入的是同一個(gè)數(shù)據(jù)Byte)ByteLength必須為偶數(shù) { u32 Length = 0; Length = (ByteLength/2)-1; //AAI模式每次寫(xiě)入兩字節(jié)數(shù)據(jù),因此ByteLength各字節(jié),分成Length次寫(xiě)入 SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(AAI_WordProgram); //發(fā)送AAI模式寫(xiě)入命令 SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發(fā)送24位的寫(xiě)入數(shù)據(jù)地址 SPI_Flash_SendByte((Addr & 0xFF00) >> 8); SPI_Flash_SendByte(Addr & 0xFF); SPI_Flash_SendByte(Byte); //寫(xiě)入第一個(gè)字節(jié)數(shù)據(jù) SPI_Flash_SendByte(Byte); //寫(xiě)入第二個(gè)字節(jié)數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 while(Length--) //判斷是否完成Length次寫(xiě)入 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(AAI_WordProgram); //發(fā)送AAI模式寫(xiě)入命令 SPI_Flash_SendByte(Byte); //寫(xiě)入第一個(gè)字節(jié)數(shù)據(jù) SPI_Flash_SendByte(Byte); //寫(xiě)入第二個(gè)字節(jié)數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 } SST25V_WriteDisable(); //寫(xiě)入完成,退出AAI模式 } void SST25V_AAI_BufferProgram(u8 *pBuffer,u32 Addr,u16 BufferLength)//用AAI模式將pBuffer中的BufferLength個(gè)字節(jié)數(shù)據(jù)寫(xiě)入到以Addr為起始地址的區(qū)域,ByteLength必須為偶數(shù) { u16 Length = 0; Length = (BufferLength/2)-1; //AAI模式每次寫(xiě)入兩字節(jié)數(shù)據(jù),因此ByteLength各字節(jié),分成Length次寫(xiě)入 SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(AAI_WordProgram); //發(fā)送AAI模式寫(xiě)入數(shù)據(jù)命令 SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發(fā)送24位的寫(xiě)入數(shù)據(jù)起始地址 SPI_Flash_SendByte((Addr & 0xFF00) >> 8); SPI_Flash_SendByte(Addr & 0xFF); SPI_Flash_SendByte(*pBuffer); //寫(xiě)入數(shù)據(jù) pBuffer++; //數(shù)據(jù)指針加1 SPI_Flash_SendByte(*pBuffer); //寫(xiě)入數(shù)據(jù) pBuffer++; //數(shù)據(jù)指針加1 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 while(Length--) //判斷是否完成Length次寫(xiě)入 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(AAI_WordProgram); //發(fā)送AAI模式寫(xiě)入數(shù)據(jù)命令 SPI_Flash_SendByte(*pBuffer); //寫(xiě)入數(shù)據(jù) pBuffer++; //數(shù)據(jù)指針加1 SPI_Flash_SendByte(*pBuffer); //寫(xiě)入數(shù)據(jù) pBuffer++; //數(shù)據(jù)指針加1 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 } SST25V_WriteDisable(); //寫(xiě)入完成,退出AAI模式 } void SST25V_AAI_WordProgram(u8 Byte1, u8 Byte2, u32 Addr)//在AAI模式下,以Addr為起始地址,分別寫(xiě)入Byte1和Byte2,必須和SST25V_AAI_WordsProgram()函數(shù)配套使用 { SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(AAI_WordProgram); //發(fā)送AAI模式寫(xiě)入數(shù)據(jù)命令 SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發(fā)送24位的寫(xiě)入數(shù)據(jù)起始地址 SPI_Flash_SendByte((Addr & 0xFF00) >> 8); SPI_Flash_SendByte(Addr & 0xFF); SPI_Flash_SendByte(Byte1); //寫(xiě)入數(shù)據(jù)Byte1 SPI_Flash_SendByte(Byte2); //寫(xiě)入數(shù)據(jù)Byte2 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 } void SST25V_AAI_WordsProgram(u8 state,u8 Byte1, u8 Byte2) //在AAI模式下,繼續(xù)寫(xiě)入Byte1和Byte2,必須和SST25V_AAI_WordProgram()函數(shù)配套使用,state==1退出AAI模式 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(AAI_WordProgram); //繼續(xù)發(fā)送AAI模式寫(xiě)入數(shù)據(jù)命令 SPI_Flash_SendByte(Byte1); //寫(xiě)入數(shù)據(jù)Byte1 SPI_Flash_SendByte(Byte2); //寫(xiě)入數(shù)據(jù)Byte2 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待寫(xiě)操作完成 if(state==1) //state==1時(shí),退出AAI模式 { SST25V_WriteDisable(); } } void SST25V_SectorErase_4KByte(u32 Addr) //擦除4KB數(shù)據(jù)空間,Addr是擦除起始地址 { SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(SectorErace_4KB); //發(fā)送擦除4KB數(shù)據(jù)空間命令 SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發(fā)送24位的擦除起始地址 SPI_Flash_SendByte((Addr & 0xFF00) >> 8); SPI_Flash_SendByte(Addr & 0xFF); SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待擦除操作完成 } void SST25V_BlockErase_32KByte(u32 Addr) //擦除32KB數(shù)據(jù)空間,Addr是擦除起始地址 { SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(BlockErace_32KB); //發(fā)送擦除32KB數(shù)據(jù)空間命令 SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發(fā)送24位的擦除起始地址 SPI_Flash_SendByte((Addr & 0xFF00) >> 8); SPI_Flash_SendByte(Addr & 0xFF); SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待擦除操作完成 } void SST25V_BlockErase_64KByte(u32 Addr) //擦除64KB數(shù)據(jù)空間,Addr是擦除起始地址 { SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(BlockErace_64KB); //發(fā)送擦除64KB數(shù)據(jù)空間命令 SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發(fā)送24位的擦除起始地址 SPI_Flash_SendByte((Addr & 0xFF00) >> 8); SPI_Flash_SendByte(Addr & 0xFF); SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待擦除操作完成 } void SST25V_ChipErase(void) //擦除整個(gè)芯片數(shù)據(jù)空間 { SST25V_WriteEnable(); //允許寫(xiě)入操作 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(ChipErace); //發(fā)送擦除整個(gè)芯片空間命令 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 SST25V_WaitForWriteEnd(); //等待擦除操作完成 } u8 SST25V_ReadStatusRegister(void) //讀取狀態(tài)寄存器 { u8 StatusRegister = 0; SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(ReadStatusRegister); //發(fā)送讀取狀態(tài)寄存器命令 StatusRegister = SPI_Flash_ReceiveByte(); //接收狀態(tài)寄存器數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 return StatusRegister; //返回讀取到的狀態(tài)寄存器數(shù)據(jù) } void SST25V_WriteEnable(void) //允許對(duì)芯片寫(xiě)入操作 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(WriteEnable); //發(fā)送允許寫(xiě)入操作命令 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } void SST25V_WriteDisable(void) //禁止對(duì)芯片寫(xiě)入操作 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(WriteDisable); //發(fā)送禁止寫(xiě)入操作命令 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } void SST25V_EnableWriteStatusRegister(void) //允許改寫(xiě)狀態(tài)寄存器 { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(EnableWriteStatusRegister); //發(fā)送允許改寫(xiě)狀態(tài)寄存器命令 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } void SST25V_WriteStatusRegister(u8 Byte) //改寫(xiě)狀態(tài)寄存器,向狀態(tài)寄存器寫(xiě)入數(shù)據(jù)Byte { SST25V_EnableWriteStatusRegister(); //允許改寫(xiě)狀態(tài)寄存器 SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(WriteStatusRegister); //發(fā)送改寫(xiě)狀態(tài)寄存器命令 SPI_Flash_SendByte(Byte); //向狀態(tài)寄存器寫(xiě)入數(shù)據(jù)Byte SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } void SST25V_WaitForWriteEnd(void) //等待寫(xiě)入操作完成 { u8 FLASH_Status = 0; SST25V_CS_LOW(); //片選端置低--選中芯片 do { FLASH_Status = SST25V_ReadStatusRegister(); //獲取狀態(tài)寄存器值 } while((FLASH_Status & 0x01) == SET); //判斷芯片是否處于忙碌狀態(tài),忙則繼續(xù)讀取狀態(tài)寄存器的值 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } u32 SST25V_ReadJedecID(void) //讀取JEDEC ID { u32 JEDECID = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0; SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(ReadJedec_ID); //發(fā)送讀取JEDEC ID命令 Temp0 = SPI_Flash_ReceiveByte(); //接收第一字節(jié)數(shù)據(jù) Temp1 = SPI_Flash_ReceiveByte(); //接收第二字節(jié)數(shù)據(jù) Temp2 = SPI_Flash_ReceiveByte(); //接收第三字節(jié)數(shù)據(jù) SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 JEDECID = (Temp0 << 16) | (Temp1 << 8) | Temp2; //還原JEDEC ID return JEDECID; //返回JEDEC ID } u16 SST25V_ReadManuID_DeviceID(u32 ReadManu_DeviceID_Addr) //讀取ManufacturerID和DeviceID,ReadManu_DeviceID_Addr的狀態(tài)決定第一個(gè)字節(jié)是DeviceID還是ManufacturerID { u16 ManuID_DeviceID = 0; //存儲(chǔ)16位的ID數(shù)據(jù) u8 ManufacturerID = 0, DeviceID = 0; SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(ReadDeviceID); //發(fā)送讀取設(shè)備ID信息命令 SPI_Flash_SendByte((ReadManu_DeviceID_Addr & 0xFF0000) >> 16); //發(fā)送24位的地址字節(jié),該地址為0和1,分別決定先輸出的是ManufacturerID還是DeviceID SPI_Flash_SendByte((ReadManu_DeviceID_Addr & 0xFF00) >> 8); SPI_Flash_SendByte(ReadManu_DeviceID_Addr & 0xFF); if(ReadManu_DeviceID_Addr==1) //先輸出DeviceID { DeviceID = SPI_Flash_ReceiveByte(); //接收DeviceID ManufacturerID = SPI_Flash_ReceiveByte(); //接收ManufacturerID } else //先輸出ManufacturerID { ManufacturerID = SPI_Flash_ReceiveByte(); //接收ManufacturerID DeviceID = SPI_Flash_ReceiveByte(); //接收DeviceID } ManuID_DeviceID = ((ManufacturerID<<8) | DeviceID); //保存為16位的數(shù)據(jù),高字節(jié)為ManufacturerID,低字節(jié)為DeviceID SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 return ManuID_DeviceID; //返回16位的ManuID_DeviceID,高字節(jié)為ManufacturerID,低字節(jié)為DeviceID } void SST25V_EBSY() //允許AAI模式期間,SO腳輸出忙狀態(tài) { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(EBSY); //發(fā)送允許AAI模式期間,SO腳輸出忙狀態(tài)命令 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } void SST25V_DBSY() //禁止AAI模式期間,SO腳輸出忙狀態(tài) { SST25V_CS_LOW(); //片選端置低--選中芯片 SPI_Flash_SendByte(DBSY); //發(fā)送禁止AAI模式期間,SO腳輸出忙狀態(tài)命令 SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片 } SST25VF.h: #include "stm32f10x_lib.h" #ifndef __SST25V_H #define __SST25V_H #define BufferSize (countof(Tx_Buffer)-1) #define countof(a) (sizeof(a) / sizeof(*(a))) #define SST25V_PageSize 256 #define Dummy_Byte 0xA5 #define SST25V_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4) #define SST25V_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4) #define SST25V_WP_LOW() GPIO_ResetBits(GPIOC, GPIO_Pin_0) #define SST25V_WP_HIGH() GPIO_SetBits(GPIOC, GPIO_Pin_0) #define SST25V_HOLD_LOW() GPIO_ResetBits(GPIOC, GPIO_Pin_1) #define SST25V_HOLD_HIGH() GPIO_SetBits(GPIOC, GPIO_Pin_1) #define Read_Data 0x03 //讀取存儲(chǔ)器數(shù)據(jù) #define HighSpeedReadData 0x0B //快速讀取存儲(chǔ)器數(shù)據(jù) #define SectorErace_4KB 0x20 //扇區(qū)擦除 #define BlockErace_32KB 0x52 //32KB塊擦除 #define BlockErace_64KB 0xD8 //64KB塊擦除 #define ChipErace 0xC7 //片擦除 #define Byte_Program 0x02 //頁(yè)面編程--寫(xiě)數(shù)據(jù) #define AAI_WordProgram 0xAD #define ReadStatusRegister 0x05 //讀狀態(tài)寄存器 #define EnableWriteStatusRegister 0x50 #define WriteStatusRegister 0x01 //寫(xiě)狀態(tài)寄存器 #define WriteEnable 0x06 //寫(xiě)使能,設(shè)置狀態(tài)寄存器 #define WriteDisable 0x04 //寫(xiě)禁止 #define ReadDeviceID 0xAB //獲取設(shè)備ID信息 #define ReadJedec_ID 0x9F //JEDEC的ID信息 #define EBSY 0X70 //允許AAI模式期間,SO腳輸出忙狀態(tài)命令 #define DBSY 0X80 //禁止AAI模式期間,SO腳輸出忙狀態(tài)命令 void SST25V_Init(void); //Flash芯片初始化 u8 SST25V_ByteRead(u32 ReadAddr); //從ReadAddr地址讀取一個(gè)字節(jié)數(shù)據(jù) void SST25V_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead); //從ReadAddr地址開(kāi)始讀取NumByteToRead個(gè)字節(jié)數(shù)據(jù) u8 SST25V_HighSpeedByteRead(u32 ReadAddr); //從ReadAddr高速讀取一個(gè)字節(jié)數(shù)據(jù) void SST25V_HighSpeedBufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);//從ReadAddr開(kāi)始高速讀取NumByteToRead個(gè)字節(jié)數(shù)據(jù),并存儲(chǔ)于pBuffer中 u8 SPI_Flash_SendByte(u8 byte); //SPI發(fā)送數(shù)據(jù) u8 SPI_Flash_ReceiveByte(void); //SPI接收數(shù)據(jù) void SST25V_ByteWrite(u8 Byte, u32 WriteAddr); //寫(xiě)入一個(gè)數(shù)據(jù)字節(jié) void SST25V_BufferWrite(u8 *pBuffer,u32 Addr,u16 BufferLength);//將pBuffer中的BufferLength個(gè)字節(jié)數(shù)據(jù)寫(xiě)入到以Addr為起始地址的區(qū)域 void SST25V_WriteBytes(u8 Byte, u32 WriteAddr,u32 ByteLength); //以WriteAddr為起始地址,寫(xiě)入ByteLength個(gè)數(shù)據(jù)Byte(寫(xiě)入的是同一個(gè)數(shù)據(jù)Byte) void SST25V_AAI_WriteBytes(u8 Byte, u32 Addr,u32 ByteLength); //以Addr為起始地址,用AAI模式,寫(xiě)入ByteLength個(gè)數(shù)據(jù)Byte(寫(xiě)入的是同一個(gè)數(shù)據(jù)Byte)ByteLength必須為偶數(shù) void SST25V_AAI_BufferProgram(u8 *pBuffer,u32 Addr,u16 BufferLength); //用AAI模式將pBuffer中的BufferLength個(gè)字節(jié)數(shù)據(jù)寫(xiě)入到以Addr為起始地址的區(qū)域,ByteLength必須為偶數(shù) void SST25V_AAI_WordProgram(u8 Byte1, u8 Byte2, u32 Addr); //在AAI模式下,以Addr為起始地址,分別寫(xiě)入Byte1和Byte2,必須和SST25V_AAI_WordsProgram()函數(shù)配套使用 void SST25V_AAI_WordsProgram(u8 state,u8 Byte1, u8 Byte2); //在AAI模式下,繼續(xù)寫(xiě)入Byte1和Byte2,必須和SST25V_AAI_WordProgram()函數(shù)配套使用,state==1退出AAI模式 void SST25V_SectorErase_4KByte(u32 Addr); //擦除4KB數(shù)據(jù)空間,Addr是擦除起始地址 void SST25V_BlockErase_32KByte(u32 Addr); //擦除32KB數(shù)據(jù)空間,Addr是擦除起始地址 void SST25V_BlockErase_64KByte(u32 Addr); //擦除64KB數(shù)據(jù)空間,Addr是擦除起始地址 void SST25V_ChipErase(void); //擦除整個(gè)芯片數(shù)據(jù)空間 u8 SST25V_ReadStatusRegister(void); //讀取狀態(tài)寄存器 void SST25V_WriteEnable(void); //允許對(duì)芯片寫(xiě)入操作 void SST25V_WriteDisable(void); //禁止對(duì)芯片寫(xiě)入操作 void SST25V_EnableWriteStatusRegister(void); //允許改寫(xiě)狀態(tài)寄存器 void SST25V_WriteStatusRegister(u8 Byte); //改寫(xiě)狀態(tài)寄存器,向狀態(tài)寄存器寫(xiě)入數(shù)據(jù)Byte void SST25V_WaitForWriteEnd(void); //等待寫(xiě)入操作完成 u32 SST25V_ReadJedecID(void); //讀取JEDEC ID u16 SST25V_ReadManuID_DeviceID(u32 ReadManu_DeviceID_Addr); //讀取ManufacturerID和DeviceID,ReadManu_DeviceID_Addr的狀態(tài)決定第一個(gè)字節(jié)是DeviceID還是ManufacturerID void SST25V_EBSY(); //允許AAI模式期間,SO腳輸出忙狀態(tài) void SST25V_DBSY(); //禁止AAI模式期間,SO腳輸出忙狀態(tài) #endif hw_conf.c: #include"stm32f10x_lib.h" #include "hw_conf.h" ErrorStatus HSEStartUpStatus; void RCC_Configuration(void) { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource() != 0x08) { } } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); } void GPIO_Configuration(void) { //PC4567分別接LED4,3,2,1,以便調(diào)試觀察 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); //PA5--SPI1_SCK PA6--SPI1--MISO PA7--SPI1--MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //Configure SPI1 pins: NSS, SCK, MISO and MOSI GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //PA4--SPI1_NSS GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //Configure PA.4 as Output push-pull, used as Flash Chip select GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); } void SPI_configuration() //SPI1 configuration { SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI設(shè)置為雙線雙向全雙工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //設(shè)置為主 SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI發(fā)送接收 8 位幀結(jié)構(gòu) SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //時(shí)鐘懸空高 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //數(shù)據(jù)捕獲于第二個(gè)時(shí)鐘沿 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //內(nèi)部 NSS 信號(hào)有 SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //波特率預(yù)分頻值為 4 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //數(shù)據(jù)傳輸從 MSB 位開(kāi)始 SPI_InitStructure.SPI_CRCPolynomial = 7; //定義了用于 CRC值計(jì)算的多項(xiàng)式 7 SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); //Enable SPI1 } void NVIC_Configuration(void) { #ifdef VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif } void Setup_System(void) { RCC_Configuration(); GPIO_Configuration(); SPI_configuration(); NVIC_Configuration(); } hw_conf.h: #ifndef _hw_conf_H_ #define _hw_conf_H_ extern void Setup_System(void); #endif