新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32 SPI W25X16驅動

        STM32 SPI W25X16驅動

        作者: 時間:2016-11-25 來源:網絡 收藏

        void User_SPI_W25X16_WaitForWriteEnd(void)
        {
        u8 ReceiveStatus;//用于存放W25X16返回的狀態非零就是操作結束

        SPI_W25X16_CS_Select;

        User_SPI_W25X16_SendByte(ReadStatusRegister);

        do
        {
        ReceiveStatus=User_SPI_W25X16_SendByte(NoneCode);
        }
        while(ReceiveStatus & JudgeCode==SET);

        SPI_W25X16_CS_DisSelect;
        }

        本文引用地址:http://www.104case.com/article/201611/321302.htm


        void User_SPI_W25X16_SectorErase(vu32 SectorAddress)
        {

        User_SPI_W25X16_WriteEnable();

        SPI_W25X16_CS_Select;


        User_SPI_W25X16_SendByte(SectorErase);

        User_SPI_W25X16_SendByte((SectorAddress & 0xff0000)>>16); //發送最高8位
        User_SPI_W25X16_SendByte((SectorAddress & 0xff00)>>8); // 中間8位
        User_SPI_W25X16_SendByte(SectorAddress & 0xff); //發送最低8位


        SPI_W25X16_CS_DisSelect;


        User_SPI_W25X16_WaitForWriteEnd();
        }


        void User_SPI_W25X16_BulkErase(void)
        {

        User_SPI_W25X16_WriteEnable();

        SPI_W25X16_CS_Select;


        User_SPI_W25X16_SendByte(ChipErase);


        SPI_W25X16_CS_DisSelect;


        User_SPI_W25X16_WaitForWriteEnd();
        }


        void User_SPI_W25X16_PageWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite)
        {

        User_SPI_W25X16_WriteEnable();

        SPI_W25X16_CS_Select;


        User_SPI_W25X16_SendByte(PageProgram);


        User_SPI_W25X16_SendByte((WriteAddress & 0xff0000)>>16); //最高8位地址
        User_SPI_W25X16_SendByte((WriteAddress & 0xff00)>>8); //中間8位地址
        User_SPI_W25X16_SendByte(WriteAddress & 0xff); //最低8位地址


        if(NumberOfWrite > SPI_W25X16_PerPageWriteSize) //W25X16采用的是頁寫入方式,最多一次性寫入256個數據,然后內部地址指針歸零
        {
        NumberOfWrite=SPI_W25X16_PerPageWriteSize;
        printf("哦偶,一次性寫入的數據太多,不能超過256的啦,ARM將為你寫入前256個數據");
        }


        while(NumberOfWrite--)
        {
        User_SPI_W25X16_SendByte(*DataTable);
        DataTable++; //數組指針 +1
        }

        SPI_W25X16_CS_DisSelect;


        User_SPI_W25X16_WaitForWriteEnd();
        }


        void User_SPI_W25X16_ChipWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite)
        {
        u8 AddressRemainder =0;
        u8 NumberOfPage =0;
        u8 Count =0; //存放地址所在頁需要寫入的最多數據
        u8 NumberOfSingle =0; //寫入數據的最后一些需要寫入的數據個數
        u8 Buffer =0; //保留

        AddressRemainder =WriteAddress % SPI_W25X16_PageSize;
        Count =SPI_W25X16_PageSize - AddressRemainder;
        NumberOfPage =NumberOfWrite / SPI_W25X16_PageSize;
        NumberOfSingle =NumberOfWrite % SPI_W25X16_PageSize;


        if(AddressRemainder==0)
        {

        if(NumberOfPage==0) //NumberOfWrite < SPI_W25X16_PageSize
        {
        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfWrite);
        }

        else
        {

        while(NumberOfPage--)
        {
        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,SPI_W25X16_PageSize); //一次性寫入256個
        DataTable+=SPI_W25X16_PageSize; //接著寫下一個256數據
        WriteAddress+=SPI_W25X16_PageSize; //地址就移到下一頁(256為單位)
        }

        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfSingle);
        }
        }

        else
        {

        if(NumberOfPage==0)
        {

        if(NumberOfWrite < Count)
        {
        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfWrite);
        }

        else
        {

        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,Count); //起始地址所在頁只需要寫入Count個
        Buffer=NumberOfWrite-Count; //計算出下一頁要寫入的數據數量
        DataTable+=Count;
        WriteAddress+=Count;


        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,Buffer);
        }
        }

        else
        {

        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,Count);

        //之后需要重新計算以下參數 原因:數據量超過一頁分兩種情況:1、數據量不會覆蓋完起始地址下一頁;2、數據量會完全覆蓋起始地址下一頁
        //重新計算就是看是否會覆蓋掉下一頁,如果會就進入while()循環,否則就不進入
        DataTable+=Count;
        WriteAddress+=Count;
        NumberOfWrite-=Count;
        NumberOfPage=NumberOfWrite / SPI_W25X16_PageSize;
        NumberOfSingle=NumberOfWrite % SPI_W25X16_PageSize;


        while(NumberOfPage--)
        {
        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,SPI_W25X16_PageSize);
        DataTable+=SPI_W25X16_PageSize;
        WriteAddress+=SPI_W25X16_PageSize;
        }


        if(NumberOfSingle != 0)
        {
        User_SPI_W25X16_PageWrite(DataTable,WriteAddress,NumberOfSingle);
        }
        }
        }
        }


        void User_SPI_W25X16_ChipRead(u8 *DataTable,vu32 ReadAddress,vu16 NumberOfRead)
        {
        //雖然要發送地址,但是不需要說明有個寫操作(I2C才是這樣的時序)
        SPI_W25X16_CS_Select;


        User_SPI_W25X16_SendByte(ReadData);


        User_SPI_W25X16_SendByte((ReadAddress & 0xff0000) >> 16); //最高8位地址
        User_SPI_W25X16_SendByte((ReadAddress & 0xff00) >> 8); //中間8位
        User_SPI_W25X16_SendByte(ReadAddress & 0xff); //最低8位


        while(NumberOfRead--)
        {
        *DataTable = User_SPI_W25X16_SendByte(NoneCode);
        DataTable++;
        }


        SPI_W25X16_CS_DisSelect;
        }


        vu32 User_SPI_W25X16_ReadID(void)
        {
        vu32 ID =0;
        vu32 IDBuffer1=0;
        vu32 IDBuffer2=0;
        vu32 IDBuffer3=0;

        SPI_W25X16_CS_Select;

        User_SPI_W25X16_SendByte(JedecID);


        IDBuffer1=User_SPI_W25X16_SendByte(NoneCode);//讀取高位
        IDBuffer2=User_SPI_W25X16_SendByte(NoneCode);//讀取中位
        IDBuffer3=User_SPI_W25X16_SendByte(NoneCode);//讀取低位

        SPI_W25X16_CS_DisSelect;

        ID=(IDBuffer1<<16)|(IDBuffer2<<8)|IDBuffer3;

        return ID;
        }


        vu32 User_SPI_W25X16_ReadDeviceID(void)
        {
        vu32 ID =0;
        vu32 IDBuffer1=0;
        vu32 IDBuffer2=0;
        vu32 IDBuffer3=0;

        SPI_W25X16_CS_Select;

        User_SPI_W25X16_SendByte(ManufatureID);


        IDBuffer1=User_SPI_W25X16_SendByte(NoneCode);//讀取高位
        IDBuffer2=User_SPI_W25X16_SendByte(NoneCode);//讀取中位
        IDBuffer3=User_SPI_W25X16_SendByte(NoneCode);//讀取低位

        SPI_W25X16_CS_DisSelect;

        ID=(IDBuffer1<<16)|(IDBuffer2<<8)|IDBuffer3;

        return ID;
        }


        void User_SPI_W25X16_StartReadSequence(vu32 ReadAddress)
        {
        SPI_W25X16_CS_Select;

        User_SPI_W25X16_SendByte(ReadData);

        User_SPI_W25X16_SendByte((ReadAddress & 0xff0000) >> 16); //最高8位地址
        User_SPI_W25X16_SendByte((ReadAddress & 0xff00) >> 8); //中間8位
        User_SPI_W25X16_SendByte(ReadAddress & 0xff); //最低8位

        //SPI_W25X16_DisSelect;
        }


        void User_SPI_W25X16_PowerDown(void)
        {
        SPI_W25X16_CS_Select;

        User_SPI_W25X16_SendByte(PowerDown);

        SPI_W25X16_CS_DisSelect;
        }


        void User_SPI_W25X16_WakeUp(void)
        {
        SPI_W25X16_CS_Select;

        User_SPI_W25X16_SendByte(WakeUp);

        SPI_W25X16_CS_DisSelect;
        }

        user_spi_w25x16.h

        //SPI FLASH chip W25X16 頭文件

        #ifndef _USER_SPI_W25X16_H
        #define _USER_SPI_W25X16_H

        #include"stm32f10x.h"

        typedef enum{Failed=0,Successed=!Failed}TestStatus; //聲明定義枚舉型變量 用于表示測試失敗與成功

        #define SPI_W25X16_SectorSize4096
        #define SPI_W25X16_PageSize256//W25X16每頁數據長度
        #define SPI_W25X16_PerPageWriteSize256//每頁最多寫入的數據個數


        #define SPI_W25X16SPI1
        #define SPI_W25X16_ClockRCC_APB2Periph_SPI1


        #define SPI_W25X16_CS_ClockRCC_APB2Periph_GPIOC
        #define SPI_W25X16_CS_PortGPIOC
        #define SPI_W25X16_CS_PinGPIO_Pin_4


        #define SPI_W25X16_SCK_ClockRCC_APB2Periph_GPIOA
        #define SPI_W25X16_SCK_PortGPIOA
        #define SPI_W25X16_SCK_PinGPIO_Pin_5


        #define SPI_W25X16_MISO_Clock RCC_APB2Periph_GPIOA
        #define SPI_W25X16_MISO_PortGPIOA
        #define SPI_W25X16_MISO_PinGPIO_Pin_6


        #define SPI_W25X16_MOSI_ClockRCC_APB2Periph_GPIOA
        #define SPI_W25X16_MOSI_PortGPIOA
        #define SPI_W25X16_MOSI_PinGPIO_Pin_7


        #define SPI_24G_CS_ClockRCC_APB2Periph_GPIOB
        #define SPI_24G_CS_PortGPIOB
        #define SPI_24G_CS_PinGPIO_Pin_2


        #define SPI_VS1003B_CS_ClockRCC_APB2Periph_GPIOB
        #define SPI_VS1003B_CS_PortGPIOB
        #define SPI_VS1003B_CS_PinGPIO_Pin_0


        #define SPI_W25X16_CS_SelectGPIO_ResetBits(SPI_W25X16_CS_Port,SPI_W25X16_CS_Pin)

        #define SPI_W25X16_CS_DisSelectGPIO_SetBits(SPI_W25X16_CS_Port,SPI_W25X16_CS_Pin)



        u8 User_SPI_W25X16_SendByte(u8 SendByteData) ;//send data that is byte
        u8 User_SPI_W25X16_ReadByte(void); //Read ByteData from chip W25X16
        vu16 User_SPI_W25X16_SendHalfWord(u16 HalfWord) ;//send data ,is halfword
        void User_SPI_W25X16_WriteEnable(void); //write enable for W25X16
        void User_SPI_W25X16_WaitForWriteEnd(void); //wait the end about write for chip W25X16


        void User_SPI_Config(void); //SPI1 init configuration
        void User_SPI_W25X16_SectorErase(vu32 SectorAddress);
        void User_SPI_W25X16_BulkErase(void);//erase the W25X16
        void User_SPI_W25X16_PageWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite);
        void User_SPI_W25X16_ChipWrite(u8 *DataTable,vu32 WriteAddress,vu16 NumberOfWrite);
        void User_SPI_W25X16_ChipRead(u8 *DataTable,vu32 ReadAddress,vu16 NumberOfRead);
        vu32 User_SPI_W25X16_ReadID(void);//read chip ID
        vu32 User_SPI_W25X16_ReadDeviceID(void);//read manufacture device ID
        void User_SPI_W25X16_StartReadSequence(vu32 ReadAddress);
        void User_SPI_W25X16_PowerDown(void);
        void User_SPI_W25X16_WakeUp(void);


        #endif

        以上,結束。


        上一頁 1 2 下一頁

        關鍵詞: STM32SPIW25X16驅

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 鄢陵县| 辽宁省| 竹北市| 江津市| 当雄县| 察隅县| 黄骅市| 农安县| 呼图壁县| 阿坝县| 北票市| 仁布县| 澜沧| 峨山| 大化| 曲周县| 张北县| 阿拉尔市| 石景山区| 皋兰县| 阳信县| 牙克石市| 格尔木市| 怀集县| 湘阴县| 临城县| 永登县| 全椒县| 昌平区| 长泰县| 沐川县| 广宗县| 宁德市| 德阳市| 区。| 河东区| 唐山市| 六安市| 扬州市| 合肥市| 上栗县|