在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<abbr id="27omo"></abbr>

<menu id="27omo"><dl id="27omo"></dl></menu>
    • <label id="27omo"><tt id="27omo"></tt></label>

      新聞中心

      EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > SST25VF080B SPI接口FLASH STM32驅(qū)動

      SST25VF080B SPI接口FLASH STM32驅(qū)動

      作者: 時間:2016-10-07 來源:網(wǎng)絡 收藏

        所有的FLASHA 都一樣只能從1變0,要想從0變1 只有擦除一個頁扇, SST25VF080B 最小可以擦除4KB的頁 速度也不錯 50MHz 容量1MB 挺夠用的 10萬次的擦寫壽命。最低2.7V 就可正常工作。

      本文引用地址:http://www.biyoush.com/article/201610/310909.htm

        Flexible Erase Capability

        – Uniform 4 KByte sectors

        – Uniform 32 KByte overlay blocks

        – Uniform 64 KByte overlay blocks

        先記下 這些個7788的命令

        

       

        SST25VF080B 的各種命令比較繁瑣

       

        Status Register這個設置寫保護多點 我這里只用它的判忙BUSY

        

       

        一樣先配置與GPIO口 上圖~~

       

        

       

        

       

        在這也就是CE有用片選嘛~~

        #define SST_SELECT() GPIO_ResetBits(GPIOC, GPIO_Pin_13) /* SST CS = L */

        #define SST_DESELECT() GPIO_SetBits(GPIOC, GPIO_Pin_13) /* SST CS = H */

        /***********************************************

        **函數(shù)名:FLASH__Config

        **功能:初始化串行FLASH的接口

        **注意事項:串行FLASH使用了SPI1接口

        ***********************************************/

        void FLASH_SPI_Config(void)

        {

        SPI_InitTypeDef SPI_InitStructure;

        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |

        RCC_APB2Periph_AFIO |

        RCC_APB2Periph_SPI1,

        ENABLE);

        /* SCK, MISO and MOSI A5=CLK,A6=MISO,A7=MOSI*/

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* PC.13 作片選*/

        GPIO_SetBits(GPIOC, GPIO_Pin_13); //預置為高

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

        GPIO_Init(GPIOC, &GPIO_InitStructure);

        /* SPI1 configuration */

        SPI_Cmd(SPI1, DISABLE); //必須先禁能,才能改變MODE

        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //兩線全雙工

        SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主

        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位

        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CPOL=0 時鐘懸空低

        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //CPHA=0 數(shù)據(jù)捕獲第1個

        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //軟件NSS

        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //2分頻=36M SST25VF說是50M沒事

        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前

        SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC7 我不解的是如果出錯要如何處理

        SPI_Init(SPI1, &SPI_InitStructure);

        //SPI_SSOutputCmd(SPI1, ENABLE); //使能NSS腳可用 我這就一個SPI 器件

        SPI_Cmd(SPI1, ENABLE);

        }

        /***************************************

        **函數(shù)名:SPIByte

        **功能:讀寫SPI總線

        **注意事項:對于SPI來說,主機的讀也需要先寫,

        **使用此函數(shù),讀的時候建議參數(shù)設置為0xff,寫的時候則寫參數(shù).這里使用直接操作寄存器的辦法實現(xiàn)SPI硬件層讀寫,是為了加快速寫速度 在說LCD 的時候我用的就是庫函數(shù) 比如

        SPI_I2S_SendData SPI_I2S_ReceiveData SPI_I2S_GetFlagStatus

        ***************************************/

        static u8 SPIByte(u8 byte)

        {

        /*等待發(fā)送寄存器空*/

        while((SPI1->SR & SPI_I2S_FLAG_TXE)==RESET);

        /*發(fā)送一個字節(jié)*/

        SPI1->DR = byte;

        /* 等待接收寄存器有效*/

        while((SPI1->SR & SPI_I2S_FLAG_RXNE)==RESET);

        return(SPI1->DR);

        }

        

       

        //咱用模式0

        /*****************************************

        **函數(shù)名:SSTCmd1/2/4

        **功能:寫一個SST命令/寫一個命令后接一個數(shù)據(jù)/寫一個命令后再寫3個數(shù)據(jù)

        **注意事項:這是一個完整的單命令操作,不返回

        *****************************************/

        void SSTCmd1(u8 cmd)

        {

        SST_SELECT();

        SPIByte(cmd);

        SST_DESELECT();

        }

        void SSTCmd2(u8 cmd,u8 data)

        {

        SST_SELECT();

        SPIByte(cmd);

        SPIByte(data);

        SST_DESELECT();

        }

        void SSTCmd4(u8 cmd,u8 *addr)

        {

        SST_SELECT();

        SPIByte(cmd); //首命令

        SPIByte(*addr++);

        SPIByte(*addr++);

        SPIByte(*addr);

        SST_DESELECT();

        }

        /****************************************

        **函數(shù)名:SSTCmdb1b/SSTCmd4bs

        **功能:寫一個SST命令,返回1字節(jié)數(shù)據(jù)/寫1個命令字,3個地址字,返回多個字節(jié)

        **更多使用在讀出上的

        ****************************************/

        u8 SSTCmdb1b(u8 cmd)

        {

        u8 tmp;

        SST_SELECT();

        SPIByte(cmd);

        tmp=SPIByte(0xff);

        SST_DESELECT();

        return(tmp);

        }

        void SSTCmd4bs(u8 cmd,u8* addr,u8* data,u32 no)

        {

        SST_SELECT();

        SPIByte(cmd); //首命令

        SPIByte(*addr++);

        SPIByte(*addr++);

        SPIByte(*addr);

        for(;no>0;no--)

        {

        *data++=SPIByte(0xff);

        }

        SST_DESELECT();

        }

        //命令時序復雜啊~~當然了我這為了求全都寫出來了

        常用的芯片功能

        /***************************************

        SST25WREN 允許寫功能

        ***************************************/

        void SST25WREN(void)

        {

        SSTCmd1(0x06);

        }

        /***********************************

        SST25WRDI 屏蔽寫功能

        ***********************************/

        void SST25WRDI(void)

        {

        SSTCmd1(0x04);

        }

        

       

        /**********************************

        SST25BY 檢測忙

        **********************************/

        u8 SST25BY(void)

        {

        u8 sta;

        sta=SSTCmdb1b(0x05);

        return(sta&0x01);

        }

        /***********************************

        SST25WPEN 允許軟件寫保護

        注意事項:25的寫入比較繁瑣,建議在每次操作前都取消掉寫保護,操作完成后則重新允許寫保護

        

       

        ***********************************/

        void SST25WPEN(void)

        {

        u8 sta;

        sta=SSTCmdb1b(0x05)|0x1c; //讀出寄存器并加入保護位

        SSTCmd1(0x50); //允許寫Status Register

        SSTCmd2(0x01,sta);

        }

        //先消除保護位,再允許寫位

        void SST25WriteEn(void)

        {

        u8 sta;

        sta=SSTCmdb1b(0x05)&(~0x1c); //讀出寄存器并消除保護位

        SSTCmd1(0x50); //允許寫寄存器Status Register

        SSTCmd2(0x01,sta); //寫寄存器

        SSTCmd1(0x06); //允許寫

        }

        /********************************寄存器Status Register**********************************/

        

       

        就是這樣實現(xiàn)寫保護。

        

       

        /**********************************

        SST25ReadID 讀取SST的ID 這個功能 呵呵不用多說~當然單純的讀寫操作肯定用不上

        **********************************/

        u16 SST25ReadID(void)

        {

        u8 id[3];

        u8 addr[3]={0,0,0};

        SSTCmd4bs(0x90,addr,id,3);

        return((id[0]<<8)+id[1]);

        }

        

       

        /**********************************

        SST25ChipErase 刷除CHIP

        **********************************/

        void SST25ChipErase(void)

        {

        SST25WriteEn();

        SSTCmd1(0x60);

        while(SST25BY());

        SST25WPEN();

        }

        

       

        /***********************************

        SST25SectorErase 刷扇區(qū) 用的是4kb大小 假如地址在0~4095 之間那么這之間的地址都會刷除

        當然我給 4096 的話4096到4096+4095 之間都會刷掉

        ***********************************/

        void SST25SectorErase(u32 addr)

        {

        u8 ad[3];

        ad[0]=(addr>>16)&0xff;

        ad[1]=(addr>>8)&0xff;

        ad[2]=addr&0xff;

        SST25WriteEn();

        SST_SELECT();

        SPIByte(0x20);

        SPIByte(ad[0]);

        SPIByte(ad[1]);

        SPIByte(ad[2]);

        SST_DESELECT();

        while(SST25BY());

        // SST25WPEN();

        }

        /**********************************

        SST25ByteProgram 寫一個字節(jié)*注意在此前要調(diào)用取消寫保護,實際寫應使用AAI,此函數(shù)在AAI中調(diào)用,用于寫奇數(shù)個字節(jié)

        **********************************/

        void SST25ByteProgram(u32 addr,u8 byte)

        {

        u8 ad[3];

        ad[0]=(addr>>16)&0xff;

        ad[1]=(addr>>8)&0xff;

        ad[2]=addr&0xff;

        SST_SELECT();

        SPIByte(0x02);

        SPIByte(ad[0]);

        SPIByte(ad[1]);

        SPIByte(ad[2]);

        SPIByte(byte);

        SST_DESELECT();

        while(SST25BY());

        }

        /***********************************

        SST25Write 寫多個字節(jié)

        ***********************************/

        void SST25Write(u32 addr,u8* p_data,u32 no)

        {

        u8 ad[3];

        u32 cnt;

        if(no==0)

        return;

        SST25WriteEn();

        if(no==1) //no<2則應使用普通單字節(jié)方式

        {

        SST25ByteProgram(addr,*p_data);

        // SST25WPEN();

        }

        else

        {

        cnt=no;

        ad[2]=(addr>>16)&0xff;

        ad[1]=(addr>>8)&0xff;

        ad[0]=addr&0xff;

        SST_SELECT();

        SPIByte(0xad);

        SPIByte(ad[2]);

        SPIByte(ad[1]);

        SPIByte(ad[0]);

        SPIByte(*p_data++);

        SPIByte(*p_data++);

        SST_DESELECT();

        cnt-=2;

        while(SST25BY()); //判忙

        //中間的雙字節(jié)寫

        for(;cnt>1;cnt-=2)

        {

        SST_SELECT();

        SPIByte(0xad);

        SPIByte(*p_data++);

        SPIByte(*p_data++);

        SST_DESELECT();

        while(SST25BY()); //判忙

        }

        SST25WRDI(); //WRDI用于退出AAI寫模式 所謂AAI 就是地址自動加

        //如果有最后一個字節(jié)(no為奇數(shù))

        if(cnt==1)

        {

        SST25WriteEn();

        SST25ByteProgram(addr+no-1,*p_data);

        }

        }

        SST25WPEN();//WP保護

        }

        

       

        //我們用的是下邊這種

        

       

        /*************************************

        SST25Read 高速讀 對于后續(xù)帶5的芯片,可調(diào)用此函數(shù)讀

        *************************************/

        void SST25Read(u32 addr,u8* p_data,u32 no)

        {

        SST_SELECT();

        SPIByte(0x0b);

        SPIByte(addr>>16);

        SPIByte(addr>>8);

        SPIByte(addr);

        SPIByte(0xff);

        for(;no>0;no--)

        *p_data++=SPIByte(0xff);

        SST_DESELECT();

        }

        /****************************************

        SST25ReadL 低速讀

        ****************************************/

        void SST25ReadL(u32 addr,u8* p_data,u32 no)

        {

        u8 ad[3];

        ad[2]=(addr>>16)&0xff;

        ad[1]=(addr>>8)&0xff;

        ad[0]=addr&0xff;

        SSTCmd4bs(0x03,ad,p_data,no);

        }

        

       

        好了 所有的底層讀寫都做好了~!

        后面~~

        SST25SectorErase(0); //擦除 0~4095 地址之間的數(shù)據(jù)

        SST25Write(addr,db_sst1,64); //往addr 寫入db_sst164個字節(jié)

        SST25Read(addr,db_sst1,64); //從addr讀64個字節(jié)到db_sst1

        就這些接口常用了~~~



      關鍵詞: STM32 SPI

      評論


      相關推薦

      技術專區(qū)

      關閉