SPI Topic (II)——STM32 Driver FLASH (W25Q64)

Publisher:灵感火花Latest update time:2019-01-09 Source: eefocusKeywords:SPI Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Hardware Connection


W25Q64 divides the 8M capacity into 128 blocks, each block is 64K bytes, each block is divided into 16 sectors, each sector is 4K bytes. The minimum erase unit of W25Q64 is one sector, which means that 4K bytes must be erased each time. The operation requires a cache area of ​​at least 4K for W25Q64, which has high requirements for SRAM. The chip must have more than 4K SRAM to operate well.


Write the picture description here


The W25Q64 has an erase and write cycle of up to 10W times, a data retention period of 20 years, and supports a voltage of 2.7~3.6V. The W25Q64 supports standard SPI and dual-output/quad-output SPI. The maximum SPI clock can reach 80Mhz (equivalent to 160Mhz for dual output and 320Mhz for quad output).


1.1 Hardware Connection


The pin connections with STM32 are as follows: SPI1 configuration is used here.


Write the picture description here



STM32 pins corresponding to SPI functions

PA2 Chip Select CS

PA5 clock SCK

PA6 MISO

PA7 MOSI

The SPI function of STM32 is very powerful. The SPI clock can reach up to 18Mhz, supports DMA, and can be configured as SPI protocol or I2S protocol (only supported by large-capacity models).


1.2 SPI communication timing


The SPI protocol defines the communication start and stop signals, data validity, clock synchronization and other aspects.


Write the picture description here


This is a communication sequence of a host. NSS, SCK, and MOSI signals are all generated by the host, while the MISO signal is generated by the slave. The host reads the data of the slave through this signal line. The MOSI and MISO signals are only valid when NSS is low. MOSI and MISO transmit one bit of data in each clock cycle of SCK.


1. Communication start and stop signals


At the number 1 in the figure, the NSS signal line changes from high to low, which is the start signal of SPI communication. NSS is a signal line that each slave has its own. When the slave detects the start signal on its own NSS line, it knows that it has been selected by the host and begins to prepare to communicate with the host. At the number 6 in the figure, the NSS signal changes from low to high, which is the stop signal of SPI communication, indicating that this communication is over and the selected state of the slave is cancelled.


2. Data Validity


SPI uses MOSI and MISO signal lines to transmit data, and uses SCK signal line for data synchronization. MOSI and MISO data lines transmit one bit of data in each clock cycle of SCK, and data input and output are performed simultaneously. There is no hard and fast rule for MSB first or LSB first when transmitting data, but to ensure that the same protocol is used between two SPI communication devices, the MSB first mode shown in the figure is generally adopted.


Observe the 2345 mark in the figure. The data of MOSI and MISO changes and outputs during the rising edge of SCK, and is sampled at the falling edge of SCK. That is, at the falling edge of SCK, the data of MOSI and MISO is valid, and the high level indicates data "1", and the low level indicates data "0". At other times, the data is invalid, and MOSI and MISO prepare for the next data representation. Each SPI data transmission can be 8 bits or 16 bits per unit, and the number of units transmitted each time is not limited.


1.3 STM32 SPI peripherals


The SPI peripheral of STM32 can be used as the master and slave of communication, and supports the highest SCK clock frequency of fpclk/2 (the default fpclk1 of STM32F103 chip is 72MHz, and fpclk2 is 36MHz), fully supports the 4 modes of SPI protocol, the data frame length can be set to 8 bits or 16 bits, and the data can be set to MSB first or LSB first. It also supports two-line full-duplex (this mode is described in the previous section), two-line unidirectional and single-line mode.


SPI architecture:


Write the picture description here


Communication pins:


All the hardware architecture of SPI is developed from the MOSI, MISO, SCK and NSS lines on the left side of the figure. The STM32 chip has multiple SPI peripherals, and their SPI communication signals are led out to different GPIO pins. When used, they must be configured to these designated pins.


2. Software Configuration

Here we use the master mode of STM32's SPI1. The SPI-related library functions and definitions are distributed in the file stm32f10x_spi.c and the header file stm32f10x_spi.h.


2.1 Configure the multiplexing function of related pins and enable SPI1 clock

The first step is to enable the clock of SPI1, which is set by the 12th bit of APB2ENR. Secondly, the relevant pins of SPI1 should be set as multiplexed outputs, so that they can be connected to SPI1. Otherwise, these IO ports are still in the default state, that is, standard input and output ports. Here we use PA5, 6, and 7 (SCK, MISO, MOSI,  CS uses software management), so these three are set as multiplexed IO.



    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd( RCC_APB2P%riphGPHOA|RCC_APB2Periph_SPI1%r52C%521ENABLE ); 


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Multiplex push-pull output

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);


2.2 Initialize SPI1 and set SPI1 working mode

Next, initialize SPI1, set SPI1 to host mode, set the data format to 8 bits, and then set the SCK clock polarity and sampling mode. Set the SPI1 clock frequency (maximum 18Mhz) and the data format (MSB first or LSB first). This is achieved in the library function through the SPI_Init function. 

Function prototype:


void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);


The first parameter is the SPI number, and the second parameter structure type SPI_InitTypeDef is used to set the related properties.


The definition of SPI_InitTypeDef is as follows:


typedef struct

{

uint16_t SPI_Direction;

uint16_t SPI_Mode;

uint16_t SPI_DataSize;

uint16_t SPI_CPOL;

uint16_t SPI_CPHA;

uint16_t SPI_NSS;

uint16_t SPI_BaudRatePrescaler;

uint16_t SPI_FirstBit;

uint16_t SPI_CRCPolynomial;

}SPI_InitTypeDef;


Parameter Explanation

SPI_Direction sets the SPI communication mode, which can be selected as half-duplex, full-duplex, and serial transmission and serial reception.

SPI_Mode sets the master and slave modes of SPI, master mode (SPI_Mode_Master), slave mode (SPI_Mode_Slave).

SPI_DataSiz Data is 8-bit or 16-bit frame format selection item. SPI_DataSize_8b (8 bits), SPI_DataSize_16b (16 bits)

SPI_CPOL sets the clock polarity

SPI_CPHA sets the clock phase, that is, selects the first or second edge of the serial synchronous clock at which the data is sampled.

SPI_NSS Sets whether the NSS signal is controlled by hardware (NSS pin) or software

SPI_BaudRatePrescaler sets the SPI baud rate prescaler value, which is the parameter that determines the SPI clock. There are 8 optional values ​​from no channel division to 256 division. Select the 256 division value SPI_BaudRatePrescaler_256, and the transmission speed is 36M/256=140.625KHz.

SPI_FirstBit sets the data transmission order to be MSB first or LSB first. SPI_FirstBit_MSB (high bit first)

SPI_CRCPolynomial sets the CRC check polynomial to improve communication reliability. It can be greater than 1.

The sample format of initialization is:


    SPI_InitTypeDef  SPI_InitStructure;


SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //Set SPI unidirectional or bidirectional data mode: SPI is set to two-line bidirectional full-duplex

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //Set SPI working mode: set to master SPI

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //Set the SPI data size: SPI sends and receives 8-bit frame structure

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //Select the steady state of the serial clock: the clock is floating high

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //Data capture (sampling) at the second clock edge

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS signal is managed by hardware (NSS pin) or software (using SSI bit): internal NSS signal is controlled by SSI bit

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //Define the baud rate prescaler value: the baud rate prescaler value is 256

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Specify whether data transmission starts from the MSB bit or the LSB bit: Data transmission starts from the MSB bit

    SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC value calculation polynomial

    SPI_Init(SPI1, &SPI_InitStructure); //Initialize the peripheral SPIx registers according to the parameters specified in SPI_InitStruct


2.3 Enable SPI1

After initialization is completed, enable SPI1 communication. After enabling SPI1, you can start SPI communication. The method to enable SPI1 is:


SPI_Cmd(SPI1, ENABLE); //Enable SPI peripheral


2.4 SPI Data Transmission

The communication interface needs to have functions for sending and receiving data. The prototype of the sending data function provided by the firmware library is:


void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);


Write data to the SPIx data register to achieve transmission.


The prototype of the data receiving function provided by the firmware library is:


uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) ;


This reads the received data from the SPIx data register.


2.5 Check SPI transmission status

During SPI transmission, it is necessary to determine whether the data transmission is completed, whether the sending area is empty, etc. This is achieved through the function SPI_I2S_GetFlagStatus. The method to determine whether the transmission is completed is:


SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE);


3. Software Design

3.1 SPI Implementation


SPI_InitTypeDef  SPI_InitStructure;


void SPI1_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE ); 


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Multiplex push-pull output

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);


    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //Set SPI unidirectional or bidirectional data mode: SPI is set to two-line bidirectional full-duplex

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //Set SPI working mode: set to master SPI

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //Set the SPI data size: SPI sends and receives 8-bit frame structure

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //Select the steady state of the serial clock: the clock is floating high

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //Data capture (sampling) at the second clock edge

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS signal is managed by hardware (NSS pin) or software (using SSI bit): internal NSS signal is controlled by SSI bit

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //Define the baud rate prescaler value: the baud rate prescaler value is 256

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Specify whether data transmission starts from the MSB bit or the LSB bit: Data transmission starts from the MSB bit

    SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC value calculation polynomial

    SPI_Init(SPI1, &SPI_InitStructure); //Initialize the peripheral SPIx registers according to the parameters specified in SPI_InitStruct


    SPI_Cmd(SPI1, ENABLE); //Enable SPI peripheral


    SPI1_ReadWriteByte(0xff); //Start transmission      

}   

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

//SPI speed setting function

//SpeedSet:

//SPI_BaudRatePrescaler_2   2分频   (SPI 36M@sys 72M)

//SPI_BaudRatePrescaler_8   8分频   (SPI 9M@sys 72M)

//SPI_BaudRatePrescaler_16  16分频  (SPI 4.5M@sys 72M)

//SPI_BaudRatePrescaler_256 256分频 (SPI 281.25K@sys 72M)


void SPI1_SetSpeed(u8 SpeedSet)

{

    SPI_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;

    SPI_Init(SPI1, &SPI_InitStructure);

    SPI_Cmd(SPI1,ENABLE);


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

//SPIx read and write a byte

//TxData: Bytes to be written

//Return value: the bytes read

u8 SPI1_ReadWriteByte(u8 TxData)

{       

    u8 retry=0;                 

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) // Check if the specified SPI flag is set: send buffer empty flag

        {

        retry++;

        if(retry>200)return 0;

        }             

    SPI_I2S_SendData(SPI1, TxData); //Send a data through peripheral SPIx

    retry=0;


    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) // Check whether the specified SPI flag is set: receive buffer not empty flag

        {

        retry++;

        if(retry>200)return 0;

        }                               

    return SPI_I2S_ReceiveData(SPI1); //Return the data most recently received via SPIx                     

}


3.2 Flash Read and Write


u16 SPI_FLASH_TYPE=W25Q64; //The default is 25Q64

//4Kbytes is a Sector

//16 sectors make up 1 Block

//W25X16

//The capacity is 2M bytes, with a total of 32 blocks and 512 sectors 


//Initialize the SPI FLASH IO port

void SPI_Flash_Init(void)

{


    GPIO_InitTypeDef GPIO_InitStructure;


  RCC_APB2PeriphClockCmd(   RCC_APB2Periph_GPIOA, ENABLE );


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;  //SPI CS

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //Multiplexed push-pull output

    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_SetBits(GPIOA,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);

    SPI1_Init(); //Initialize SPI

    SPI1_SetSpeed(SPI_BaudRatePrescaler_4); //Set to 18M clock, high speed mode

    SPI_FLASH_TYPE=SPI_Flash_ReadID();//读取FLASH ID.

}  

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

//Read the status register of SPI_FLASH

//BIT7 6 5 4 3 2 1 0

//SPR   RV  TB BP2 BP1 BP0 WEL BUSY

//SPR: default 0, status register protection bit, used with WP

//TB,BP2,BP1,BP0: FLASH area write protection setting

//WEL: Write Enable Lock

//BUSY: busy flag (1, busy; 0, idle)

//Default: 0x00

u8 SPI_Flash_ReadSR(void)   

{  

    u8 byte=0;   

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_ReadStatusReg); //Send the read status register command    

    byte=SPI1_ReadWriteByte(0Xff); //Read a byte  

    SPI_FLASH_CS=1; //Cancel chip select     

    return byte;   


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

//Write SPI_FLASH status register

//Only SPR, TB, BP2, BP1, BP0 (bit 7, 5, 4, 3, 2) can be written!!!

void SPI_FLASH_Write_SR(u8 sr)   

{   

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_WriteStatusReg); //Send the command to write the status register    

    SPI1_ReadWriteByte(sr); //Write a byte  

    SPI_FLASH_CS=1; //Cancel chip select             

}   


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

//SPI_FLASH write enable  

//Set WEL   

void SPI_FLASH_Write_Enable(void)   

{

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_WriteEnable); //Send write enable  

    SPI_FLASH_CS=1; //Cancel chip select             


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

//SPI_FLASH write disabled  

// Clear WEL  

void SPI_FLASH_Write_Disable(void)   

{  

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_WriteDisable); //Send write disable command    

    SPI_FLASH_CS=1; //Cancel chip select             

}               


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

//Read chip ID W25X16 ID: 0XEF14

u16 SPI_Flash_ReadID(void)

{

    u16 Temp = 0;     

    SPI_FLASH_CS=0;                 

    SPI1_ReadWriteByte(0x90); //Send read ID command     

    SPI1_ReadWriteByte(0x00);       

    SPI1_ReadWriteByte(0x00);       

    SPI1_ReadWriteByte(0x00);                  

    Temp|=SPI1_ReadWriteByte(0xFF)<<8;  

    Temp|=SPI1_ReadWriteByte(0xFF);  

    SPI_FLASH_CS=1;                 

    return Temp;

}               


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

//Read SPI FLASH  

//Start reading data of the specified length at the specified address

//pBuffer: data storage area

//ReadAddr: start reading address (24bit)

//NumByteToRead: the number of bytes to read (maximum 65535)

void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   

    u16 and;                                                      

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_ReadData); //Send read command   

    SPI1_ReadWriteByte((u8)((ReadAddr)>>16)); //Send 24-bit address    

    SPI1_ReadWriteByte((u8)((ReadAddr)>>8));   

    SPI1_ReadWriteByte((u8)ReadAddr);   

    for(i=0;i

    { 

        pBuffer[i]=SPI1_ReadWriteByte(0XFF); //Loop reading  

    }

    SPI_FLASH_CS=1; //Cancel chip select             

}  


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

//SPI writes less than 256 bytes of data in one page (0~65535)

//Start writing data up to 256 bytes at the specified address

//pBuffer: data storage area

//WriteAddr: start writing address (24bit)

//NumByteToWrite: The number of bytes to be written (maximum 256), this number should not exceed the remaining bytes of the page!!!   

void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)

{

    u16 and;  

    SPI_FLASH_Write_Enable();                  //SET WEL 

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_PageProgram); //Send write page command   

    SPI1_ReadWriteByte((u8)((WriteAddr)>>16)); //Send 24-bit address    

    SPI1_ReadWriteByte((u8)((WriteAddr)>>8));   

    SPI1_ReadWriteByte((u8)WriteAddr);   

    for(i=0;i

        {

            SPI1_ReadWriteByte(pBuffer[i]);//Loop write data  

        }

    SPI_FLASH_CS=1; //Cancel chip select 

    SPI_Flash_Wait_Busy(); //Wait for writing to end


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

//Write SPI FLASH without checking 

// Make sure that all data in the address range you write is 0XFF, otherwise data written at non-0XFF will fail!

//With automatic page change function 

//Start writing data of the specified length at the specified address, but make sure the address does not cross the boundary!

//pBuffer: data storage area

//WriteAddr: start writing address (24bit)

//NumByteToWrite: the number of bytes to be written (maximum 65535)

//CHECK OK

void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   

{                    

    u16 pageremain;    

    pageremain=256-WriteAddr%256; //Number of bytes remaining in a single page                

    if(NumByteToWrite<=pageremain)

        pageremain=NumByteToWrite; //No more than 256 bytes

    while(1)

    {      

        SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);

        if(NumByteToWrite==pageremain)

            break; // Writing is finished

        else //NumByteToWrite>pageremain

        {

            pBuffer+=pageremain;

            WriteAddr+=pageremain;  


            NumByteToWrite-=pageremain; //Subtract the number of bytes already written

            if(NumByteToWrite>256)

                pageremain=256; //256 bytes can be written at a time

            else pageremain=NumByteToWrite; //Not enough 256 bytes

        }

    };      


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

//Write SPI FLASH  

//Start writing data of the specified length at the specified address

//This function has erase operation!

//pBuffer: data storage area

//WriteAddr: start writing address (24bit)

//NumByteToWrite: the number of bytes to be written (maximum 65535)          

u8 SPI_FLASH_BUF[4096]; //Size of a sector

void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   

    u32 secpos;

    u16 secoff;

    u16 secremain;     

    u16 and;    


    secpos=WriteAddr/4096; //sector address 0~511 for w25x16

    secoff=WriteAddr%4096; //Offset within the sector

    secremain=4096-secoff; //Sector remaining space size   


    if(NumByteToWrite<=secremain)

        secremain=NumByteToWrite; //No more than 4096 bytes

    while(1) 

    {   

        SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//Read the contents of the entire sector

        for(i=0;i

        {

            if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//need to erase     

        }

        if(i

        {

            SPI_Flash_Erase_Sector(secpos); //Erase this sector

            for(i=0;i

            {

                SPI_FLASH_BUF[i+secoff]=pBuffer[i];   

            }

            SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//Write the entire sector  


        }

        else 

            SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//Write what has been erased, directly write to the remaining area of ​​the sector.                 

        if(NumByteToWrite==secremain)

            break; // Writing is finished

        else //Writing is not finished

        {

            secpos++; //sector address increment by 1

            secoff=0; //Offset position is 0    


            pBuffer+=secremain; //Pointer offset

            WriteAddr+=secremain; //write address offset       

            NumByteToWrite-=secremain; //Number of bytes decreases

            if(NumByteToWrite>4096)secremain=4096; //The next sector still cannot be written

            else secremain=NumByteToWrite; //The next sector can be written

        }    

    };       

}


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

// Erase the entire chip

//Whole chip erase time:

//W25X16:25s 

//W25X32:40s 

//W25X64:40s 

//Waiting time is too long...

void SPI_Flash_Erase_Chip(void)   

{                                             

    SPI_FLASH_Write_Enable();                  //SET WEL 

    SPI_Flash_Wait_Busy();   

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_ChipErase); //Send chip erase command  

    SPI_FLASH_CS=1; //Cancel chip select             

    SPI_Flash_Wait_Busy(); //Wait for chip erasure to end

}   


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

// Erase a sector

//Dst_Addr: sector address 0~511 for w25x16

//Minimum time to erase a mountain area: 150ms

void SPI_Flash_Erase_Sector(u32 Dst_Addr)   

{   

    Dst_Addr*=4096;

    SPI_FLASH_Write_Enable();                  //SET WEL     

    SPI_Flash_Wait_Busy();   

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_SectorErase); //Send sector erase command 

    SPI1_ReadWriteByte((u8)((Dst_Addr)>>16)); //Send 24-bit address    

    SPI1_ReadWriteByte((u8)((Dst_Addr)>>8));   

    SPI1_ReadWriteByte((u8)Dst_Addr);  

    SPI_FLASH_CS=1; //Cancel chip select             

    SPI_Flash_Wait_Busy(); //Wait for erasing to complete

}  


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

//Wait for free time

void SPI_Flash_Wait_Busy(void)   

{   

    while ((SPI_Flash_ReadSR()&0x01)==0x01); // Wait for BUSY bit to clear

}  


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

//Enter power-down mode

void SPI_Flash_PowerDown(void)   

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_PowerDown); //Send power-down command  

    SPI_FLASH_CS=1; //Cancel chip select             

    delay_us(3); //Wait for TPD  

}   


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

//wake

void SPI_Flash_WAKEUP(void)   

{  

    SPI_FLASH_CS=0; //Enable device   

    SPI1_ReadWriteByte(W25X_ReleasePowerDown);   //  send W25X_PowerDown command 0xAB    

      SPI_FLASH_CS=1; //Cancel chip select               

    delay_us(3); //Wait for TRES1

}   



reference:

1. Atomic library function manual


2.SPI—Read and write serial FLASH

--------------------- 

Author:wwt18811707971 

Source: CSDN 

Original text: https://blog.csdn.net/wwt18811707971/article/details/77756312 

Copyright Statement: This article is an original article by the blogger. Please attach the blog link when reprinting!


Keywords:SPI Reference address:SPI Topic (II)——STM32 Driver FLASH (W25Q64)

Previous article:STM32 learning notes one by one input capture
Next article:IIC Topic 2 - STM32 driving AT24C02

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号