Stm32f10xmcu advanced -- spi use

Using SPI to communicate with external flash(MX25L6406EM21)IC

  • Connection mode

                  

 

         

As shown in the figure above, MCU is connected with external flash chip through SPI2.

  • MCU spi2 initialization

                

Define the SPI port number used in SPI2

                          

Initialization of communication function in spi2

Read data and write data

  • Instruction description

Check the datasheet of flash chip. mx25 chip supports writing by page and erasing by sector. Page "program" is 0x02, and section "erase" is 0x20. Before writing data to each page, you must ensure that the sector where this page is located has been erased. The maximum write size of each page is 256byte, and the size of a sector is 4Kbyte

  • Write data, write data by page (write one page of data)

Write instruction 0x06 according to chip

void spi_flash_write_page(uint8_t* pBuffer,uint32_t write_address,uint16_t num_byte_to_write) //Write data to the page, where write "address must be the entire data part of 256, that is, the start position of a page,
{
    uint16_t i=0;
    
//    debug_out("SpiPage:0x%08x Len:%d\r\n", write_address, num_byte_to_write);
    
    spi_flash_wait_busy();   //Busy waiting
    spi_flash_write_enable();
    spi_flash_wait_busy();
    
    spi2_cs_low();
    spi2_read_write_byte(MX25_PAGE_PROGRAM);
    spi2_read_write_byte((uint8_t) ( ((write_address) >> 16 )&0xFF) );
    spi2_read_write_byte((uint8_t) ( ((write_address) >> 8 )&0xFF) );
    spi2_read_write_byte((uint8_t) ( (write_address)&0xff ) );
    
    for(i=0;i<num_byte_to_write;i++)
    {
        spi2_read_write_byte(pBuffer[i]);
    }
    spi2_cs_high();
    spi_flash_wait_busy();        
    
}
  • Erase sector
void spi_flash_erase_sector(uint32_t addr)   //addr starts as a multiple of 4K and clears a sector
{
    spi_flash_wait_busy();
    spi_flash_write_enable();
    spi_flash_wait_busy();
    
    //½øÐвÁ³ý²Ù×÷
    spi2_cs_low();
    spi2_read_write_byte(MX25_SECTOR_ERASE);
    spi2_read_write_byte((uint8_t) ( ((addr) >> 16 )&0xFF) );
    spi2_read_write_byte((uint8_t) ( ((addr) >> 8 )&0xFF) );
    spi2_read_write_byte((uint8_t) ( (addr)&0xff ) );
    spi2_cs_high();
    spi_flash_wait_busy();
}
  • Start writing data of specified length at specified address

Writes data of the specified length from the specified address. It is also written from the beginning of a sector to calculate the total number of pages to be written. At the same time, if it is the beginning of a sector, remember to erase the sector.

void spi_flash_write(uint8_t* pBuffer,uint32_t address,uint16_t buffer_len) 
{
    uint16_t pageCount = 0;
    uint16_t pageIndex = 0;
    uint16_t length = 0;
    uint16_t i=0;
    pageCount = buffer_len / SPI_FLASH_PAGE_SIZE;
    if( ( buffer_len % SPI_FLASH_PAGE_SIZE ) != 0 )
    {
        pageCount += 1;
    }
    while( pageIndex < pageCount )
    {
        length = buffer_len - ( pageIndex * SPI_FLASH_PAGE_SIZE ) ;
        length = length > SPI_FLASH_PAGE_SIZE ? SPI_FLASH_PAGE_SIZE : length;
        if( ( (  address + pageIndex * SPI_FLASH_PAGE_SIZE ) % SPI_FLASH_SECTOR_SIZE ) == 0 )
        {
            spi_flash_erase_sector( address + pageIndex * SPI_FLASH_PAGE_SIZE );
        }
        spi_flash_write_page(pBuffer + pageIndex * SPI_FLASH_PAGE_SIZE, address + pageIndex * SPI_FLASH_PAGE_SIZE, length );
        pageIndex ++;
    }
}
  • Read data

Reading data is much simpler than writing data. It starts from the specified address and reads the specified length

void spi_flash_read(uint8_t* pBuffer,uint32_t read_address,uint16_t num_byte_to_read) 
{
    uint16_t i=0;
    spi_flash_wait_busy();
    
    spi2_cs_low();
    
    spi2_read_write_byte(MX25_READ_DATA);
    spi2_read_write_byte((uint8_t) ( ((read_address) >> 16 )&0xFF) );
    spi2_read_write_byte((uint8_t) ( ((read_address) >> 8 )&0xFF) );
    spi2_read_write_byte((uint8_t) ( (read_address)&0xff ) );
    
    for(i=0;i<num_byte_to_read;i++)
    {
        pBuffer[i]=spi2_read_write_byte(0xFF);
    }
    
    spi2_cs_high();
    
}

So far, the whole driver has been written.

Tags: C

Posted on Wed, 15 Apr 2020 09:26:01 -0700 by jamesl73