本案例使用的是新唐M451的SPI1驅動W25M02的.- //W25 IC復位
- void SpiFlash_Rest(void)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- //有些地方使用了 16 24 32 位模式 所以這里會重新設置一遍
- SPI_SET_DATA_WIDTH(SPI1, 8);//設置SPI為8位模式
- au32SourceData = 0xFF;//復位指令
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- }
- //選擇模具 IChange == 0 或 1
- void SpiFlash_IC_Change(u8 IChange)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);//設置SPI為8位模式
- //選擇模具指令 選擇W25M02GV內的兩片W25N01GV中的其中一片 然后進行操作
- au32SourceData = 0xC2;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = IChange;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- }
- //讀取IC ID值 一共24位
- unsigned int SpiFlash_ReadMidDid(void)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x9F;//讀取ID指令 9F 00
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- //如果不想更改SPI設置 也可以拆成3個8位來操作
- SPI_SET_DATA_WIDTH(SPI1, 24);//設置SPI為24位模式
- I2S_CLR_RX_FIFO(SPI1);//清除SPI緩存
- // 接收
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- //導出SPI緩存數據
- au32DestinationData = SPI_READ_RX(SPI1);
- return (au32DestinationData & 0xffffff);
- }
- //寫寄存器1
- void SpiFlash_WriteStatusReg1(u8 SRData)
- { unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x01;//寫寄存器1指令: 01 A0
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0xA0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = SRData;;//寫寄存器1:數據
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- }
- //寫狀態寄存器2
- void SpiFlash_WriteStatusReg2(u8 SRData)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x01;//寫寄存器2指令: 01 B0
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0xB0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = SRData;//寫寄存器2:數據
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- }
- //讀寄存器1
- unsigned int SpiFlash_ReadStatusReg1(void)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x05;//讀寄存器1指令: 05 A0
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0xA0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- I2S_CLR_RX_FIFO(SPI1);
- au32SourceData = 0X0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32DestinationData = SPI_READ_RX(SPI1);//導致寄存器1數據
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- return (au32DestinationData & 0xFF);
- }
- //讀寄存器2
- unsigned int SpiFlash_ReadStatusReg2(void)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1); SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x05;//讀寄存器2指令: 05 B0
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0xB0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- I2S_CLR_RX_FIFO(SPI1);
- au32SourceData = 0X0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32DestinationData = SPI_READ_RX(SPI1);
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- return (au32DestinationData & 0xFF);
- }
- //讀寄存器3
- unsigned int SpiFlash_ReadStatusReg3(void)
- {
- unsigned int au32SourceData;
- unsigned int au32DestinationData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x05;//讀寄存器2指令: 05 C0
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0xC0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- I2S_CLR_RX_FIFO(SPI1);
- au32SourceData = 0X0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32DestinationData = SPI_READ_RX(SPI1);
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- return (au32DestinationData & 0xFF);
- }
- //等待ic空閑
- void SpiFlash_WaitReady(void)
- {
- unsigned int ReturnValue;
- do
- { ReturnValue = SpiFlash_ReadStatusReg3();
- ReturnValue = ReturnValue & 1;
- }while(ReturnValue != 0);
- }
- //判斷是否正在寫入IC
- void SpiFlash_WaitWEL_1(void)
- {
- unsigned int ReturnValue;
- do
- { ReturnValue = SpiFlash_ReadStatusReg3();
- ReturnValue = ReturnValue | 0XFD;
- }while(ReturnValue != 0XFF);
- }
- //擦除一塊數據 64頁 :64*2048=128k 字節
- void SpiFlash_PageErase(u32 StartAddress)
- { unsigned int au32SourceData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x06;//寫啟用指令 06
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- SpiFlash_WaitReady();//等閑
- SpiFlash_WaitWEL_1();
- SPI_SET_SS_LOW(SPI1);
- au32SourceData = 0xD8;//擦除塊 指令 D8 00
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 16);
- //改塊64頁中任意一頁地址
- au32SourceData=ADDR_Row_PA15_PA0(StartAddress);
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- SpiFlash_WaitReady();//等閑
- }
- //擦除功能函數
- void SpiFlash_ChipErase(u32 StartAddress)
- {
- SpiFlash_PageErase(StartAddress);
- W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
- if(W25M_STR3 & 0x04)//擦除失敗
- {
- //printf("\r\nErase_Error\r\n");
- SpiFlash_PageErase(StartAddress);
- }
- SpiFlash_WaitReady();
- }
- //寫入數據功能函數
- //StartAddress1 12~27位: 頁地址
- //StartAddress1 0~11位:頁內數據位置
- //ByteCount字節個數
- void SpiFlash_WriteData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
- {
- u32 au32SourceData;
- unsigned int Counter;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x06;//寫啟用指令 06
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- SpiFlash_WaitReady();//等閑
- SpiFlash_WaitWEL_1();
- SPI_SET_SS_LOW(SPI1);
- au32SourceData = 0x02;//數據寫入IC緩沖區指令 02
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 16); au32SourceData=StartAddress1;
- au32SourceData = (u16)(au32SourceData&0x7ff);//頁內位置
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 8);
- for(Counter = 0; Counter < ByteCount; Counter++)//數據寫入IC換沖執行過程
- {
- au32SourceData = DataBuffer[Counter];
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- }
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- SpiFlash_WaitReady();//等閑
- SPI_SET_SS_LOW(SPI1);
- au32SourceData = 0x10;//換沖導入存儲區指令 10 00
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 16);
- au32SourceData=StartAddress1;
- au32SourceData = (u16)(au32SourceData>>12);//頁地址
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- SpiFlash_WaitReady();//等閑
- W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
- if(W25M_STR3 & 0x08)//寫入失敗
- {
- //printf("\r\nWrite_Error\r\n");
- }
- SpiFlash_WaitReady();
- }
- //一頁數據導出到IC緩沖區
- void SpiFlash_LoadData(u32 StartAddress1)
- {
- u32 au32SourceData;
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x13;//頁數據讀取到緩存指令 13 00
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 16);
- au32SourceData=(u16)(StartAddress1>>12);//頁地址
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_SS_HIGH(SPI1);
- sys_delayms(2);
- SpiFlash_WaitReady();//等閑
-
- }
- //讀出數據功能函數
- //StartAddress1 12~27位: 頁地址
- //StartAddress1 0~11位:頁內數據位置
- //ByteCount字節個數void SpiFlash_ReadData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
- {
- u32 au32SourceData;
- unsigned int au32DestinationData;
- unsigned int Counter;
- SpiFlash_LoadData(StartAddress1);
- W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
- if(W25M_STR3 & 0x20)//讀取失敗
- {
- //printf("\r\nRead_Load_Error\r\n");
- SpiFlash_LoadData(StartAddress1);
- W25M_STR3=SpiFlash_ReadStatusReg3();//判斷是否成功
- if(W25M_STR3 & 0x20)//讀取失敗
- {
- //UART1_PUTS(":讀取失敗\r\n");
- }
- }
- SPI_SET_SS_LOW(SPI1);
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x03;//讀取IC緩沖區數據指令 03
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 16);
- au32SourceData=StartAddress1;
- au32SourceData = (u16)(au32SourceData&0x7ff);//頁內位置
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- SPI_SET_DATA_WIDTH(SPI1, 8);
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- I2S_CLR_RX_FIFO(SPI1);//清空SPI緩沖區 準備接收IC緩沖區數據
- for(Counter = 0; Counter < ByteCount; Counter++)
- {
- au32SourceData = 0x0;
- SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
- au32DestinationData = SPI_READ_RX(SPI1);
- DataBuffer[Counter] = (u8) au32DestinationData;
- }
- SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
- SpiFlash_WaitReady();
- }
- //以下是工程函數的案例
- #defineW25PAGE(n)( 4096 * n )
- //0 <= n < { 1024(塊)*64(頁)}
- //注意:擦除操作時是擦除整塊 SpiFlash_ChipErase(W25PAGE(n))
- //拿第一塊為例:n=0或n=63都是擦除第一塊64個頁的存儲區
- //參數寫0并保存
- void W25M_write_0(void)
- {
- u16 i=0;
- for(i=0;i<2048;i++)
- {W25M_temp[i]=0;}
- SpiFlash_ChipErase(W25PAGE(0));SpiFlash_WriteData(W25M_temp, W25PAGE(0),2048);
- }
- //保存工程參數
- void W25M_write_GongChen(void)
- {
- SpiFlash_ChipErase(W25PAGE(0));
- SpiFlash_WriteData(W25M_temp, W25PAGE(0),500);
- }
- //讀取工程參數
- void W25M_read_GongChen(void)
- {
- SpiFlash_ReadData(W25M_temp,W25PAGE(0),500);
- }
復制代碼
|