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(); //系統啟動
SST25V_Init(); //Flash芯片初始化
SST25V_ChipErase(); //擦除整個芯片空間
DataByte = SST25V_ByteRead(0x000000); //讀取0x000000地址空間的數據信息
DataByte = SST25V_ByteRead(0x000010); //讀取0x000000地址空間的數據信息
DataByte = SST25V_ByteRead(0x000100); //讀取0x000100地址空間的數據信息
DataByte = SST25V_ByteRead(0x001000); //讀取0x001000地址空間的數據信息
DataByte = SST25V_ByteRead(0x010000); //讀取0x010000地址空間的數據信息
DataByte = SST25V_ByteRead(0x100000); //讀取0x100000地址空間的數據信息
DataByte = SST25V_ByteRead(0x600000); //讀取0x000000地址空間的數據信息
DataByte = SST25V_ByteRead(0xF00000); //讀取0x600000地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFFFFF); //讀取0xFFFFFF地址空間的數據信息
SST25V_AAI_WriteBytes(0x72, 0xFFF000,0x001000); //向以0xFFF000為起始地址的數據空間寫入0x001000個0x10--即向最后4KB空間寫入0x10
DataByte = SST25V_ByteRead(0x000000); //讀取0x000000地址空間的數據信息
DataByte = SST25V_ByteRead(0x000001); //讀取0x000001地址空間的數據信息
DataByte = SST25V_ByteRead(0x000002); //讀取0x000002地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFF000); //讀取0xFFF000地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFF0EE); //讀取0xFFF0EE地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFFEEE); //讀取0xFFFEEE地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFFFFF); //讀取0xFFFFFF地址空間的數據信息
SST25V_SectorErase_4KByte(0xFFF000); //擦除以0xFFF000為起始地址的4KB數據空間
DataByte = SST25V_ByteRead(0x000000); //讀取0x000000地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFF000); //讀取0xFFF000地址空間的數據信息
DataByte = SST25V_ByteRead(0x000001); //讀取0x000001地址空間的數據信息
DataByte = SST25V_ByteRead(0x000002); //讀取0x000002地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFEEEE); //讀取0xFFEEEE地址空間的數據信息
DataByte = SST25V_ByteRead(0xFFFFFF); //讀取0xFFFFFF地址空間的數據信息
//SST25V_BufferWrite(Tx_Buffer,0xFFF000,16); //將Tx_Buffer中的16個字節數據寫入以0xFFF000為起始地址的數據空間
SST25V_AAI_BufferProgram(Tx_Buffer,0xFFF000,16); //采用AAI模式,將Tx_Buffer中的16個字節數據寫入以0xFFF000為起始地址的數據空間
SST25V_BufferRead(Rx_Buffer,0xFFF000,16); //讀出0xFFF000為起始地址的16字節數據,存放于Rx_Buffer中
DataByte = SST25V_ByteRead(0xFFEEEE); //讀取0xFFEEEE地址空間的數據信息
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(); //保護WP#管腳置高--BPL的狀態決定是否允許寫狀態寄存器
SST25V_HOLD_HIGH(); //保持HOLD#管腳置高
SST25V_WriteStatusRegister(0x02); //給狀態寄存器寫入數據02
SST25V_DBSY(); //禁止AAI模式時,SO腳輸出忙狀態
}
u8 SST25V_ByteRead(u32 ReadAddr) //從ReadAddr地址讀取一個字節數據
{
u8 Temp = 0;
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(Read_Data); //發送讀取數據命令
SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發送24位的讀取數據地址
SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
SPI_Flash_SendByte(ReadAddr & 0xFF);
Temp = SPI_Flash_ReceiveByte(); //接收讀取到的數據
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
return Temp; //返回讀取到的數據
}
void SST25V_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)//從ReadAddr地址開始讀取NumByteToRead個字節數據
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(Read_Data); //發送讀取數據命令
SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發送24位的讀取數據起始地址
SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
SPI_Flash_SendByte(ReadAddr & 0xFF);
while(NumByteToRead--) //判斷是否完成讀取NumByteToRead個字節數據
{
*pBuffer = SPI_Flash_ReceiveByte(); //接受讀取到的數據,并存儲于pBuffer中
pBuffer++; //pBuffer指針自增1
}
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
u8 SST25V_HighSpeedByteRead(u32 ReadAddr) //從ReadAddr高速讀取一個字節數據
{
u32 Temp = 0;
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(HighSpeedReadData); //發送快速讀取數據命令
SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發送24位的讀取數據地址
SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
SPI_Flash_SendByte(ReadAddr & 0xFF);
SPI_Flash_SendByte(Dummy_Byte); //發送虛擬字節數據
Temp = SPI_Flash_ReceiveByte(); //接收讀取到的數據
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
return Temp; //返回讀取到的數據
}
void SST25V_HighSpeedBufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)//從ReadAddr開始高速讀取NumByteToRead個字節數據,并存儲于pBuffer中
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(HighSpeedReadData); //發送快速讀取數據命令
SPI_Flash_SendByte((ReadAddr & 0xFF0000) >> 16); //發送24位的讀取數據起始地址
SPI_Flash_SendByte((ReadAddr& 0xFF00) >> 8);
SPI_Flash_SendByte(ReadAddr & 0xFF);
SPI_Flash_SendByte(Dummy_Byte); //發送虛擬字節數據
while(NumByteToRead--) //判斷是否完成讀取NumByteToRead個字節數據
{
*pBuffer = SPI_Flash_ReceiveByte(); //接受讀取到的數據,并存儲于pBuffer中
pBuffer++; //pBuffer指針自增1
}
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
u8 SPI_Flash_SendByte(u8 byte) //SPI發送數據
{
while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET); //等待SPI1的Tx buffer為空
SPI_SendData(SPI1, byte); //發送數據字節byte
while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET); //等待SPI1完成數據接收
return SPI_ReceiveData(SPI1); //返回讀取到的數據
}
u8 SPI_Flash_ReceiveByte(void) //SPI接收數據
{
return (SPI_Flash_SendByte(Dummy_Byte)); //發送虛擬字節,提供接收數據時鐘
}
void SST25V_ByteWrite(u8 Byte, u32 WriteAddr) //寫入一個數據字節
{
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(Byte_Program); //發送寫數據命令
SPI_Flash_SendByte((WriteAddr & 0xFF0000) >> 16); //發送24位的寫入數據地址
SPI_Flash_SendByte((WriteAddr & 0xFF00) >> 8);
SPI_Flash_SendByte(WriteAddr & 0xFF);
SPI_Flash_SendByte(Byte); //發送要寫入的數據
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
}
void SST25V_BufferWrite(u8 *pBuffer,u32 Addr,u16 BufferLength)//將pBuffer中的BufferLength個字節數據寫入到以Addr為起始地址的區域
{
while(BufferLength--) //判斷是否完成寫入NumByteToRead個字節數據
{
SST25V_ByteWrite(*pBuffer,Addr); //把當前pBuffer對應的數據,寫入當前Addr中
pBuffer++; //數據指針自增1
Addr++; //寫入地址自增1
}
}
void SST25V_WriteBytes(u8 Byte, u32 WriteAddr,u32 ByteLength) //以WriteAddr為起始地址,寫入ByteLength個數據Byte(寫入的是同一個數據Byte)
{
while(ByteLength--) //判斷是否完成寫入NumByteToRead個字節數據
{
SST25V_ByteWrite(Byte,WriteAddr); //向WriteAddr中寫入數據字節Byte
WriteAddr++; //寫入地址自增1
}
}
void SST25V_AAI_WriteBytes(u8 Byte, u32 Addr,u32 ByteLength)//以Addr為起始地址,用AAI模式,寫入ByteLength個數據Byte(寫入的是同一個數據Byte)ByteLength必須為偶數
{
u32 Length = 0;
Length = (ByteLength/2)-1; //AAI模式每次寫入兩字節數據,因此ByteLength各字節,分成Length次寫入
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(AAI_WordProgram); //發送AAI模式寫入命令
SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發送24位的寫入數據地址
SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
SPI_Flash_SendByte(Addr & 0xFF);
SPI_Flash_SendByte(Byte); //寫入第一個字節數據
SPI_Flash_SendByte(Byte); //寫入第二個字節數據
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
while(Length--) //判斷是否完成Length次寫入
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(AAI_WordProgram); //發送AAI模式寫入命令
SPI_Flash_SendByte(Byte); //寫入第一個字節數據
SPI_Flash_SendByte(Byte); //寫入第二個字節數據
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
}
SST25V_WriteDisable(); //寫入完成,退出AAI模式
}
void SST25V_AAI_BufferProgram(u8 *pBuffer,u32 Addr,u16 BufferLength)//用AAI模式將pBuffer中的BufferLength個字節數據寫入到以Addr為起始地址的區域,ByteLength必須為偶數
{
u16 Length = 0;
Length = (BufferLength/2)-1; //AAI模式每次寫入兩字節數據,因此ByteLength各字節,分成Length次寫入
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(AAI_WordProgram); //發送AAI模式寫入數據命令
SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發送24位的寫入數據起始地址
SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
SPI_Flash_SendByte(Addr & 0xFF);
SPI_Flash_SendByte(*pBuffer); //寫入數據
pBuffer++; //數據指針加1
SPI_Flash_SendByte(*pBuffer); //寫入數據
pBuffer++; //數據指針加1
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
while(Length--) //判斷是否完成Length次寫入
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(AAI_WordProgram); //發送AAI模式寫入數據命令
SPI_Flash_SendByte(*pBuffer); //寫入數據
pBuffer++; //數據指針加1
SPI_Flash_SendByte(*pBuffer); //寫入數據
pBuffer++; //數據指針加1
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
}
SST25V_WriteDisable(); //寫入完成,退出AAI模式
}
void SST25V_AAI_WordProgram(u8 Byte1, u8 Byte2, u32 Addr)//在AAI模式下,以Addr為起始地址,分別寫入Byte1和Byte2,必須和SST25V_AAI_WordsProgram()函數配套使用
{
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(AAI_WordProgram); //發送AAI模式寫入數據命令
SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發送24位的寫入數據起始地址
SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
SPI_Flash_SendByte(Addr & 0xFF);
SPI_Flash_SendByte(Byte1); //寫入數據Byte1
SPI_Flash_SendByte(Byte2); //寫入數據Byte2
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
}
void SST25V_AAI_WordsProgram(u8 state,u8 Byte1, u8 Byte2) //在AAI模式下,繼續寫入Byte1和Byte2,必須和SST25V_AAI_WordProgram()函數配套使用,state==1退出AAI模式
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(AAI_WordProgram); //繼續發送AAI模式寫入數據命令
SPI_Flash_SendByte(Byte1); //寫入數據Byte1
SPI_Flash_SendByte(Byte2); //寫入數據Byte2
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待寫操作完成
if(state==1) //state==1時,退出AAI模式
{
SST25V_WriteDisable();
}
}
void SST25V_SectorErase_4KByte(u32 Addr) //擦除4KB數據空間,Addr是擦除起始地址
{
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(SectorErace_4KB); //發送擦除4KB數據空間命令
SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發送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數據空間,Addr是擦除起始地址
{
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(BlockErace_32KB); //發送擦除32KB數據空間命令
SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發送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數據空間,Addr是擦除起始地址
{
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(BlockErace_64KB); //發送擦除64KB數據空間命令
SPI_Flash_SendByte((Addr & 0xFF0000) >> 16); //發送24位的擦除起始地址
SPI_Flash_SendByte((Addr & 0xFF00) >> 8);
SPI_Flash_SendByte(Addr & 0xFF);
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待擦除操作完成
}
void SST25V_ChipErase(void) //擦除整個芯片數據空間
{
SST25V_WriteEnable(); //允許寫入操作
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(ChipErace); //發送擦除整個芯片空間命令
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
SST25V_WaitForWriteEnd(); //等待擦除操作完成
}
u8 SST25V_ReadStatusRegister(void) //讀取狀態寄存器
{
u8 StatusRegister = 0;
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(ReadStatusRegister); //發送讀取狀態寄存器命令
StatusRegister = SPI_Flash_ReceiveByte(); //接收狀態寄存器數據
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
return StatusRegister; //返回讀取到的狀態寄存器數據
}
void SST25V_WriteEnable(void) //允許對芯片寫入操作
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(WriteEnable); //發送允許寫入操作命令
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
void SST25V_WriteDisable(void) //禁止對芯片寫入操作
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(WriteDisable); //發送禁止寫入操作命令
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
void SST25V_EnableWriteStatusRegister(void) //允許改寫狀態寄存器
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(EnableWriteStatusRegister); //發送允許改寫狀態寄存器命令
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
void SST25V_WriteStatusRegister(u8 Byte) //改寫狀態寄存器,向狀態寄存器寫入數據Byte
{
SST25V_EnableWriteStatusRegister(); //允許改寫狀態寄存器
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(WriteStatusRegister); //發送改寫狀態寄存器命令
SPI_Flash_SendByte(Byte); //向狀態寄存器寫入數據Byte
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
void SST25V_WaitForWriteEnd(void) //等待寫入操作完成
{
u8 FLASH_Status = 0;
SST25V_CS_LOW(); //片選端置低--選中芯片
do
{
FLASH_Status = SST25V_ReadStatusRegister(); //獲取狀態寄存器值
} while((FLASH_Status & 0x01) == SET); //判斷芯片是否處于忙碌狀態,忙則繼續讀取狀態寄存器的值
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); //發送讀取JEDEC ID命令
Temp0 = SPI_Flash_ReceiveByte(); //接收第一字節數據
Temp1 = SPI_Flash_ReceiveByte(); //接收第二字節數據
Temp2 = SPI_Flash_ReceiveByte(); //接收第三字節數據
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的狀態決定第一個字節是DeviceID還是ManufacturerID
{
u16 ManuID_DeviceID = 0; //存儲16位的ID數據
u8 ManufacturerID = 0, DeviceID = 0;
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(ReadDeviceID); //發送讀取設備ID信息命令
SPI_Flash_SendByte((ReadManu_DeviceID_Addr & 0xFF0000) >> 16); //發送24位的地址字節,該地址為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位的數據,高字節為ManufacturerID,低字節為DeviceID
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
return ManuID_DeviceID; //返回16位的ManuID_DeviceID,高字節為ManufacturerID,低字節為DeviceID
}
void SST25V_EBSY() //允許AAI模式期間,SO腳輸出忙狀態
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(EBSY); //發送允許AAI模式期間,SO腳輸出忙狀態命令
SST25V_CS_HIGH(); //片選CS#管腳置高--不選中芯片
}
void SST25V_DBSY() //禁止AAI模式期間,SO腳輸出忙狀態
{
SST25V_CS_LOW(); //片選端置低--選中芯片
SPI_Flash_SendByte(DBSY); //發送禁止AAI模式期間,SO腳輸出忙狀態命令
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 //讀取存儲器數據
#define HighSpeedReadData 0x0B //快速讀取存儲器數據
#define SectorErace_4KB 0x20 //扇區擦除
#define BlockErace_32KB 0x52 //32KB塊擦除
#define BlockErace_64KB 0xD8 //64KB塊擦除
#define ChipErace 0xC7 //片擦除
#define Byte_Program 0x02 //頁面編程--寫數據
#define AAI_WordProgram 0xAD
#define ReadStatusRegister 0x05 //讀狀態寄存器
#define EnableWriteStatusRegister 0x50
#define WriteStatusRegister 0x01 //寫狀態寄存器
#define WriteEnable 0x06 //寫使能,設置狀態寄存器
#define WriteDisable 0x04 //寫禁止
#define ReadDeviceID 0xAB //獲取設備ID信息
#define ReadJedec_ID 0x9F //JEDEC的ID信息
#define EBSY 0X70 //允許AAI模式期間,SO腳輸出忙狀態命令
#define DBSY 0X80 //禁止AAI模式期間,SO腳輸出忙狀態命令
void SST25V_Init(void); //Flash芯片初始化
u8 SST25V_ByteRead(u32 ReadAddr); //從ReadAddr地址讀取一個字節數據
void SST25V_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead); //從ReadAddr地址開始讀取NumByteToRead個字節數據
u8 SST25V_HighSpeedByteRead(u32 ReadAddr); //從ReadAddr高速讀取一個字節數據
void SST25V_HighSpeedBufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);//從ReadAddr開始高速讀取NumByteToRead個字節數據,并存儲于pBuffer中
u8 SPI_Flash_SendByte(u8 byte); //SPI發送數據
u8 SPI_Flash_ReceiveByte(void); //SPI接收數據
void SST25V_ByteWrite(u8 Byte, u32 WriteAddr); //寫入一個數據字節
void SST25V_BufferWrite(u8 *pBuffer,u32 Addr,u16 BufferLength);//將pBuffer中的BufferLength個字節數據寫入到以Addr為起始地址的區域
void SST25V_WriteBytes(u8 Byte, u32 WriteAddr,u32 ByteLength); //以WriteAddr為起始地址,寫入ByteLength個數據Byte(寫入的是同一個數據Byte)
void SST25V_AAI_WriteBytes(u8 Byte, u32 Addr,u32 ByteLength); //以Addr為起始地址,用AAI模式,寫入ByteLength個數據Byte(寫入的是同一個數據Byte)ByteLength必須為偶數
void SST25V_AAI_BufferProgram(u8 *pBuffer,u32 Addr,u16 BufferLength); //用AAI模式將pBuffer中的BufferLength個字節數據寫入到以Addr為起始地址的區域,ByteLength必須為偶數
void SST25V_AAI_WordProgram(u8 Byte1, u8 Byte2, u32 Addr); //在AAI模式下,以Addr為起始地址,分別寫入Byte1和Byte2,必須和SST25V_AAI_WordsProgram()函數配套使用
void SST25V_AAI_WordsProgram(u8 state,u8 Byte1, u8 Byte2); //在AAI模式下,繼續寫入Byte1和Byte2,必須和SST25V_AAI_WordProgram()函數配套使用,state==1退出AAI模式
void SST25V_SectorErase_4KByte(u32 Addr); //擦除4KB數據空間,Addr是擦除起始地址
void SST25V_BlockErase_32KByte(u32 Addr); //擦除32KB數據空間,Addr是擦除起始地址
void SST25V_BlockErase_64KByte(u32 Addr); //擦除64KB數據空間,Addr是擦除起始地址
void SST25V_ChipErase(void); //擦除整個芯片數據空間
u8 SST25V_ReadStatusRegister(void); //讀取狀態寄存器
void SST25V_WriteEnable(void); //允許對芯片寫入操作
void SST25V_WriteDisable(void); //禁止對芯片寫入操作
void SST25V_EnableWriteStatusRegister(void); //允許改寫狀態寄存器
void SST25V_WriteStatusRegister(u8 Byte); //改寫狀態寄存器,向狀態寄存器寫入數據Byte
void SST25V_WaitForWriteEnd(void); //等待寫入操作完成
u32 SST25V_ReadJedecID(void); //讀取JEDEC ID
u16 SST25V_ReadManuID_DeviceID(u32 ReadManu_DeviceID_Addr); //讀取ManufacturerID和DeviceID,ReadManu_DeviceID_Addr的狀態決定第一個字節是DeviceID還是ManufacturerID
void SST25V_EBSY(); //允許AAI模式期間,SO腳輸出忙狀態
void SST25V_DBSY(); //禁止AAI模式期間,SO腳輸出忙狀態
#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,以便調試觀察
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設置為雙線雙向全雙工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //設置為主 SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI發送接收 8 位幀結構
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //時鐘懸空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //數據捕獲于第二個時鐘沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //內部 NSS 信號有 SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //波特率預分頻值為 4
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //數據傳輸從 MSB 位開始
SPI_InitStructure.SPI_CRCPolynomial = 7; //定義了用于 CRC值計算的多項式 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